我最近开始使用 Apple Pencil 在我的 iPad 上使用 Procreate 应用进行绘画。我喜欢这种绘画方式的灵活性。通常让我无法在家绘画的原因是一些基本的事情,例如设置、清洁画笔、适当的通风以及其他与绘画本身无关的因素。Procreate 在模拟绘画和绘图过程方面做得相当不错,但还添加了撤消/重做、图层和图层效果等数字功能。
这是一幅我用 Procreate 绘制的画作,我最终将其导出并在网络上进行了动画处理。
查看 CodePen 上 Sarah Drasner (@sdras) 的作品
斑马页面 - 来自 Procreate 绘制的网页动画。
在 CodePen 上。
您也可以做到!这里我们将介绍两种基本的动画效果:悬停时发生的视差效果(以及 针对前庭疾病患者关闭该效果 的功能),以及页面加载时的微型绘图效果。
使用绘图图层创建视差效果
我提到过,我喜欢在 iPad 上绘画的部分原因是能够分层工作。创建图层时,我会注意将某些“主题”保留在同一图层上,例如,斑马条纹在一个图层上,而点则在条纹下方的另一个图层上。
我会将绘画扩展到上一层线条结束位置之外,主要是因为当我们在视差效果中移动绘画时,您将能够稍微窥视一下它。如果线条在任何点都非常清晰,则看起来会不自然。

创建完图层后,我可以将其导出为 Photoshop (PSD) 文件,这要归功于 Procreate 的导出选项。

然后,我会将几个图层组合在一起,以便最多只处理大约 8 个图层。我使用一个名为 tinyPNG 的 Photoshop 插件来单独导出每个图层。我听说还有更好的压缩工具,但我对这个工具非常满意。
接下来,我将进入我的代码编辑器,并创建一个 div 来容纳图层中包含的所有各种图像。我为该 div 设置相对定位,而其中的所有图像则获得绝对定位。这会将图像一个叠放在另一个上面。
<div id="zebra-ill" role="presentation">
<img class="zebraimg" src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/zebraexport6.png' />
<img class="zebraimg" src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/28963/zebraexport5.png' />
…
</div>
#zebra-ill {
position: relative;
min-height: 650px;
max-width: 500px;
}
.zebraimg {
position: absolute;
top: 0;
left: 0;
perspective: 600px;
transform-style: preserve-3d;
transform: translateZ(0);
width: 100%;
}
图像上的 100% 宽度会将所有图像限制在父 div 的大小内。我这样做是为了同时使用相同的限制条件控制它们,这对于响应式条件非常有效。父元素上的 max-width
和 min-height
允许我限制 div 的收缩和增长方式,尤其是在将其放入 CSS Grid 布局时。它需要灵活,但也要有一些约束,CSS Grid 很适合这一点。
接下来,我使用 JavaScript 在父 div 上添加一个 mousemove
事件监听器。这使我可以使用 e.clientX
和 e.clientY
捕获有关鼠标坐标的一些信息。
const zebraIll = document.querySelector('#zebra-ill')
// Hover
zebraIll.addEventListener('mousemove', e => {
let x = e.clientX;
let y = e.clientY;
})
然后,我将遍历每个绘图,并使用这些坐标来移动图像。我甚至会应用与这些坐标相关的转换样式。
const zebraIll = document.querySelector('#zebra-ill')
const zebraIllImg = document.querySelectorAll('.zebraimg')
const rate = 0.05
//hover
zebraIll.addEventListener('mousemove', e => {
let x = e.clientX;
let y = e.clientY;
zebraIllImg.forEach((el, index) => {
el.style.transform =
`rotateX(${x}deg) rotateY(${y}deg)`
})
})
查看 CodePen 上 Sarah Drasner (@sdras) 的作品
斑马页面。
在 CodePen 上。
哇,慢下来,伙计!移动速度太快了,我们需要一些更细微的效果。因此,我需要通过将其乘以较低的速率(例如 0.05)来大幅降低速度。我还想为每个图层稍微更改一下,因此我将使用图层索引来加快或减慢移动速度。
const zebraIll = document.querySelector('#zebra-ill')
const zebraIllImg = document.querySelectorAll('.zebraimg')
const rate = 0.05
// Hover
zebraIll.addEventListener('mousemove', e => {
let x = e.clientX;
let y = e.clientY;
zebraIllImg.forEach((el, index) => {
let speed = index += 1
let xPos = speed + rate * x
let yPos = speed + rate * y
el.style.transform =
`rotateX(${xPos - 20}deg) rotateY(${yPos - 20}deg) translateZ(${index * 10}px)`
})
})
最后,我可以创建一个复选框,询问用户是否要关闭此效果。
<p>
<input type="checkbox" name="motiona11y" id="motiona11y" />
<label for="motiona11y">If you have a vestibular disorder, check this to turn off some of the effects</label>
</p>
const zebraIll = document.querySelector('#zebra-ill')
const zebraIllImg = document.querySelectorAll('.zebraimg')
const rate = 0.05
const motioncheck = document.getElementById('motiona11y')
let isChecked = false
// Check to see if someone checked the vestibular disorder part
motioncheck.addEventListener('change', e => {
isChecked = e.target.checked;
})
// Hover
zebraIll.addEventListener('mousemove', e => {
if (isChecked) return
let x = e.clientX;
let y = e.clientY;
// ...
})
现在,用户能够在悬停时查看绘图的分层维度,但如果效果令人反感,也可以将其关闭。
绘图效果
使某些内容看起来像是绘制到页面上的功能已经存在一段时间了,并且有很多关于 如何实现此功能的文章。我还在我为 Frontend Masters 制作的 课程 中介绍了它。
前提如下
- 获取 SVG 路径,并使用
dashoffset
使其虚线化。 - 使虚线长度等于形状的整个长度。
- 为
dashoffset
(虚线之间的间距)制作动画。
最终得到的是一种“绘制”效果。
但在这种特殊的绘画中,您可能已经注意到我制作动画的部分看起来像是手绘的,这有点独特。您会看到,虽然这种效果对于更机械的图纸非常有效,但网络尚不支持使用锥形线条(线条厚度变化,这是手绘感的典型特征)。
对于这种方法,我将文件导入 Illustrator,描摹了绘画该部分的线条,并通过进入“描边”面板、选择“更多选项”并从下拉菜单中单击锥形选项来使这些线条呈锥形。

