用Canvas制作可以根据手势摆动的树

用Canvas制作可以根据手势摆动的树

根据工作的需要,制作一个摆动的树做为页面的背景。为了增加页面的交互性,我又为背景中的树增加了鼠标(触控)事件,使他能够根据鼠标(触控)做出相应的动作,当手指做上下或者左右滑动的时候树会跟着摆动。先看看最终效果。

Step1.完成HTML页面,新建一个Tree类

完成HTML页面后新建一个Tree类用来记录树的各个属性。其中x,y为树根部的坐标值,branchLen,branchWidth分别是树枝的长度与宽度,depth为树枝的层数,canvas用来接页面中的canvas元素(默认是ID为canvas的元素)。

function Tree(x,y,branchLen,branchWidth,depth,canvas){
    this.canvas = canvas || document.getElementById('canvas');
    this.ctx = this.canvas.getContext('2d');
    this.x = x||0;
    this.y = y||0;
    this.branchLen = branchLen||0;
    this.branchWidth = branchWidth||0;
    var depth = depth || 5;
}

点击查看历史代码

Step2.添加drawRoot方法,用来绘制树干

首先在drawRoot中画第一个枝干。drawRoot的参数意义同上。并且在Tree类的构造函数中运行drawRoot并把Tree接受到的参数传入。最后new一个Tree类,使树根位于屏幕的底部正中心,树枝长100px,树枝宽度为8px,树枝层数为8层(暂时用不上)。var atree = new Tree(canvas.width/2-4,canvas.height,100,8,8,canvas);

在drawRoot中我们需要用lineTo()画出树枝。树枝的起始的坐标值(x,y)已经给出,结束的坐标值(toX,toY)需要进行计算。第一个画的是树干,由于树干垂直于地面所以结束坐标toX等于初始坐标x,而结束坐标toY等于初始y减去树干长度branchLen(注意坐标的0,0点在canvas的左上角)。var
toX = x;var toY = y-branchLen;

function Tree(x,y,branchLen,branchWidth,depth,canvas){
    this.canvas = canvas || document.getElementById('canvas');
    this.ctx = this.canvas.getContext('2d');
    this.x = x||0;
    this.y = y||0;
    this.branchLen = branchLen||0;
    this.branchWidth = branchWidth||0;
    var depth = depth || 5;
    this.drawRoot(this.x,this.y,this.branchLen,this.branchWidth);
}
Tree.prototype.drawRoot = function(x,y,branchLen,branchWidth){
    var toX = x;
    var toY = y-branchLen;
    this.ctx.save();
    this.ctx.strokeStyle="rgba(37, 141, 194, 0.93)";
    this.ctx.beginPath();
    this.ctx.lineCap = "butt";
    this.ctx.lineJoin="round";
    this.ctx.lineWidth = branchWidth;
    this.ctx.moveTo(x,y);
    this.ctx.lineTo(toX,toY);
    this.ctx.closePath();
    this.ctx.stroke();
    this.ctx.restore();
}
var atree = new Tree(canvas.width/2-4,canvas.height,100,8,8,canvas);

运行代码:

点击查看历史代码

Step3.添加drawBranch方法,用来绘制树枝

drawBranch同样是根据初始与结束坐标画出一条直线代表树枝。与树干不同的是树枝不再是垂直与地面而是与树干保持一定的角度,而且树枝的初始值是树干的结束点(toX,toY)。所以在drawBranch中我们加入新参数angle用来表示树枝与树干的垂直夹角α,这样就可以根据α算出toX与toY。请看图。

这样我们在画完树干后再分别画两个不同角度的树枝,一个是30°一个-30°。并将传给树枝的宽度branchWidth减小一个像素,使其与树干粗细不同。

