html5+canvs实现flash效果。

   2023-02-08 学习力0
核心提示:[转自:http://www.javaeye.com/topic/602187]效果和源码:(本代码使用了本人自己的js框架,自己修改代码的话, 请务必引用我试用的框架,否则会出现错误)(请务必试用非ie浏览器浏览,极力推荐Safari和 chrome,其他浏览器运行速度堪忧)http://www.beiju123.cn/blog

[转自:http://www.javaeye.com/topic/602187]

效果和源码:(本代码使用了本人自己的js框架,自己修改代码的话, 请务必引用我试用的框架,否则会出现错误)

(请务必试用非ie浏览器浏览,极力推荐Safari和 chrome,其他浏览器运行速度堪忧)

http://www.beiju123.cn/blog/wp-content/uploads/2010/02/canvas-demo.html

1.什么是canvas:

引用Firefox开发者中心的一段话:<canvas> is a new HTML element which can be used to draw graphics using scripting (usuallyJavaScript). It can for instance be used to draw graphs, make photo compositions or do simple (and not so simple) animations. The image on the right shows some examples of <canvas>implementations which we will see later in this tutorial.

注意,canvas主要是用来画图的,而不是注重动画,所以在canvas中没有帧的概念,没有精灵(Sprite)的概念,flash中的概念在 canvas中很多都不存在.

canvas说白了,就是给js加了几个对象,多了几个方法.并不是一个独立的东西,应该说是JavaScript的一点点补充.就跟其他编程语言 中的graphic对象差不多,提供了画基本图形和路径,图像,提供了颜色和样式管理.

更多关于canvas的基础,见https://developer.mozilla.org/en/Canvas_tutorial(英 文版)

 


2.基本的动画:

可能很多人会嚼的我这篇文章纯属多余,既然能够画图,那加上一个定时器不就是动画了嘛?

是的,如果你只是想在画布上画出一个圆或者矩形,然后让它动起来的话,那这么做无疑是可以得出结果的.代码也很简单,如下:

var x=0;
var y=0;
var ctx = document.getElementByIdx_x('canvas').getContext('2d');
setInterval(function(){
ctx.clearRect(0,0,800,800);//清除画布某某个范围内的内容,参数分别为x,y,宽度,高度
ctx.fillStyle = '#FFF'//设置颜色
ctx.fillRect(x++,y++,50,50)//画一个矩形,参数为:x,y,宽,高
})

效果就是一个方块在画布上向右下角移动.


3.升级需求:

动画往往不是如此简单,在flash里,复杂的动画里会包含很多元素,有剪辑,有精灵,他们之间还有包含关系,我们可以单独控制某个元素的移动,控 制速度,控制属性.flash里有帧,我们可以在帧上放置元素,控制帧速.最重要的,做复杂的动画的时候,我们需要把每个元素抽象成一个完整的对象,例 如:一个人对象啊,我们需要控制它走动,控制它攻击.

可是在canvas里面,图形并不是一个对象,在整个canvas元素里,有且只有只有一个画布的对象(多次创建的话,只会创建一个引用),如果想 把里面的图形作为对象来控制的话,上面的动画方法就做不到了.这个时候,考虑一下flash的工作原理,我想出了如下的解决方案.


4.让画布里的图形变成可以控制的对象:

我们现在需要一种新的方法,这种方法可以让画布上的元素变成可以单独控制的对象.而画布上其实只有一个对象,怎么让它能承载多个动画对象呢?

我们想想flash的工作原理吧,flash中最基本的两个东西,一个是帧,一个是精灵(Sprite).下面我们就给我们的动画程序添加这两个概 念.

首先是帧,我们通过一个定时器,每隔一段时间就重画一下画布,在这段时间里我们改变画布上的元素的位置,这样就是最基本的帧了.

然后现在问题就是如何控制画布上元素的属性呢?我们把画布上所有要用到的动画元素都抽象出来,每个元素都抽象成一个对象,这个对象拥有位置和大小, 速度等信息.然后在每一帧重画画布的时候,我们遍历这些对象,调用它们自己的draw方法,让它们根据自己的属性把自己画到画布上.我们将这些元素统称为 Sprite,也就是动画精灵.

现在,我们就可以控制这些动画元素了,因为它们都被抽象成了对象,可以有自己的属性和方法,他们都要实现一个接口.虽然在js中不存在接口的概念, 但是我们要自己去衡量在每个扩展的精灵里是否都实现了接口的方法.因为这些方法都是必须的.我们把这个接口定义成如下的样子:


var Sprite=function(){
this.speed={
x:1,
y:1
}
}
Sprite.prototype={

draw:function(){

},

move:function(){
this.x+=this.speed.x;
this.y+=this.speed.y;
if(this.childs!=null&&this.childs.length>0){
for(var i=0;i<this.childs.length;i++){
this.childs[i].speed=this.speed;
this.childs[i].move();
}
}
},

appendChild:function(sprite){
if(this.childs==null) this.childs=[]
this.childs.push(sprite)
},

drawChild:function(){
if(this.childs!=null&&this.childs.length>0){
for(var i=0;i<this.childs.length;i++){
this.childs[i].draw();
}
}
}
}

下面定义一个帧的对象,我们将其命名为:Canvas.


var Canvas=function(){
this.interval=null;
this.sprites=[]
}

Canvas.prototype={

begin:function(){
this.interval=setInterval((function(param){
return function(){param.render();}
})(this),20);
},

render:function(){
// M.trace(this.sprites.length)
this.ctx.clearRect(-800, -800, 1600, 1600)
for(var i in this.sprites){
if(typeof(this.sprites[i])=="function") continue;
this.sprites[i].draw();
}
},

addSprite:function(name,sprite){
this.sprites[name]=sprite;
},

stop:function(){
clearInterval(this.interval)
},
clear:function(){
for(var i in this.sprites){
if(typeof(this.sprites[i])=="function") continue;
if(this.sprites[i].x>800&&this.sprites[i].y>800){
delete this.sprites[i]
}
}
}
}

上面两个对象:精灵和帧.是本文讨论中的重点,有了他们,我们就可以开始组建我们的高级动画程序了.


5.开始我们的动画之旅吧:

基础有了,那我们就开始构建动画吧,首先注意上面两个对象,其中的精灵并不是真实的对象,而只是提供一个类似接口的东东,如果我们想构建动画的话, 我们需要构建一个继承自精灵的真正的对象.

下面,我们构建一个圆环对象,然后实例化多个圆环对象,之后控制这些实例的运作:


var Circle=function(ctx,x,y,radius,config){
this.ctx=ctx;
this.x=x;
this.y=y;
this.radius=radius;
this.config={
strokeStyle:"#000",
lineWidth:"1"
}
M.dom.mixin(this.config, config)
}
Circle.prototype=new Sprite();

Circle.prototype.draw=function(){
this.ctx.beginPath();
this.ctx.lineWidth = this.config.lineWidth;
this.ctx.strokeStyle =this.config.strokeStyle;
this.ctx.arc(this.x,this.y,this.radius,0,Math.PI*2,true)
this.ctx.stroke();
this.drawChild();
}

这就是一个基础的圆环的对象,当然你可以给它添加其他任何属性和方法来使它看起来和动起来像一个真正的"对象"(智能对象?)

下面是重要的一步,通过这一步我们在画布上产生100个圆环,它们的位置会是随机的,而且它们向着不同的方向前进:

首先,我们初始化我们的动画程序:

var ctx=$("canvas").getContext('2d');
var can=new Canvas();
can.ctx=ctx;
can.begin();//开始渲染
setInterval(function(){
for(var i in can.sprites){
if(typeof(can.sprites[i])=="function") continue;
can.sprites[i].move()
}
},20)//这里就是帧速了,这里是50帧每秒

然后我们创建100个圆环:

for(var i=0;i<100;i++){
var circle=new Circle(ctx,0,0,m.random(30))
circle.speed={x:Math.random(4),y:Math.random(4)}
can.addSprite(i, circle)
}

如果此时打开此网页,你会发现一百个圆环从原点处开始向右下角移动了.速度不同,方向不同,俨然一群小生命.俨然一群真正的对象.

具体原理,请揣摩源代码:


6.其他

我在程序里还添加了一个特性,让精灵有了层级的概念,类似flash中的剪辑,当然还很不完善,只是做个演示,这里也就不介绍如何使用了,回头我还 要好好修改一下,让精灵变成影片剪辑的概念.这样才能创作出更加复杂的动画

回头等先做个游戏演示一下.canvas看起来简单,其实要想做出大型的东西来还是需要好好思考的.

 
反对 0举报 0 评论 0
 

免责声明:本文仅代表作者个人观点,与乐学笔记(本网)无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
    本网站有部分内容均转载自其它媒体,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责,若因作品内容、知识产权、版权和其他问题,请及时提供相关证明等材料并与我们留言联系,本网站将在规定时间内给予删除等相关处理.

  • HTML中将背景颜色渐变 html设置背景颜色渐变
    通过使用 css3 渐变可以让背景两个或多个指定的颜色之间显示平稳的过渡,由于用到css3所以需要考虑下浏览器兼容问题,例如:从左到右的线性渐变,且带有透明度的样式:#grad {background: -webkit-linear-gradient(left,rgba(255,0,0,0),rgba(255,0,0,1)); /*
    03-08
  • html5 Canvas 如何自适应屏幕大小
    但是这样创建出的画布不能随着浏览器窗口大小的改变而动态的改变画布的大小。而这一点往往又非常重要, 因为我们会经常改变浏览器窗口大小,不会一直保持某个固定的大小。 html代码 canvas width="300" height="300" id="myCanvas"/canvas设置样式 * {
    03-08
  • Vue中出现Do not use built-in or reserved HTML elements as component id:footer等等vue warn问题
    Vue中出现Do not use built-in or reserved HTM
    错误示图:原因:是因为在本地项目对应文件的script中,属性name出现了错误的命名方式,导致浏览器控制台报错!  诸如: name: header 、  、 name: menu , 等等都属于错误的命名方式等 错误代码命名如下:解决办法:办法1: 如果我们采用正确命名
    03-08
  • HTML在网页中插入音频视频简单的滚动效果
    HTML在网页中插入音频视频简单的滚动效果
    每次上网,打开网页后大家都会看到在网页的标签栏会有个属于他们官网的logo,现在学了HTML了,怎么不会制作这个小logo呢,其实很简单,也不需要死记硬背,每当这行代码出现的时候能知道这是什么意思就ok1 link rel="shortcuticon" type="image/x-icon" href="
    03-08
  • HTML的video标签,不能下载视频代码
    !-- 在线视频不能下载代码 --!DOCTYPE html html headscript src="../Demo/demo/book/JQuery/jQuery v2.2.0.js"/script/headbody div style="text-align:center;"video src="../images/PreviewVideo.mp4" width="820"controls="controls&
    03-08
  • ThinkPHP报错 The requested URL /admin/index/login.html was not found on this server.
    ThinkPHP报错 The requested URL /admin/index/
           解决方案在入口文件夹public下查看.htaccess是否存在。不存在则新建,存在的话,那内容替换为下面这串代码 就可以解决Not Fund#IfModule mod_rewrite.c#Options +FollowSymlinks -Multiviews#RewriteEngine On##RewriteCond %{REQUEST_FILENAME
    03-08
  • HTML特殊字符、列表、表格总结 html特殊符号对
            HTML实体字符  在HTML中一些特殊的字符需要用特殊的方式才能显示出来,比如小于号、版权等,  在课堂上老师教了我们一个有点意思的:空格,在教材上字符实体是“nbsp”通过老师  的演示我们发现不同的浏览器他所显示的效果不同,有的比
    03-08
  • 【JavaScript】使用document.write输出覆盖HTML
    您只能在 HTML 输出中使用 document.write。如果您在文档加载后使用该方法,会覆盖整个文档。分析HTML输出流是指当前数据形式是HTML格式的数据,这部分数据正在被导出、传输或显示,所以称为“流”。通俗的来说就是HTML文档的加载过程,如果遇到document.writ
    03-08
  • ASP.Net MVC 控制@Html.DisplayFor日期显示格式
    在做一個舊表的查詢頁時,遇到一個問題:字段在db里存儲的是DATETIME,但保存的值只有日期,沒有時間數據,比如2018/2/26 0:00:00,顯示出來比較難看,當然也可以做一個ViewModel,在字段上添加Attribute定義來更改名稱和顯示名稱,如下:[Display(Name = "建
    03-08
  • html 基础代码
    title淄博汉企/title/headbody bgcolor="#00CC66" topmargin="200" leftmargin="200" bottommargin="200"a name="top"/a今天br /天气nbsp;nbsp;nbsp;nbsp;nbsp;不错br /font color="#CC0000"格式控制标签br /b 文字加粗方式1\bbr /str
    03-08
点击排行