如何将 Procreate 绘制的作品转化为网页动画

Avatar of Sarah Drasner
Sarah Drasner

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

我最近开始使用 Apple Pencil 在我的 iPad 上使用 Procreate 应用进行绘画。我喜欢这种绘画方式的灵活性。通常让我无法在家绘画的原因是一些基本的事情,例如设置、清洁画笔、适当的通风以及其他与绘画本身无关的因素。Procreate 在模拟绘画和绘图过程方面做得相当不错,但还添加了撤消/重做、图层和图层效果等数字功能。

这是一幅我用 Procreate 绘制的画作,我最终将其导出并在网络上进行了动画处理。

查看 CodePen 上 Sarah Drasner (@sdras) 的作品
斑马页面 - 来自 Procreate 绘制的网页动画

CodePen 上。

您也可以做到!这里我们将介绍两种基本的动画效果:悬停时发生的视差效果(以及 针对前庭疾病患者关闭该效果 的功能),以及页面加载时的微型绘图效果。

使用绘图图层创建视差效果

我提到过,我喜欢在 iPad 上绘画的部分原因是能够分层工作。创建图层时,我会注意将某些“主题”保留在同一图层上,例如,斑马条纹在一个图层上,而点则在条纹下方的另一个图层上。

我会将绘画扩展到上一层线条结束位置之外,主要是因为当我们在视差效果中移动绘画时,您将能够稍微窥视一下它。如果线条在任何点都非常清晰,则看起来会不自然。

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

在 Photoshop 中打开的同一幅画作。

然后,我会将几个图层组合在一起,以便最多只处理大约 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-widthmin-height 允许我限制 div 的收缩和增长方式,尤其是在将其放入 CSS Grid 布局时。它需要灵活,但也要有一些约束,CSS Grid 很适合这一点。

接下来,我使用 JavaScript 在父 div 上添加一个 mousemove 事件监听器。这使我可以使用 e.clientXe.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,描摹了绘画该部分的线条,并通过进入“描边”面板、选择“更多选项”并从下拉菜单中单击锥形选项来使这些线条呈锥形。

Screenshot of the Illustrator Stroke menu.

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

以下是我的操作步骤

  • 我使用钢笔工具进行描摹,并使用了锥形画笔。
  • 我复制了图层,并将线条更改为统一且更粗。
  • 我获取了第一层并创建了一个复合路径。
  • 我简化了路径点。
  • 我创建了剪切蒙版。

从那里,我可以使用 drawSVGGreenSock 为所有内容制作动画。虽然您不需要这样做,但也可以为此类动画使用 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 项目变得独特。如果您制作了任何很酷的东西,请在下面的评论中告诉我们!