全国服务热线:4008-888-888

技术知识

html5怎样在Canvas中完成自定相对路径动漫示例

在近期的新项目中笔者必须做1个新要求:在canvas中完成自定的相对路径动漫。这里所谓的自定相对路径不单是包含1条平行线,或许是好几条平行线的健身运动组成,乃至还包括了贝塞尔曲线图,因而,这个动漫或许是下面这个模样的:

那末怎样才可以在canvas中完成这类动漫实际效果呢?实际上很简易,针对相对路径的解决svg十分内行,因而在canvas中完成自定相对路径动漫,大家必须依靠svg的能量。

建立Path

制做动漫前,先要拿到动漫的相对路径,对此大家能够立即应用svg的path界定标准,例如大家界定了1条较为繁杂的相对路径(它究竟长甚么样大伙儿能够自身试试,这里就不展现了),随后,大家必须将界定好的相对路径导入进1个新生儿成的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内完成自定相对路径动漫1般也是根据这两个api去处理)详细信息请戳:SVGPathElement MDN

getTotalLength方式能够获得SVGPathElement的总长度

getPointAtLength方式,传入1个长度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();
}

最终,大家把它封裝1下,便可完成1个在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制做自定相对路径动漫时,大家不但要考虑到怎样完成,更要考虑到特性提升,例如在这个完成思路中,大家是不是能够降低无须要的3D渲染次数?帧率怎样操纵做到最佳?这些。

尽管它们其实不在这篇文章内容的探讨范畴中,当也理应值得大家思索。

以上便是本文的所有內容,期待对大伙儿的学习培训有一定的协助,也期待大伙儿多多适用脚本制作之家。



在线客服

关闭

客户服务热线
4008-888-888


点击这里给我发消息 在线客服

点击这里给我发消息 在线客服