阅读 102

canvas - 图片裁剪 - 花瓣散落动画

用drawImage 带你做一个花瓣散落的动画

之前我们阅读过canvas的基础api。 但是其中包括有很多较为复杂的api我们直接跳过了。

drawImage 就是其中之一。今天我们就一起来看看他。

drawImage 一个方法包括了两种使用方式:渲染 和 裁剪 。 我们重点看看裁剪。

渲染

在我们渲染图片之前我们需要对图片进行预加载。

 function loadImg(url) {   return new Promise((resolve, reject) => {     let img = new Image()     img.onload = function () {       resolve(img)     }     img.src = url   }) } 复制代码

在图片加载结束之后我们将整个img对象返回。在这个img对象中我们可以拿到对img的宽高和img的实例。 而这个img的实例就是 我们drawImage的第一个参数。

我们使用drawImage对img,在参数0,0坐标处进行渲染。 我们可以看到效果是,图形将按照元是的像素进行渲染。

 let img = await loadImg(imgUrl); let sw = img.width let sh = img.height ctx.drawImage(img, 0, 0) 复制代码

我们可以设置一个缩放比例 将img的长宽高都进行缩放然后在进行渲染。

     let ZC = 0.2 // 缩放比例我们将缩放比例设置成20%      // 在0,0这个点  按照缩放比例 ZC对图片进行渲染   ctx.drawImage(img, 0, 0, sw * ZC, sh * ZC)    复制代码

裁剪

drawImage 还有一个形变的公式,那就是裁剪

下面这段代码表示:

在图片宽度的43.6%高度的58%处截取 宽度为宽度的12.7%高度的24%的图形,放在画布的0,shZC高度处  按5050的大小显示出来

  ctx.drawImage(img,sw*0.236,sh*0.58,sw*0.127,sh*0.24,0,sh*ZC,50,50) 复制代码

花瓣飘落动画

动画原理:

  1. 花瓣裁剪 我们首先定义一个花的类文件

    在这个文件中我们顶一个,Flows数组 讲生成花瓣之后的实例都存放在其中。

    另外实例的重点就是play方法讲水平移动 垂直移动的数值计算之后,

    使用我们的图片裁剪裁剪出一朵花瓣,最后在画布中运动。

    好,好这个类就定义完成了。

    看代码。

     let Flows = [] // 飘动雪花数组          class Flow {            constructor(x, y, w, img, sw, sh) {         this.x = x         this.y = y         this.w = w         this.img = img         this.sw = sw         this.sh = sh         this.g = Math.random() * 3+1 // 重力加速度         this.v = - (Math.random() * 2) // 水平移动速度         Flows.push(this)       }            play() {         let img = this.img         let sw = this.sw         let sh = this.sh         this.x -= this.v         this.y += this.g              // 最初始值绘图         ctx.drawImage(img,sw*0.236,sh*0.58,sw*0.127,sh*0.24,this.x, this.y,100*this.w/10,100*this.w/10)              // 达到零界点清除         if(this.y > canvas.height){           this.clear()         }            }            clear() {         let index = Flows.indexOf(this)         Flows.splice(index,1)       }          } 复制代码

  1. 花瓣运动

    因为我们封装的图片加载是promise,我想使用异步的方式,

    我们顶一个了一个立即执行函数,在图片加载完成之后 ,我们开启生成花瓣的函数。

    没什么东西可以说的,理解了就很简单。

    看代码。

   let canvas = document.getElementById('canvas')   let ctx = canvas.getContext('2d')   canvas.height = window.innerHeight   canvas.width = window.innerWidth      let imgUrl = 'https://bloggers-1304641141.cos.ap-beijing.myqcloud.com/img/1631072101978.png'   function loadImg(url) {     return new Promise((resolve, reject) => {       let img = new Image()       img.onload = function () {         resolve(img)       }       img.src = url     })   }   ( async () => {     let img = await loadImg(imgUrl);     let sw = img.width     let sh = img.height     let ZC = 0.2     let index = 0          new Flow(Math.random() * canvas.width/2, 0, Math.random() * 8, img, sw, sh)     new Flow(Math.random() * canvas.width/2, 0, Math.random() * 8, img, sw, sh)     // 60帧每秒渲染     setInterval(() => {       ctx.clearRect(0, 0, canvas.width, canvas.height)       // // 生产花朵       if (index % 50 === 0) {         new Flow(Math.random() * canvas.width, 0, Math.random() * 4+3,img,sw,sh)       }       for (let i = 0; i < Flows.length; i++) {         let element = Flows[i]         element.play()       }       index++     }, 1000 / 60)   })()


作者:玩鲁班的哥哥
链接:https://juejin.cn/post/7018478056381628430

文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