我复制了这些线条,并在下面创建了更粗的统一路径。然后,我获取这些粗线条并将其动画化到页面上。现在,我的绘画显示在形状的下方。

以下是我的操作步骤
- 我使用钢笔工具进行描摹,并使用了锥形画笔。
- 我复制了图层,并将线条更改为统一且更粗。
- 我获取了第一层并创建了一个复合路径。
- 我简化了路径点。
- 我创建了剪切蒙版。
从那里,我可以使用 drawSVG 和 GreenSock 为所有内容制作动画。虽然您不需要这样做,但也可以为此类动画使用 CSS。路径点非常多,因此在这种情况下,使用更强大的工具是有意义的。我写了 另一篇文章,详细介绍了如何开始创建此类动画。如果您是新手,我建议您从那里开始。
要使用 drawSVG,我们需要执行以下操作
- 加载插件脚本。
- 在 JavaScript 文件的顶部注册插件。
- 确保正在使用路径,并且这些路径上有描边。
- 确保目标是这些路径而不是包含它们的组。可以改为定位父元素。
这是一个非常基本的 drawSVG 示例(由 GreenSock 提供)
查看 CodePen 上 GreenSock (@GreenSock) 的作品
DrawSVGPlugin 值。
在 CodePen 上。
因此,在图形编辑器中,有一个剪切蒙版,其中包含更精美的线条,这些线条会露出下方的粗统一线条。从这里,我们将抓住这些较粗的路径,并使用 drawSVG 插件将其动画化到页面上。
//register the plugin
gsap.registerPlugin(DrawSVGPlugin);
const drawLines = () => {
gsap.set('.cls-15, #yellowunderline, .cls-13', {
visibility: 'visible'
})
const timeline = gsap.timeline({
defaults: {
delay: 1,
ease: 'circ',
duration: 2
}
})
.add('start')
.fromTo('.cls-15 path', {
drawSVG: '0%'
}, {
drawSVG: '100%',
immediateRender: true
}, 'start')
.fromTo('#yellowunderline path', {
drawSVG: '50% 50%'
}, {
drawSVG: '100%',
immediateRender: true
}, 'start+=1')
.fromTo('.cls-13', {
drawSVG: '50% 50%'
}, {
drawSVG: '100%',
immediateRender: true
}, 'start+=1')
}
window.onload = () => {
drawLines()
};
就是这样!这是我们网站的初始插图,它是从 Procreate iPad 应用中的分层绘画创建的。我希望这能帮助您开始使用精美的手绘插图使您的 Web 项目变得独特。如果您制作了任何很酷的东西,请在下面的评论中告诉我们!