Tree.prototype.drawRoot = function(x,y,branchLen,branchWidth){
    var toX = x;
    var toY = y-branchLen;
    this.ctx.save();
    this.ctx.strokeStyle="rgba(37, 141, 194, 0.93)";
    this.ctx.beginPath();
    this.ctx.lineCap = "butt";
    this.ctx.lineJoin="round";
    this.ctx.lineWidth = branchWidth;
    this.ctx.moveTo(x,y);
    this.ctx.lineTo(toX,toY);
    this.ctx.closePath();
    this.ctx.stroke();
    this.ctx.restore();
    this.drawBranch(toX,toY,branchLen,branchWidth-1,30);
    this.drawBranch(toX,toY,branchLen,branchWidth-1,-30);
}
Tree.prototype.drawBranch = function(x,y,branchLen,branchWidth,angle){
    var angle = angle || 0;
    var radian = (90-angle)*(Math.PI/180);
    var toX = x+Math.cos(radian)*branchLen;
    var toY = y-Math.sin(radian)*branchLen;
    this.ctx.save();
    this.ctx.strokeStyle="rgba(37, 141, 194, 0.93)";
    this.ctx.beginPath();
    this.ctx.lineCap = "butt";
    this.ctx.lineJoin="round";
    this.ctx.lineWidth = branchWidth;
    this.ctx.moveTo(x,y);
    this.ctx.lineTo(toX,toY);
    this.ctx.closePath();
    this.ctx.stroke();
    this.ctx.restore();
}

运行代码:

点击查看历史代码

Step4.修改drawBranch函数,重复画树枝

在drawBranch函数的最后再次调用两次drawBranch

this.drawBranch(toX,toY,branchLen,branchWidth-1,angle+30);
this.drawBranch(toX,toY,branchLen,branchWidth-1,angle-30);

使其调用自己完成递归,注意这里传入的角度是在之前的角度的基础上在增加或者减少30度。

为了使递归停下来我们需要一个停止条件,就是之前一直没有用到的depth参数。我们在每次画下一层之前使其减1表示已经完成了一层树枝的绘制,直至depth减小到0表示绘制完所有的层数。

function Tree(x,y,branchLen,branchWidth,depth,canvas){
    this.canvas = canvas || document.getElementById('canvas');
    this.ctx = this.canvas.getContext('2d');
    this.x = x||0;
    this.y = y||0;
    this.branchLen = branchLen||0;
    this.branchWidth = branchWidth||0;
    var depth = depth || 5;
    this.drawRoot(this.x,this.y,this.branchLen,this.branchWidth,depth);
}
Tree.prototype.drawRoot = function(x,y,branchLen,branchWidth,depth){
    var toX = x;
    var toY = y-branchLen;
    var depth = depth||5;
    this.ctx.save();
    this.ctx.strokeStyle="rgba(37, 141, 194, 0.93)";
    this.ctx.beginPath();
    this.ctx.lineCap = "butt";
    this.ctx.lineJoin="round";
    this.ctx.lineWidth = branchWidth;
    this.ctx.moveTo(x,y);
    this.ctx.lineTo(toX,toY);
    this.ctx.closePath();
    this.ctx.stroke();
    this.ctx.restore();
    depth--;
    if(depth>0){
      this.drawBranch(toX,toY,branchLen,branchWidth-1,30,depth);
      this.drawBranch(toX,toY,branchLen,branchWidth-1,-30,depth);
    }
}
Tree.prototype.drawBranch = function(x,y,branchLen,branchWidth,angle,depth){
    var angle = angle || 0;
    var radian = (90-angle)*(Math.PI/180);
    var toX = x+Math.cos(radian)*branchLen;
    var toY = y-Math.sin(radian)*branchLen;
    this.ctx.save();
    this.ctx.strokeStyle="rgba(37, 141, 194, 0.93)";
    this.ctx.beginPath();
    this.ctx.lineCap = "butt";
    this.ctx.lineJoin="round";
    this.ctx.lineWidth = branchWidth;
    this.ctx.moveTo(x,y);
    this.ctx.lineTo(toX,toY);
    this.ctx.closePath();
    this.ctx.stroke();
    this.ctx.restore();
    depth--;
    if(depth>0){
      this.drawBranch(toX,toY,branchLen,branchWidth-1,angle+30,depth);
      this.drawBranch(toX,toY,branchLen,branchWidth-1,angle-30,depth);
    }
}

运行代码:

由于树之间角度过大,而且所有树枝长度都相等,看起来并不像一棵树。所以我们需要在Tree的构造函数中加入几个参数用来调整树的姿态。

function Tree(x,y,branchLen,branchWidth,depth,canvas){
    ......
    this.branchLenFactor = 0.8;
    this.rootLenFactor = 1.2;
    this.branchAngle = 20;
    ......
}

branchLenFactor:画每一层树枝的时候乘在branchLen上面,用来控制树枝长度。rootLenFactor:画树根的时候乘在branchLen上面,用来控制树根长度。branchAngle: 用来控制树枝之间的角度。

