前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Canvas特效之魔鬼四边形

Canvas特效之魔鬼四边形

作者头像
Jean
发布2021-10-27 11:44:25
5360
发布2021-10-27 11:44:25
举报
文章被收录于专栏:Web行业观察

像素流Peer Stream的仓库中有一个专门用于网络状态嗅探的虚幻模拟器:test/unreal.html。其中提供了3种即时视频流,分别是摄像头、屏幕录制、canvas动画,本文介绍这个canvas动画的实现原理,只有短短20行代码。

如图所示,和上一期《Shader编程之地标特效》中运行在GPU上的shader特效不同,canvas特效是运行在CPU上的,2个算法有本质区别,canvas算法的优势在于比较好理解,适合比较简单的、二维的特效。首先观察一下这个特效,它有以下特征:

  • 动画在一个圆形区域内的二维动画。
  • 若干个同心四边形(矩形框、方框)以正弦函数的规律来回旋转。
  • 边长更大的四边形质量更大,“惯性”也看上去更大,整体看来,像是中心的旋转力量带动了周围四边形的旋转。
  • 四边形的颜色是任意的不透明的饱和色,亮度适中。

首先需要一个<canvas>画板,并指定任意的宽高:

代码语言:javascript
复制
<canvas id="canvas" width="500" height="500"></canvas>

接下来通过getContext函数定义它为二维画板,接着将canvas的宽和高中最小的一边作为圆形区域的直径,通过CanvasRenderingContext2D的clip方法限定圆形绘画区域,完整的代码如下:

代码语言:javascript
复制
const $ = canvas.getContext("2d");
const l = Math.min(canvas.width, canvas.height) / 2;

$.strokeStyle = `hsl(${360 * Math.random()}deg 100% 50%)`;
$.lineWidth = 6;

$.beginPath();
$.arc(l, l, l, 0, Math.PI * 2);
$.clip();

(function frame(time) {
  $.clearRect(-l, -l, l * 2, l * 2);

  for (let x = 1; x <= l; x += $.lineWidth + 2) {
    $.strokeRect(-x, -x, x * 2, x * 2);
    const theta = Math.sin(x / l - time / 512) * 60;
    $.setTransform(new DOMMatrix().translate(l, l).rotate(0, 0, theta));
  }

  window.animationFrame = requestAnimationFrame(frame);
})(0);

然后我们使用CSS的hsl函数生成随机的饱和亮色,使得特效更鲜艳。在256 x 256 x 256 = 16777216种真彩色中,只有256 x 256 x 3 = 196608种饱和色,约占总数的1%,剩下的颜色都是不鲜艳的,而这1%的饱和色中又只有256 x 6 = 1536种亮色,剩下的都不够亮。所以既饱和又明亮的颜色只占总数的(256 x 6) / (256 x 256 x 256) ≈ 0.009%,在色谱上,只有一条边属于这个范围:

接下来我们要定义每一帧的函数frame(time),然后通过requestAnimationFrame来循环调用frame,并且传入当前的时刻time,我们利用这个时刻来计算当时每个四边形的旋转角度。每一帧中,先使用clearRect函数清除掉上一帧的画面,然后遍历每个四边形,矩形边框(四边形)之间保持一定的间隙,最后在正弦函数中决定这个方框的角度,角度和当前时刻和方框的边长都有关系,所以Math.sin中传入了2个变量:空间变量x(边长)和时间变量time(时刻)。最终调用strokeRect函数画出方框,就实现了魔鬼四边形特效:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WebHub 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档