2019独角兽企业重金招聘Python工程师标准>>>

本讲我们在上一讲的基础上,给旗子添加高光,使其看起来更加有立体感。我会用两种方式来分别实现这个效果,然后比较一下优劣,还是先讲原理。

方法一:在原来的代码drawImage之后通过 fillRect 函数来增加一个白色蒙层,通过透明度的递增和递减来模拟。具体多少透明度?当然你可以用数学的方法来求导计算出某一点的斜率,根据其大小和正负得出其透明度大小,斜率越大,透明度越小。这里用一种更取巧也效率更高的方法,即保存某一点前一个点的y轴坐标,与该点的y坐标相减,即可得到斜率的相对大小,因为两点之间的x轴上距离都是1px,所以y轴变化越大,|斜率|则越大。

方法二:先通过遍历 getImageData 函数返回的元素逐像素获取原始画布每个点的rgba值,然后每一帧通过运动函数对每个点的位置进行偏移,对比原画布,获取该点在原位置的rgba值,然后直接对a分量进行修改,修改的依据仍然是斜率。

这是方法一的代码,我只贴出修改的部分(// +++ 之间):

var y = 0
// +++++++++++++++++++++
var lastY = 0
// +++++++++++++++++++++
var distance = 0
var tick = function () {if (stop) return falsetimeNow = Date.now()delta = timeNow - timeLastif (delta > interval) {timeLast = timeNowdistance += (delta / 1000 * v)ctx.clearRect(0, 0, canvasWidth, canvasHeight)for (var x = 0; x < imgWidth; x++) {y = cftA * x * Math.sin(cftX * (x - distance)) + amplitudectx.drawImage(image, x, 0, 1, imgHeight, x, y, 1, imgHeight)// +++++++++++++++++++++ctx.fillStyle = 'rgba(255,255,255,' + (x === 0 ? 0 : (y - lastY) * 0.5) + ')'ctx.fillRect(x, y, 1, imgHeight)// +++++++++++++++++++++lastY = y}}requestAnimationFrame(tick)
}

完整代码戳这里

Demo:See the Pen flag waving by canvas2d(rect)  by Kay (@oj8kay) on CodePen.

方法二的核心代码如下:

var tick = function () {if (stop) return falsetimeNow = Date.now()delta = timeNow - timeLastif (delta > interval) {timeLast = timeNowdistance += (delta / 1000 * v)// +++++++++++++++++++++for (var i = 0; i < canvasHeight; i++) {for (var j = 0; j < canvasWidth; j++) {if (i === 0) {yBuf[j] = cftA * j * Math.sin(cftX * (j - distance))}r = (i * canvasWidth + j) * 4g = r + 1b = r + 2a = r + 3oR = r + (~~(0.5 + yBuf[j])) * canvasWidth * 4oG = oR + 1oB = oR + 2oA = oR + 3offset = j === 0 ? 0 : (yBuf[j] - lastY) * 100pixels[r] = oPixels[oR] + offsetpixels[g] = oPixels[oG] + offsetpixels[b] = oPixels[oB] + offsetpixels[a] = oPixels[oA]lastY = yBuf[j]}}ctx.putImageData(imgData, 0, 0)// +++++++++++++++++++++}requestAnimationFrame(tick)
}

这个方法做出的另外一点修改是,由于操作是对画布逐像素进行的,包括透明元素,所以既不用clearRect,也不用对Y轴进行偏移。

完整代码戳这里

Demo:See the Pen flag waving by canvas2d(pixel)  by Kay (@oj8kay) on CodePen.

两个方法的效果图如下

通过chrome dev tool对两者的性能进行分析:

这是方法1的CPU占有率的变化:

这是方法2的:

哪个性能更好显而易见。方法二的性能虽然差,但是它的好处是灵活性更大,你甚至可以任意改变“光源”的位置。

下一讲我会通过webgl对其进行重写,使其大部分的渲染逻辑从CPU转到GPU,可以使其的性能得到成倍的提高。建议大家先学习一下webgl的一些基本用法,包括矩阵的知识,着色器等。

转载于:https://my.oschina.net/codingDog/blog/1839099

前端实现旗帜飘动效果系列 (Ⅲ):canvas2D实现(2)相关推荐

  1. 前端实现旗帜飘动效果系列 (Ⅰ):dom+css实现

    hello,民娜桑~~我又来开新坑了( ̄ε(# ̄)╰╮o( ̄皿 ̄///),这次尽量保证把这个坑填完~ 本系列我会分四篇来完成主题,分别是① DIV+CSS的实现,② canvas2D的简单实现,③ c ...

  2. 初学RenderMonkey做一面旗帜飘动的效果

    这几天在捣鼓一个游戏 骑马与砍杀 不知道有没有人玩过.官方出了个shader包,可以自定义shader,于是就开始学起来了,学了一点,简单的实现了一直想弄的动态世界.这期间一直在用RenderMonk ...

  3. 【Unity】Shader之旗帜漂浮效果

    模型资源出自<Shader入门精要>的项目,github链接如下: https://github.com/candycat1992/Unity_Shaders_Book 原理:利用顶点动画 ...

  4. 非常漂亮的Web前端波形点击效果

    非常漂亮的Web前端波形点击效果 介绍一种Web前端波形点击效果,第一次发文,大佬勿喷. 我的博客 介绍 Waves 这需要 Waves ,但是作者早在2018年就停止了对他的更新. 官网:Waves ...

  5. OpenGL(十九)——Qt OpenGL波动纹理(旗子的飘动效果)

    OpenGL(十九)--Qt OpenGL波动纹理(旗子的飘动效果) 一.场景 在日常的项目中,我们经常会实现波动的一些纹理效果,比如飘动的旗子,水的波纹,地图上某一点的波浪圈圈等...,本篇介绍波动 ...

  6. html飘羽毛效果,HTML5实现的柳叶飘动效果

    HTML5实现的柳叶飘动效果_网页代码站(www.webdm.cn) .qmg_leaf_div{width:500px;height:200px;overflow:hidden;} .qmg_lea ...

  7. css3蒲公英飘动效果_纯CSS3逼真的气球漂浮动画特效

    这是一款使用纯CSS3制作的效果非常逼真的气球漂浮动画特效.这个气球飘动效果主要使用CSS3 animation来制作,通过控制不同气球的位移和旋转角度,来达到气球漂浮的效果. 制作方法 HTML结构 ...

  8. 2023跨年烟花(浪漫烟花+美妙音乐+雪花飘飘)含前端源码直接下载---系列最终篇

    2023年快要到来啦,很高兴这次我们又能一起度过~ 特辑最终篇!!!  视觉中国 目录 一.前言 二.跨年烟花 三.效果展示 四.详细介绍 五.编码实现 index.html js 六.获取代码 需要 ...

  9. HTML5前端开发入门之H系列标签,P标签和Hr标签

    ##H系列标签(Header1~Header2) -作用:用于给文本添加标题语义 -格式: -<h1>xxxxxx</h2> -注意点: -H标签是用来给文本添加标题语义的,而 ...

最新文章

  1. 解密淘宝网的开源架构(转)
  2. 我和我的Android
  3. python基础知识点总结-Python基础知识总结
  4. 单臂路由的配置及应用:
  5. sqlplus查oracle存储过程,在SQL PLUS中调试Oracle存储过程
  6. Windows下使用Notepad++修改二进制文件,exe可执行文件
  7. 在线流程图绘制网站draw.io支持的三种存储介质
  8. SAP WebIDE里UI5应用的隐藏文件project.json
  9. @data注解的作用_Java中注解学习系列教程-2
  10. SpringCloud注册与发现Eureka
  11. 泡沫股价、外卖小哥要失业了?测试员还要不要进美团?一文带你了解背后真相
  12. Java代码增加回滚6_如何编写取消按钮的代码以撤消/回滚添加和更新正在进行的行4gl...
  13. 计算机usb速度设置,怎样提升USB2.0的速度 注册列表修改法【详解】
  14. Java、OC、C/C++中的null
  15. python安装使用pip安装numpy
  16. oppok3如何刷机_OPPO K3怎么刷机?
  17. 大型电子病历系统【整套源代码分享】
  18. DBSCAN聚类算法
  19. Ckeditor5 整合Ckfinder3 防出错实战教程(二)整合篇
  20. leaflet所有示例下载

热门文章

  1. php去除最后一位,php字符串怎么去除最后一个字符
  2. 苹果开发着账号:个人、公司、企业账号的申请流程
  3. Android实现下拉头部缩放功能
  4. vue 多层双层全选_vue多级复杂列表展开/折叠及全选/分组全选实现
  5. 大一大专计算机考试题型,大专,计算机一级考试考什么内容,麻烦详细点,谢谢。...
  6. 在Windows里备份Linux分区,在Windows里分出Linux分区(Linux分区).pdf
  7. 华为交换机SSH和telnet登录配置
  8. Linux初学(CnetOS7 Linux)之切换命令模式和图形模式的方法
  9. golang 中 map 转 struct
  10. Hadoop记录-metastore jmx配置