Tree.prototype.drawRoot = function(x,y,branchLen,branchWidth,depth){
    var toX = x;
    var toY = y-branchLen*this.rootLenFactor;
    var depth = depth||5;
    this.ctx.save();
    this.ctx.strokeStyle="rgba(37, 141, 194, 0.93)";
    this.ctx.beginPath();
    this.ctx.lineCap = "butt";
    this.ctx.lineJoin="round";
    this.ctx.lineWidth = branchWidth;
    this.ctx.moveTo(x,y);
    this.ctx.lineTo(toX,toY);
    this.ctx.closePath();
    this.ctx.stroke();
    this.ctx.restore();
    depth--;
    if(depth>0){
      this.drawBranch(toX,toY,branchLen*this.branchLenFactor,branchWidth-1,this.branchAngle,depth);
      this.drawBranch(toX,toY,branchLen*this.branchLenFactor,branchWidth-1,-this.branchAngle,depth);
    }
  }
  Tree.prototype.drawBranch = function(x,y,branchLen,branchWidth,angle,depth){
    var angle = angle || 0;
    var radian = (90-angle)*(Math.PI/180);
    var toX = x+Math.cos(radian)*branchLen;
    var toY = y-Math.sin(radian)*branchLen;
    this.ctx.save();
    this.ctx.strokeStyle="rgba(37, 141, 194, 0.93)";
    this.ctx.beginPath();
    this.ctx.lineCap = "butt";
    this.ctx.lineJoin="round";
    this.ctx.lineWidth = branchWidth;
    this.ctx.moveTo(x,y);
    this.ctx.lineTo(toX,toY);
    this.ctx.closePath();
    this.ctx.stroke();
    this.ctx.restore();
    depth--;
    if(depth>0){
      this.drawBranch(toX,toY,branchLen*this.branchLenFactor,branchWidth-1,angle+this.branchAngle,depth);
      this.drawBranch(toX,toY,branchLen*this.branchLenFactor,branchWidth-1,angle-this.branchAngle,depth);
    }
  }

运行代码:

点击查看历史代码

Step5.使树枝晃动起来

为了使树枝有摇晃的效果,我们只需要改变树枝之间的角度branchAngle就可以了。我需要在Tree的构造函数中增加三个新属性:oBranchAngle用来记录初始角度;branchAngleFactor用来控制角度随时间变化的变化量;swingAngle:随时间增加用来记录摇动的角度。

同时修改下drawRoot函数使其不用接受参数。调用更加方便。

function Tree(x,y,branchLen,branchWidth,depth,canvas){
    ......
    this.branchAngle = 20;
    this.oBranchAngle = this.branchAngle;
    this.branchAngleFactor = 5;
    this.swingAngle = 0;
    ......
    this.drawRoot();
}

Tree.prototype.drawRoot = function(){
    var x = this.x,y=this.y,branchLen = this.branchLen,depth = this.depth,branchWidth = this.branchWidth;
    var toX = x;
    var toY = y-branchLen*this.rootLenFactor;
    var depth = depth||5;
    this.ctx.save();
    this.ctx.strokeStyle="rgba(37, 141, 194, 0.93)";
    this.ctx.beginPath();
    this.ctx.lineCap = "butt";
    this.ctx.lineJoin="round";
    this.ctx.lineWidth = this.branchWidth;
    this.ctx.moveTo(x,y);
    this.ctx.lineTo(toX,toY);
    this.ctx.closePath();
    this.ctx.stroke();
    this.ctx.restore();
    depth--;
    if(depth>0){
      this.drawBranch(toX,toY,branchLen*this.branchLenFactor,branchWidth-1,this.branchAngle,depth);
      this.drawBranch(toX,toY,branchLen*this.branchLenFactor,branchWidth-1,-this.branchAngle,depth);
    }
  }

增加循环函数,在循环函数中重绘整个树,并且每次重绘都要修改branchAngle值,使大树摇动起来。atree.swingAngle++;使摇动角度随时间变化。这里使用Math.sin(atree.swingAngle*(Math.PI/180))可以获得一个-1至1之间的连续变化值。atree.branchAngle = Math.sin(atree.swingAngle*(Math.PI/180))*atree.branchAngleFactor+atree.oBranchAngle;乘以系数并加在原角度上。

function loop(time){
    ctx.clearRect(0,0,canvas.width,canvas.height);
    atree.branchAngle = Math.sin(atree.swingAngle*(Math.PI/180))*atree.branchAngleFactor+atree.oBranchAngle;
    atree.drawRoot()
    requestAnimFrame(loop);
  }
  loop(0);

运行代码:

