某时某地,仔细留意花瓣飘来的方向吧,没错,那个地方就叫做爱情公寓
为心爱的人制造一场浪漫,只需一个canvas和一个动画循环。
第一步 定义 画布
首先,chrome浏览器安卓版下载先定义一个背景画布canvas,以及画布绘图能力cxt。
function startSakura() { // 定义canvas画布 var canvas = document.createElement("canvas"), cxt; // 初始化canvas画布 canvas.height = window.innerHeight; canvas.width = window.innerWidth; canvas.setAttribute( "style", "position: fixed;left: 0;top: 0;pointer-events: none;" ); canvas.setAttribute("id", "canvas_sakura"); document.getElementsByTagName("body")[0].appendChild(canvas); // 获取canvas画布上下文 提供在画布上绘图的方法和属性 cxt = canvas.getContext("2d"); ... }
第二步 绘制单个 樱花瓣
此处用到cappleanvas的drawImage()方法。这个方法可以在画布上用canvas绘制任何图像,或其他画布内容,或视频的某一帧图像等等,也可以裁剪只画其中一部分。
语法:
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidappearanceth, dHeight)
参数意义:
-
image: image是画布绘制appointment的图像源,绘制到画布上的元素,可以是canvasElement、imageE接口crc错误计数lement、svgElCanvasemen接口类型t、videAPPoElement等一系列具有图像的接口自动化元素。
-
sx:绘制裁剪的图像源的x坐标位置。
-
sy:绘制裁剪的图像变量与函数源的y坐标位置。
-
sWidth: 绘制裁剪的图像源的canvas宽度变量名。
-
sHeight: 绘制裁剪的图像的高度。
-
dx: 目标源在canvas画布上绘制的左上角的x坐标。
-
dy: 目标源在canvas画布上绘制的左上角的y坐标。
-
dWidtappearh:目标源在canvas画布上绘制的宽度,会自动根据图像源截取的宽度对比做缩放。
-
dHeight: 目标源在canvas画布上绘制的高度,会自动根据图像源截appear取的高度对比做缩放。
// 定义图像元素 var img = new Image() img.src = './images/sakura.png' // 在startSakura方法上加上 // drawImage(image, sx, sy, swidth, sheight, x, y, width, height) cxt.drawImage(img, 0, 0, 40, 40); // 图像加载开始画 img.onload = function() { startSakura(); };
效果如下:

