1. 首先规划程序逻辑
##1.1 设置canvas款到与浏览器相同
1.1.1: 获取canvas元素
1.1.2: 获取浏览器宽高
1.1.3: 为canvas元素设置宽高
1.1.4:当窗口大小变化时,自动调整canvas大小
1.2. 如何用canvas绘制图形
1.2.1 绘制矩形
1.2.2 绘制圆形
1.2.3 绘制雨滴
1.2.4绘制落地后的水花
1.3 怎么实现动画
1.4 雨滴绘制的原理
1.4.1 使用原型定义雨滴对象
1.4.2 视觉原理,动画实现雨滴下落的绘制
1.5 绘制雨滴N个,不能同时下落
问题一 Canvas宽高设置出现白边
原因:canvas是内联元素,默认display:inline;
白边为行间距。
解决方案:display:block;
问题二 Canvas具有默认大小 300px*150px
问题三 Canvas自适应页面大小如何实现?
参考链接
方案一:CSS设置100%
body{margin:0;}
html,body{
width:100%;
height:100%;
}
#rain{
display:block;
background-color:black;
width:100%;
height:100%;
margin:0;
}
结果:使用也可以实现自适应大小,但是改变页面大小时,雨滴的大小形状会变形。
原因:
将canvas按img理解,canvas样式宽高改变了,但是canvas自身的宽高却不变。当两者的宽高比例不同时,出现内容拉伸。
自适应是指元素的dispaly size缩放,是CSS布局维度(css layout dimension)自适应。而canvas的width/height属性对应的是画布内的coordinate space,不属于css负责.canvas的显示大小可以由css规则指定,但是其内部元素的像素不对应CSS像素或屏幕物理像素进行缩放显示。
方案二:使用JS获取window宽高,为canvas设置
原理:使用样式的宽高比重新设置画布的宽高比。发生重绘。
//1.1 获取canvas元素,只能用id
var can=document.getElementById("rain");
//1.2 浏览器的宽高存放在windows的全局变量
var w=window.innerWidth;
var h=window.innerHeight;
//1.3 设置canvas宽高
can.width=w;
can.height=h;
//1.4 当窗口大小变化时,自动调整canvas大小
//监控浏览器宽高变化
window.onresize=function(){
w=window.innerWidth;
h=window.innerHeight;
//1.3 设置canvas宽高
can.width=w;
can.height=h;
}
问题四 雨滴绘制原理
视觉原理:同样大小的矩形,从远处看,亮的(偏白)看起来比暗的更大。
绘制:
方案一:绘制不同透明度的矩形进行拼接。
方案二:对于一种rgb的矩形,覆盖层数不等的一种rgba整体页面。
方案二更加便于实现。
问题五 setInterval(moveRain,1000/60);
1. satInterval不写函数本体,
2. 函数体内不能写setInterval
3. 16ms所有的
4. 在第0秒就执行moveRain,隔16ms再执行一次,
5. 然而此时rainArray还没有内容,因为创建雨滴是相隔200ms创建一次
6. 进而移动函数mobeRain中无操作对象
7. 尽量不用setInterval
8. JS发现此语句,插入到栈中,间隔执行,无论其他函数怎样运行
9. 缺点:(1)丢帧 ,当callback函数运行时间太长超过setInterval间隔时(2)运行主体 window this指向问题
问题六 一个函数在没有指定调用主体前,它的this永远指向window。
/*封装框架时,this的指向,上下文,作用域
var obj={
num:1,
add:function(){
this.num++;
console.log(this.num);
/*
function(){
console.log(this.num);//此处this为window
})();//运行obj.add()输出为UNDEFINED)
*/
(function(){
console.log(this.num);
}.bind(this))();//运行obj.add()输出为UNDEFINED ;bind(this)之后输出为2),THIS指向
}
}
obj.add();
function aaa(){console.log("a"+this);}
function bbb(cb){
cb&&cb();
console.log("b"+this);
}
bbb.call(obj,aaa);
*/