点击查看历史代码

Step6.添加手势

这里为了省事只添加了touch事件,mouse事件与touch事件的处理方法大体一致。

首先为Tree新加一个属性swingSwitch = true用来表示大树是否摆动。当手指触控到屏幕的时候摆动停止,离开屏幕的时候摆动继续。

添加strengthX,strengthY两个属性;分别表示树在x轴与y轴因受到的力而移动的距离。

添加strengthXFactor,strengthYFactor;分别用来表示再一次滑动中x轴与y轴移动的最大距离。

function Tree(x,y,branchLen,branchWidth,depth,canvas){
    ......
    this.swingSwitch = true;
    ......
    this.strengthX = 0;
    this.strengthY = 0;
    ......
  }
//记录触控开始时的信息
var touchStart = {x:0,y:0,strengthX:0,strengthY:0};
document.addEventListener('touchstart',function(e){
    //让树停止摆动
    atree.swingSwitch = false;
    touchStart.x = e.touches[0].clientX;
    touchStart.y = e.touches[0].clientY;
    //记录触控开始时,原strength的值
    touchStart.strengthX = atree.strengthX;
    touchStart.strengthY = atree.strengthY;
});
document.addEventListener('touchmove',function(e){
    //阻止浏览器默认动作
    e.preventDefault();
    //(touchStart.x-e.touches[0].clientX)/canvas.width可以根据滑动距离获得一个0-1的值
    atree.strengthX = touchStart.strengthX-(touchStart.x-e.touches[0].clientX)/canvas.width*atree.strengthXFactor;
    atree.strengthY = touchStart.strengthY-(touchStart.y-e.touches[0].clientY)/canvas.height*atree.strengthYFactor;
});
document.addEventListener('touchend',function(e){
    //恢复摆动
    atree.swingSwitch = true;
});

修改drawBranch将strength的变化添加到角度与toX,toY的计算中,详情见注释。

Tree.prototype.drawBranch = function(x,y,branchLen,branchWidth,angle,depth){

    var angle = angle || 0;
    //用strengthX乘以(depth/this.depth)使得树枝末梢对角度的变化不敏感
    angle += this.strengthX*(depth/this.depth)/this.strengthXFactor*this.branchAngle;
    var radian = (90-angle)*(Math.PI/180);
    //用strengthX乘以(1-depth/this.depth)使得树枝末梢对角度的变化敏感
    var toX = x+Math.cos(radian)*branchLen+this.strengthX*(1-depth/this.depth);
    var toY = y-Math.sin(radian)*branchLen+this.strengthY*(1-depth/this.depth);
    ......
}

在动画循环中添加恢复代码,使strengthX,strengthY恢复为0,并增加swingSwitch的判断。

function loop(time){
    ......
    //当swingSwitch开启时开始摆动
    if(atree.swingSwitch){
        //将strength恢复到0
      if(atree.strengthX >0){
        atree.strengthX -= 1;
      }
      if(atree.strengthX <0){
        atree.strengthX += 1;
      }
      if(atree.strengthY >0){
        atree.strengthY -= 1;
      }
      if(atree.strengthY <0){
        atree.strengthY += 1;
      }
      atree.swingAngle++;
      atree.branchAngle = Math.sin(atree.swingAngle*(Math.PI/180))*atree.branchAngleFactor+atree.oBranchAngle;
    }
    ......
}
loop(0);

运行代码:

点击查看历史代码

Step7.添加缓动效果

Step6中的恢复strengthX,strengthY的代码过于简单,动画匀速恢复到0,显得过于突兀。比较真实的情况应该是由快变慢的恢复,所以我们要为恢复代码加上缓动。首先在Tree中添加recoverStartTime = 0用来记录恢复开始的时间,在手指离开屏幕的时候(touchend)将其赋为0,同时用oStrengthX,oStrengthY记录下来strengthX与strengthY的目标值。