(整张画布在坐标(0,0)处 画了单片花瓣)
第三步 绘制50瓣 樱花瓣
单位以点到面,在画布上花50个花瓣(大小等同,随机x y轴,不旋转)
translate(x,y)方法变量名的命名规则重新映射画布上的 (0, 0) 位置。也就是画布的平移
参数
x:X轴的偏移量
y:Y轴的偏移量
// 单花瓣 类 function Sakura(x, y, s) { this.x = x; // x轴坐标 this.y = y; // y轴随机坐标 this.s = s; // sakura大小 } Sakura.prototype.draw = function(cxt) { var xc = (40 * this.s) / 4; // 画布平移 cxt.translate(this.x, this.y); // drawImage(图像源,图像x坐标,图像y坐标,宽度, 高度) cxt.drawImage(img, 0, 0, 40 * this.s, 40 * this.s); };
// 多花瓣 类 SakuraList = function() { this.list = []; }; SakuraList.prototype.push = function(sakura) { this.list.push(sakura); }; // 多个单瓣 组成 一组花瓣 SakuraList.prototype.draw = function(cxt) { for (var i = 0, len = this.list.length; i < len; i++) { this.list[i].draw(cxt); } };
绘制成形:
var sakuraList = new SakuraList(); for (var i = 0; i < 50; i++) { // x轴随机 y轴随机 大小不变 sakura = new Sakura(Math.random() * 20, Math.random() * 5, 1); sakuraList.push(sakura); } sakuraList.draw(cxt); // 绘制
效果图如下:

第四步 随机x轴 y轴、随机大小变量之间的关系、随机旋转角度、
随机函数getRandom如下canvas平台:
function getRandom(option) { var ret, random; switch (option) { case "x": // x轴随机坐标 ret = Math.random() * window.innerWidth; break; case "y": // y轴随机坐标 ret = Math.random() * window.innerHeight; break; case "s": // sakura大小 ret = Math.random(); break; case "r": // sakura旋转角度 ret = Math.random() * 6; break; } return ret; }
这50片,每单个随机坐标随机大小随机角度
var sakuraList = new SakuraList(); for (var i = 0; i < 50; i++) { var sakura, randomX, randomY, randomS, randomR; randomX = getRandom("x"); randomY = getRandom("y"); randomR = getRandom("r"); randomS = getRandom("s"); sakura = new Sakura(randomX, randomY, randomS, randomR); sakuraList.push(sakura); } sakuraList.draw(cxt); // 绘制
效果如下:

第五步 花瓣动起来
定义一个动画控制函数,告诉浏览器希望执行动接口是什么画
window.requestAnimatichrome安卓下载onFrame:
是浏览器用于定时循环操作的一个接口,类似于setTimeout,主要用途是canvas网页版按帧对网页进行重绘。
设置这个API的目的是为了让各种网页动画效果能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。
function startSakura() { //兼容性 不同浏览器的动画控制函数 告诉浏览器希望执行动画 var requestAnimationFrame = window.requestAnimationFrame || //chrome window.mozRequestAnimationFrame || // Firefox window.webkitRequestAnimationFrame || // Chrome 兼容不同版本 window.msRequestAnimationFrame || // IE window.oRequestAnimationFrame; // Opera // 定义canvas画布 var canvas = document.createElement("canvas"), cxt; ... // 第四步花瓣循环 ... // 定义一个stop变量 (循环:清空画布-绘制-重绘) stop = requestAnimationFrame(function() { cxt.clearRect(0, 0, canvas.width, canvas.height); // 清空画布 sakuraList.draw(cxt); // 绘制 stop = requestAnimationFrame(arguments.callee); // 递归重绘 }); }
到这一步还没完,因为每次sakuraList中的单类还是同样位置,即使用了动画控制函数window.requestAnimationFrame,每一帧还是在原来的位置,这样看起来还是没有在动。那么就变量之间的关系要【更新一下x轴y轴以及每一帧的旋转角度】
function getRandom(option) { var ret, random; switch (option) { ... case "fnx": // x轴随机函数 random = -0.5 + Math.random() * 1; ret = function(x, y) { return x + 0.5 * random - 1.7; }; break; case "fny": // y轴随机函数 random = 1.5 + Math.random() * 0.7; ret = function(x, y) { return y + random; }; break; case "fnr": // r轴随机函数 random = Math.random() * 0.03; ret = function(r) { return r + random; }; break; } }
沿用上一appointment帧的x接口测试 y r,做一些小改动,保证肉眼看到的每一帧连贯性流畅性。
Sakura.prototype.update = function() { this.x = this.fn.x(this.x, this.y); this.y = this.fn.y(this.y, this.y); this.r = this.fn.r(this.r); if ( // 判断是否超出边界 this.x > window.innerWidth || this.x < 0 || this.y > window.innerHeight || this.y < 0 ) { // 如果超出边界 则重新生成随机坐标 this.r = getRandom("fnr"); if (Math.random() > 0.4) { // 如果随机值大于0.4 则重新生成x轴随机坐标 this.x = getRandom("x"); this.y = 0; this.s = getRandom("s"); this.r = getRandom("r"); } else { // 如果随机值小于0.4 则重新生成y轴随机坐标 this.x = window.innerWidth; this.y = getRandom("y"); this.s = getRandom("s"); this.r = getRandom("r"); } } }; // 清空画布之前 调用一下更新函数 sakuraList.update(); // 更新
其中单花瓣Sakura.prototypeappreciate.draw这个方法加上两句话:
c接口和抽象类的区别xt.save();
// 保存先前的状态
cxt.restore();
/canvas上交/ 恢复之前保存的状态
注:两种方法必须搭配使用,否则没有效果
canvas动画: 先保存的后恢复,后保存的先恢复。
总结
从点到面、从静到动。知识点: canvas相关、window.reapproachquestAnimatioapproachnFrame浏览器动画函数window.requestAnimationFram相关。
代码
花瓣飘来的地方,曾经appstore,最好的朋友在身边,最爱的人在对面。如今,有的人还在追逐梦想,有的人已经背起行囊,奔向远方。这里有太多快乐与忧伤,太多遗憾与不舍。但新的故事,总要启航canvas翻译…
评论(0)