html5⽔池,分享⽤canvas实现⽔流和⽔池动画的代码
svg和canvas的区别利⽤Html 5的canvas标签绘制⽔流和⽔池动画
在利⽤HTML 5的canvas进⾏动画绘制之前,⾸先先介绍⼀下基本知识,包括canvas(如果对canvas⽐较熟悉的可以直接跳过该节)、oCanvas框架、精灵动画。在了解了以上的基本知识后,就可以开始利⽤canvas做动画了。
canvas标签简介
在这部分,东西⽐较多,⽐较杂,各个⽹站上都可以到相关的简介,在此我就不造轮⼦了,菜鸟上的教程就挺不错的,另外推荐⼀个相当好的博⽂玩转html 5 canvas画图,这篇⽂章介绍的⾮常详细,推荐好好看看。
canvas框架oCanvas简介
canvas标签功能⾮常强⼤,既可以处理图⽚,⼜可以进⾏像素级的处理,完全可以取代浏览器端的flash,但是由于canvas发展还未完善,API还不是太全,元素的事件处理功能等还没有提供接⼝,在实现⼀些复杂功能时,尚需耗费许多精⼒,于是出现了许多第三⽅的基于canvas 的框架,这些框架相⽐于原⽣的canvas标签,有了更多简单易⽤的API,⼤⼤提⾼了我们编码的效率,在这⾥我选⽤的是oCanva
s 框架,相关的使⽤⽂档和demo都可以去上⾯的链接中查看。
精灵动画简介
精灵动画⼀般由⼀组⾃定义的属性值和3个⼦函数组成(init、advance、draw)。
三个函数的作⽤分别如下:
init:初始化精灵动画的属性值
advance:再画下⼀帧之前⾸先更新下⼀帧的状态值
draw:将advance函数中更新的状态值绘制到画布中
以上三个函数的执⾏顺序是:init->advance->draw->advance->draw->…..⼀直循环下去。下⾯我以⼀个随机产⽣上升⽓泡的例⼦说明⼀下上⾯的执⾏过程。var constructor_bubble = function (settings, core) {
d({
core: core,
shapeType: "rectangular",//下⾯定义了上⾯我们提到的三个函数:init(),advance(),draw()//在init中,我们map对象组、⼀个空的数组和⼀个代表⾼度的属性值
init: function () {
this.map=[
{r:2,speed:3},
{r:3,speed:3},
{r:4,speed:3},
{r:5,speed:3},
{r:6,speed:3},
{r:7,speed:3},
{r:8,speed:3},
{r:9,speed:3},
{r:10,speed:3}
]; this.points=[]; this.ainer.height_now;
},//下⾯是advance函数,在函数中我们利⽤if逻辑判断是否添加新的⽓泡以及进⾏⽓泡的位置更新,points数组利⽤队列的先进先出来存储⽓泡的
advance: function () {
this.ainer.height_now; if(Math.random()>0.95){ var new_point={
x:this.start.x+this.offset*2*(Math.random()-0.5),
y:this.start.y-this.map[0].r,
r:this.map[0].r
}; this.points.push(new_point);
} if(this.points.length>0){ for(var i=0;ithis.height-this.points[i].r-33){ this.points.shift();
}
}
}
},//draw函数中,利⽤canvas的圆弧绘制指令,将points数组中存储的⽓泡依次画出
draw: function () {
var canvas = anvas;
canvas.lineJoin = 'round';
canvas.lineWidth = this.GDwidth;
canvas.strokeStyle = "#fff"; if(this.points.length>0){ for(var i=0;i
canvas.beginPath();
canvas.arc(this.points[i].x,this.points[i].y,5,0,2*Math.PI);
canvas.stroke();
canvas.closePath();
}
}
}
}, settings);
};
start:{x:425,y:566},
container:SC02,
width:50,
offset:1,
speed:5
}).add();
⽔流和⽔池动画实现
下⾯详细介绍⼀下,项⽬中如何实现⽔流动画和⽔池动画的详细步骤:
⽔池动画的绘制var constructor_show = function (settings, core) {
d({
core: core,
shapeType: "rectangular",//上⾯四⾏都是oCanvas框架的结构语法/*下⾯init()、advance()、draw()分别是上节中说的动画精灵三元素,第⼀个⽤来初始化,第⼆个⽤来
更新操作,第三个⽤来绘制图像/动画在管道对象中,定义了⼀些属性,包括:x、y、height、width、start、
height_now、full、speed、fill、trail_flag、[trail]。其中x、y分别代表⽔池参考点相对画布左
上⾓的位置,height、width是⽔池的宽⾼属性,start表征了动画是否开始,height_now代表了⽔池中⽔
位的⾼度,full表征了⽔池是否填满,speed⽔池上涨的速度,fill⽔的颜⾊,trail_flag表征了该⽔池
是否是⼀个标准的矩形,如果不是的话,配合trail属性,指定⽔池的轮廓*/
init: function () {
//默认动画关闭,⽔池full为0,当前⾼度为0
this.start=0; this.full=0; this.height_now=0;
},
advance: function () {
//如果⽔池未满并且是开启状态,⽔位未满就更新当前⾼度,否则将full置为1
if(this.start==1&&this.full!=1){ if (this.height_now < this.Height) { this.height_now += this.speed;
} else { this.full = 1;
}
}
},
draw: function () {
var canvas = anvas, //先获得⽔池的位置
origin = Origin(),
x = this.abs_x - origin.x,
y = this.abs_y - origin.y; //开始绘制
canvas.beginPath();
canvas.strokeStyle = "#000"; if (ail_flag == 1) { //如果是不规则图形,描出轮廓
canvas.ail[i].x_t, ail[i].y_t);
}
canvas.ail[0].x_t, ail[0].y_t);
canvas.clip();
} if (this.fill !== "") { //设置颜⾊,绘制矩形⽔池
canvas.fillStyle = this.fill;
canvas.fillRect(x, y + this.Height - this.height_now, this.Width, this.height_now);
}
canvas.closePath();
}
}, settings);
};//将上⾯的动画精灵注册进oCanvas的display图形库中isterDisplayObject("SC_show", constructor_show, "init");管道⽔流动画的绘制
在管道⽔流模型中,定义了以下的属性:
destination: 当前⽔流最前端的位置
cells: 管道路径数组
deta: ⽅向斜边长
deta_x: ⽅向x边长
deta_y: ⽅向y边长
flag_x: 余弦值
flag_y:正弦值
cellIndex: 当前绘制边的index
Speed: ⽔流速度
GDwidth:⽔流宽度
LineHeight:⽔流长度
x_now: 当前绘制点x坐标
y_now: 当前绘制点y坐标
firstX: 管道第⼀个点坐标x
firstY: 管道第⼀个点坐标y
beginHeight: 第⼀段⽔流的起点位置
endHeight: 上⼀段管道遗留未画完的⽔线
legacyHeight: 最前端点在上⼀个管道留下的长度
paused: 是否开始
fill:⽔流颜⾊
full:是否填满
init函数//init函数主要完成初始化⼯作init: function () {
this.x_now = lls[0].x_cell;
this.y_now = lls[0].y_cell;
this.firstX = this.x_now;
this.firstY = this.y_now;
this.beginHeight = 0;
this.paused=0;
this.full=0;
this.destination.x_d = lls[0].x_cell;
this.destination.y_d = lls[0].y_cell;
this.legacyHeight = -1;
this.LineHeight=10;
this.Speed=2*this.LineHeight/20;
}
advance函数//advance函数主要实现每次动画的刷新步进操作
advance: function () {
if(this.paused==1){
if (llIndex < lls.length - 1) {
this.deta_x = llIndex + 1].x_cell - llIndex].x_cell; this.deta_y = llIndex + 1].y_cell - llIndex].y_cell; this.deta = Math.sqrt(this.deta_x * this.deta_x + this.deta_y * this.deta_y);
this.flag_x = this.deta_x / this.deta;
this.flag_y = this.deta_y / this.deta;
if (this.legacyHeight >= 0) {
if (llIndex < lls.length - 1) {
this.deta_x = llIndex + 1].x_cell - llIndex].x_cell; this.deta_y = llIndex + 1].y_cell - llIndex].y_cell; this.deta = Math.sqrt(this.deta_x * this.deta_x + this.deta_y * this.deta_y);
this.flag_x = this.deta_x / this.deta;
this.flag_y = this.deta_y / this.deta;
this.destination.x_d = llIndex].x_cell + this.flag_x * this.legacyHeight; this.destination.y_d = llIndex].y_cell + this.flag_y * this.legacyHeight;
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论