function Tree(x,y,branchLen,branchWidth,depth,canvas){
    ......
    this.recoverStartTime = 0;
    ......
}
function loop(time){
    ......
    if(atree.swingSwitch){
      if(atree.strengthX > 0){
        if(atree.recoverStartTime == 0){
          atree.recoverStartTime = time;
        }
        var t = time-atree.recoverStartTime;
        //五次方的缓动
        atree.strengthX =  Math.max(atree.oStrengthX-atree.oStrengthX*((t=t/2000-1)*t*t*t*t + 1)+0,0);
      }
      if(atree.strengthX < 0){
        if(atree.recoverStartTime == 0){
          atree.recoverStartTime = time;
        }
        var t = time-atree.recoverStartTime;
        //五次方的缓动
        atree.strengthX =  Math.min(atree.oStrengthX-atree.oStrengthX*((t=t/2000-1)*t*t*t*t + 1)+0,0);
      }
      if(atree.strengthY > 0){
        if(atree.recoverStartTime == 0){
          atree.recoverStartTime = time;
        }
        var t = time-atree.recoverStartTime;
        //五次方的缓动
        atree.strengthY =  Math.max(atree.oStrengthY-atree.oStrengthY*((t=t/2000-1)*t*t*t*t + 1)+0,0);
      }
      if(atree.strengthY < 0){
        if(atree.recoverStartTime == 0){
          atree.recoverStartTime = time;
        }
        var t = time-atree.recoverStartTime;
        //五次方的缓动
        atree.strengthY =  Math.min(atree.oStrengthY-atree.oStrengthY*((t=t/2000-1)*t*t*t*t + 1)+0,0);
      }
    }
    ......
}
document.addEventListener('touchend',function(e){
  atree.recoverStartTime = 0;
  atree.oStrengthX = atree.strengthX;
  atree.oStrengthY = atree.strengthY;
  ......
});

运行代码:

点击查看历史代码

Step7.使树干摇动并移至屏幕左边

修改drawRoot使树干也可以晃动,并修改var atree = new Tree(10,canvas.height,100,8,8,canvas);使其移至左边。

Tree.prototype.drawRoot = function(){
    ......
    //增加strength
    var angle = 0;
    angle += this.strengthX/this.strengthXFactor*this.branchAngle;
    var radian = (90-angle)*(Math.PI/180);
    var toX = x+Math.cos(radian)*branchLen*this.rootLenFactor;
    var toY = y-Math.sin(radian)*branchLen*this.rootLenFactor;
    ......
}
var atree = new Tree(10,canvas.height,100,8,8,canvas);

运行代码:

点击查看历史代码

Step8.

将动画循环中处理角度的部分添加到Tree的swing()中。

Tree.prototype.swing = function(time){
    this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);
    if(this.swingSwitch){
      if(this.strengthX > 0){
        if(this.recoverStartTime == 0){
          this.recoverStartTime = time;
        }
        var t = time-this.recoverStartTime;
        this.strengthX =  Math.max(this.oStrengthX-this.oStrengthX*((t=t/2000-1)*t*t*t*t + 1)+0,0);
      }
      if(this.strengthX < 0){
        if(this.recoverStartTime == 0){
          this.recoverStartTime = time;
        }
        var t = time-this.recoverStartTime;
        this.strengthX =  Math.min(this.oStrengthX-this.oStrengthX*((t=t/2000-1)*t*t*t*t + 1)+0,0);
      }
      if(this.strengthY > 0){
        if(this.recoverStartTime == 0){
          this.recoverStartTime = time;
        }
        var t = time-this.recoverStartTime;
        this.strengthY =  Math.max(this.oStrengthY-this.oStrengthY*((t=t/2000-1)*t*t*t*t + 1)+0,0);
      }
      if(this.strengthY < 0){
        if(this.recoverStartTime == 0){
          this.recoverStartTime = time;
        }
        var t = time-this.recoverStartTime;
        this.strengthY =  Math.min(this.oStrengthY-this.oStrengthY*((t=t/2000-1)*t*t*t*t + 1)+0,0);
      }
      this.swingAngle++;
      this.branchAngle = Math.sin(this.swingAngle*(Math.PI/180))*this.branchAngleFactor+this.oBranchAngle;
    }
    this.drawRoot();
}
var atree = new Tree(10,canvas.height,100,8,8,canvas);
function loop(time){
    atree.swing(time);
    requestAnimFrame(loop);
}
loop(0);

运行代码:

查看所有代码请去Github

如有问题或者建议请微博@UED天机。我会及时回复

用Canvas制作可以根据手势摆动的树,布布扣,bubuko.com

时间: 2024-10-14 12:03:40

用Canvas制作可以根据手势摆动的树的相关文章

如何使用 HTML5 Canvas 制作水波纹效果

