某时某地,仔细留意花瓣飘来的方向吧,没错,那个地方就叫做爱情公寓
为心爱的人制造一场浪漫,只需一个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翻译…