时间:2021-05-08
在最近的项目中笔者需要做一个新需求:在canvas中实现自定义的路径动画。这里所谓的自定义路径不单单包括一条直线,也许是多条直线的运动组合,甚至还包含了贝塞尔曲线,因此,这个动画也许是下面这个样子的:
那么如何才能在canvas中实现这种动画效果呢?其实很简单,对于路径的处理svg非常在行,因此在canvas中实现自定义路径动画,我们需要借助svg的力量。
创建Path
制作动画前,先要拿到动画的路径,对此我们可以直接使用svg的path定义规则,比如我们定义了一条较为复杂的路径(它到底长什么样大家可以自己试试,这里就不展示了),然后,我们需要将定义好的路径导入进一个新生成的path元素中(我们只是借助svg的api,因此并不需要将其插到页面内)
const path = 'M0,0 C8,33.90861 25.90861,16 48,16 C70.09139,16 88,33.90861 88,56 C88,78.09139 105.90861,92 128,92 C150.09139,92 160,72 160,56 C160,40 148,24 128,24 C108,24 96,40 96,56 C96,72 105.90861,92 128,92 C154,93 168,78 168,56 C168,33.90861 185.90861,16 208,16 C230.09139,16 248,33.90861 248,56 C248,78.09139 230.09139,96 208,96 L48,96 C25.90861,96 8,78.09139 8,56 Z';const pathElement = document.createElementNS('http://www.w3.org/2000/svg',"path"); pathElement.setAttributeNS(null, 'd', path);getTotalLength与getPointAtLength
SVGPathElement提供的这两个api很关键,可以说它是实现路径动画的最为核心的地方(在svg内实现自定义路径动画一般也是通过这两个api去解决)详情请戳:SVGPathElement MDN
getTotalLength方法可以获取SVGPathElement的总长度
getPointAtLength方法,传入一个长度x,将返回距离SVGPathElement起点的长度为x的终点坐标。
利用这两个api,通过循环的方式不断去更新canvas内所绘制的图形坐标,即可实现路径动画:
const length = pathElement.getTotalLength();const duration = 1000; // 动画总时长const interval = length / duration;const canvas = document.querySelector('canvas');const context = canvas.getContext('2d');let time = 0, step = 0; const timer = setInterval(function() { if (time <= duration) { const x = parseInt(pathElement.getPointAtLength(step).x); const y = parseInt(pathElement.getPointAtLength(step).y); move(x, y); // 更新canvas所绘制图形的坐标 step++; } else { clearInterval(timer) }}, interval);function move(x, y) { context.clearRect(0, 0, canvas.width, canvas.height); context.beginPath(); context.arc(x, y, 25, 0, Math.PI*2, true); context.fillStyle = '#f0f'; context.fill(); context.closePath();}最后,我们把它封装一下,即可实现一个在canvas中实现自定义动画的简易函数啦:
function customizePath(path, func) { const pathElement = document.createElementNS('http://www.w3.org/2000/svg',"path"); pathElement.setAttributeNS(null, 'd', path); const length = pathElement.getTotalLength(); const duration = 1000; const interval = length / duration; let time = 0, step = 0; const timer = setInterval(function() { if (time <= duration) { const x = parseInt(pathElement.getPointAtLength(step).x); const y = parseInt(pathElement.getPointAtLength(step).y); func(x, y); step++; } else { clearInterval(timer) } }, interval);}const path = 'M0,0 C8,33.90861 25.90861,16 48,16 C70.09139,16 88,33.90861 88,56 C88,78.09139 105.90861,92 128,92 C150.09139,92 160,72 160,56 C160,40 148,24 128,24 C108,24 96,40 96,56 C96,72 105.90861,92 128,92 C154,93 168,78 168,56 C168,33.90861 185.90861,16 208,16 C230.09139,16 248,33.90861 248,56 C248,78.09139 230.09139,96 208,96 L48,96 C25.90861,96 8,78.09139 8,56 Z';const canvas = document.querySelector('canvas');const context = canvas.getContext('2d');function move(x, y) { context.clearRect(0, 0, canvas.width, canvas.height); context.beginPath(); context.arc(x, y, 25, 0, Math.PI*2, true); context.fillStyle = '#f0f'; context.fill(); context.closePath();}customizePath(path, move);实现思路大致如上所述,然而这并不是最终成果。当我们决定要在canvas制作自定义路径动画时,我们不仅要考虑如何实现,更要考虑性能优化,比如在这个实现思路中,我们是否可以减少不必要的渲染次数?帧率如何控制达到最优?等等。
虽然它们并不在这篇文章的讨论范围中,当也应当值得我们思考。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
HTML5Canvas自定义圆角矩形与虚线(RoundedRectangleandDashLine)实现向HTMLCanvas2dcontext绘制对象中添加自
HTML5数据属性允许您将自定义数据分配给元素。本文介绍了如何使用它,并提供了理想情况下使用它的示例。做网站?介绍在HTML5之前,我们不得不依赖于使用“cla
今天要推荐的是9款非常有意思的HTML5动画,这些动画有些是基于Canvas的,有些是SVG结合HTML5实现的,让我们一起来看看。1、HTML5梦幻可给任意元
前言本篇文章会说下如何使用并且要用麻烦的自定义view去实现时间轴效果,以及如何分析、实现自定义view。需要具备的知识:Paint、Canvas、自定义vie
两种方式实现类似水波扩散效果,先上图为敬自定义view实现动画实现自定义view实现思路分析:通过canvas画圆,每次改变圆半径和透明度,当半径达到一定程度,