原文:如何使用 HTML5 Canvas 制作水波纹效果 今天,我们继续分享 JavaScript 实现的效果例子,这篇文章会介绍使用 JavaScript 实现水波纹效果.水波效果以图片为背景,点击图片任意位置都会触发.有时候,我们使用普通的 Javascript 就可以创建一个很有趣的解决功能. 在线演示      源码下载 Step 1. HTML 和以前一样,首先是 HTML 代码: <!DOCTYPE html> <html> <head> <meta

用Canvas制作简单的画图工具

今天用Canvas制作了一个画图工具,非常简单,功能也不是很多,主要有背景网格,画线,画圆,画矩形和画圆角矩形,也用到了canvas的一些基本知识,在这里一一列举. 1.线段的绘制: 如何绘制真正的1像素的线段? 如果在像素边界处绘制一条1像素宽的垂直线段,那么canvas的绘图环境对象会试着将半个像素画在边界中线的右边,将另外半个像素画在边界中线的左边.然而,在一个整像素的范围内绘制半个像素宽的线段是不可能的,,所以左右两个方向上的半像素都被扩展为1像素.如图所示 本来我们想要将线段绘制在深灰

使用canvas制作在线画板

canvas绘图的强大功能,让人前仆后继的去研究它.代码全部加起来不足百行.还用到了h5中的<input type="color"/>和<input type="range"/> 使得页面更加简洁. 本文只用了鼠标的三个事件 onmousedown onmousemove onmouseup就轻松实现了网页画板的制作. 上代码: 1 <!DOCTYPE html> 2 <html> 3 <head lang=&q

利用canvas制作乱跑的小球

canvas制作乱跑的小球 说明:将下面的代码放到html的body就可以,键盘控制上(W)下(S)左(A)右(D) <body> <canvas id="canvas" style="border: 1px solid #000;display: block;margin:30px auto;"></canvas> <script type="text/javascript"> var myCan

酷!使用 jQuery &amp; Canvas 制作相机快门效果

在今天的教程中,我们将使用 HTML5 的 Canvas 元素来创建一个简单的摄影作品集,它显示了一组精选照片与相机快门的效果.此功能会以一个简单的 jQuery 插件形式使用,你可以很容易地整合到任何网站. 效果演示     插件下载 您可能感兴趣的相关文章 Web 开发中很实用的10个效果[源码下载] 精心挑选的优秀jQuery Ajax分页插件和教程 12个让人惊叹的的创意的 404 错误页面设计 让网站动起来!12款优秀的 jQuery 动画插件 十分惊艳的8个 HTML5 & Java

Vue+WebSocket+ES6+Canvas 制作「你画我猜」小游戏

Vue+WebSocket+ES6+Canvas 制作「你画我猜」小游戏 转载 来源:jrainlau 链接:https://segmentfault.com/a/1190000005804860 项目地址:https://github.com/jrainlau/draw-something 下载 & 运行 git clone [email protected]:jrainlau/draw-something.git cd draw-something && npm install

canvas制作简单钟表

之前用html+css+JavaScript实现了一个简单钟表,但还是有一些问题,主要是一些css属性不同浏览器支持效果不一样,所以尝试用 canvas实现了一个简单的钟表,效果在下方,当然了,采用canvas同样会有一些浏览器不支持... 这里只讨论canvas的实现方式.^_^ html部分 html部分很简单,写入canvas标签,其id设置为“canvas”,用css设置成居中显示,代码如下: 1 <!doctype html> 2 <html> 3 <head>

Html5用Canvas制作绘图板

需求: 绘制多边形 可填充颜色 可设置文字 可移动,可删除 鼠标按住后,抬起之前线段应该跟随鼠标当前位置 可与后台方便的进行数据交互,保存到后台,或将数据从后台取到前台显示相应的图形 思考: 第一想到的是找现成的改一改,找来找去,就觉得fabricjs还可以,不过研究了一下,发现例子太少,很难短时间内上手 想到了最近一直想研究确没时间看的Html5,正巧之前也买了一本关于Canvas游戏开发的书,想试试看,没想到很快就上手了 结果: 一天半时间完成,效果如下: 注意: 不要使用style或者cs

Canvas制作的下雨动画

简介 在codepen上看到一个Canvas做的下雨效果动画,感觉蛮有意思的.就研究了下,这里来分享下,实现技巧.效果可以见下面的链接. 霓虹雨: http://codepen.io/natewiley/full/NNgqVJ/ 效果截图: Canvas动画基础 大家都知道,Canvas其实只是一个画板.我们可以应用canvas的api在上面绘制各种图形.Canvas 2D 的API:https://developer.mozilla.org/en-US/docs/Web/API/CanvasR