今天看到一篇CSS3写的大风车http://www.cnblogs.com/yaojaa/archive/2013/01/30/2882521.html,感觉CSS3太神奇了,这在以前用CSS是想都不敢想的。记得去年自己用canvas也写过这样的大风车,今天我打算用canvas制作一个一模一样的,连速度都一致的大风车。

  大家请看下面两张图,你们看得出这两张图有什么区别吗?哪张是CSS3写的哪张是canvas写的?

  下面就来介绍制作风车的过程。先上代码吧:

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<canvas id = "canvas" width="300" height="300"></canvas> <script>
(function () {
var Pinwheel = function (canvas, options) {
this.canvas = document.getElementById(canvas);
this.options = options;
};
Pinwheel.prototype = {
constructor: Pinwheel,
show: function () {
var canvas = this.canvas,//取得canvas元素
width = canvas.width,//canvas元素的宽度
height = canvas.height,//canvas元素的高度
color = this.options.color,//风车叶子的颜色
radius = this.options.radius,//整个风车的半径
wheelRadius = this.options.wheelRadius,//风车叶子的半径
part = this.options.part,//PI/2分成几份
ctx = canvas.getContext("2d"),//获取上下文
num = this.options.num,//叶子数量
center = {x: width / 2, y: height / 2},//绘图区域的中心
point, //叶子圆心位置
start = 0,//绘制叶子的开始角
angle = 0,//start = angle
end = Math.PI,//绘制叶子的结束角
offset = Math.PI * (360 / num) / 180,//两个相邻叶子之间的角度
rotateAngle = offset / part;//每次旋转的角度
// window.timer = setInterval(function () {
ctx.clearRect(0, 0, width, height);
for (var i = 0; i < num; i += 1) {
ctx.beginPath();//开始绘制叶子
var wheelGradient = ctx.createRadialGradient(center.x, center.y, 100, center.x, center.y, 0);//创建径向渐变
wheelGradient.addColorStop(0, color[i]);//起始颜色
wheelGradient.addColorStop(1, "#000");//结束颜色
ctx.fillStyle = wheelGradient;//填充渐变样式
point = {x: center.x + Math.cos(offset * i + angle) * radius, y: center.y + Math.sin(offset * i + angle) * radius};//叶子圆心位置
var x = start + offset * i;//绘制叶子的开始角
var y = end + offset * i;//绘制叶子的结束角
ctx.arc(point.x, point.y, wheelRadius, x, y, false);//绘制
ctx.fill();//填充
ctx.closePath();//结束绘制
}
ctx.beginPath();
var dotGradient = ctx.createRadialGradient(center.x, center.y, 0, center.x, center.y, 40);
dotGradient.addColorStop(0, "#fff");
dotGradient.addColorStop(1, "#666");
ctx.fillStyle = dotGradient;
ctx.arc(center.x, center.y, 25, 0, 2 * Math.PI, false);
ctx.fill();
ctx.closePath();
angle += rotateAngle;
start = angle;
end = Math.PI + angle;
// }, 20)
},
hide: function () {
clearInterval(window.timer);
}
}; var options = {
num: 4,
color: ["red", "yellow", "blue", "green"],
radius: 50,
wheelRadius: 50,
part: 50
}; var a = new Pinwheel("canvas", options);
a.show();
}());
</script>
</body>
</html>

首先,确定需要的各项参数:

var canvas = this.canvas,//取得canvas元素
width = canvas.width,//canvas元素的宽度
height = canvas.height,//canvas元素的高度
color = this.options.color,//风车叶子的颜色
radius = this.options.radius,//整个风车的半径
wheelRadius = this.options.wheelRadius,//风车叶子的半径
part = this.options.part,//PI/2分成几份
ctx = canvas.getContext("2d"),//获取上下文
num = this.options.num,//叶子数量
center = {x: width / 2, y: height / 2},//绘图区域的中心
point, //叶子圆心位置
start = 0,//绘制叶子的开始角
angle = 0,//start = angle
end = Math.PI,//绘制叶子的结束角
offset = Math.PI * (360 / num) / 180,//两个相邻叶子之间的角度
rotateAngle = offset / part;//每次旋转的角度

循环绘制每个叶子:

for (var i = 0; i < num; i += 1) {
  ctx.beginPath();//开始绘制叶子
  var wheelGradient = ctx.createRadialGradient(center.x, center.y, 100, center.x, center.y, 0);//创建径向渐变
  wheelGradient.addColorStop(0, color[i]);//起始颜色
  wheelGradient.addColorStop(1, "#000");//结束颜色
  ctx.fillStyle = wheelGradient;//填充渐变样式
  point = {x: center.x + Math.cos(offset * i + angle) * radius, y: center.y + Math.sin(offset * i + angle) * radius};//叶子圆心位置
  var x = start + offset * i;//绘制叶子的开始角
  var y = end + offset * i;//绘制叶子的结束角
  ctx.arc(point.x, point.y, wheelRadius, x, y, false);//绘制
  ctx.fill();//填充
  ctx.closePath();//结束绘制
}

绘制中间的大圆点:

ctx.beginPath();
var dotGradient = ctx.createRadialGradient(center.x, center.y, 0, center.x, center.y, 40);
dotGradient.addColorStop(0, "#fff");
dotGradient.addColorStop(1, "#666");
ctx.fillStyle = dotGradient;
ctx.arc(center.x, center.y, 25, 0, 2 * Math.PI, false);
ctx.fill();
ctx.closePath();

  上面的代码已经可以制作静态的风车了,但是我们要做的是动态的,于是我们需要一个计时器。下面是计时器代码:

  window.timer = setInterval(function () {
    ctx.clearRect(0, 0, width, height);//每次调用计时器需要重绘
    for (var i = 0; i < num; i += 1) {
      ctx.beginPath();//开始绘制叶子
      var wheelGradient = ctx.createRadialGradient(center.x, center.y, 100, center.x, center.y, 0);//创建径向渐变
      wheelGradient.addColorStop(0, color[i]);//起始颜色
      wheelGradient.addColorStop(1, "#000");//结束颜色
      ctx.fillStyle = wheelGradient;//填充渐变样式
      point = {x: center.x + Math.cos(offset * i + angle) * radius, y: center.y + Math.sin(offset * i + angle) * radius};//叶子圆心位置
      var x = start + offset * i;//绘制叶子的开始角
      var y = end + offset * i;//绘制叶子的结束角
      ctx.arc(point.x, point.y, wheelRadius, x, y, false);//绘制
      ctx.fill();//填充
      ctx.closePath();//结束绘制
    }
    ctx.beginPath();
    var dotGradient = ctx.createRadialGradient(center.x, center.y, 0, center.x, center.y, 40);
    dotGradient.addColorStop(0, "#fff");
    dotGradient.addColorStop(1, "#666");
    ctx.fillStyle = dotGradient;
    ctx.arc(center.x, center.y, 25, 0, 2 * Math.PI, false);
    ctx.fill();
    ctx.closePath();
    angle += rotateAngle;
    start = angle;
    end = Math.PI + angle;
  }, 20)

  动态的风车基本上就做完了,这是运行大风车代码:

var options = {
  num: 4,
  color: ["red", "yellow", "blue", "green"],
  radius: 50,
  wheelRadius: 50,
  part: 50
  };
var a = new Pinwheel("canvas", options);
a.show();

修改options对象的属性就会改变风车的状态。  

  需要停止风车运转调用这个函数:

hide: function () {
  clearInterval(window.timer);
}

  下面是展示结果的时候了:

  以前写这些代码是没有注释的,今天花了好大功夫加上注释,然后在原有基础上做了一些修改,做成了和CSS3写的一模一样的风车。

HTML5 canvas制作童年的回忆大风车的更多相关文章

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

    今天,我们继续分享 JavaScript 实现的效果例子,这篇文章会介绍使用 JavaScript 实现水波纹效果.水波效果以图片为背景,点击图片任意位置都会触发.有时候,我们使用普通的 Javasc ...

  2. 怎样用HTML5 Canvas制作一个简单的游戏

    原文连接: How To Make A Simple HTML5 Canvas Game 自从我制作了一些HTML5游戏(例如Crypt Run)后,我收到了很多建议,要求我写一篇关于怎样利用HTML ...

  3. [译]怎样用HTML5 Canvas制作一个简单的游戏

    这是我翻译自LostDecadeGames主页的一篇文章,原文地址:How To Make A Simple HTML5 Canvas Game. 下面是正文: 自从我制作了一些HTML5游戏(例如C ...

  4. HTML5 Canvas制作雷达图实战

    雷达图又叫蜘蛛网图,是一种对各项数据查看很明显的表现图,在很多游戏中,对游戏中的每个角色的分析图一般也用这种图. 下面,用HTML5的Cavas来实现雷达图. 效果 一.创建Canvas var mW ...

  5. 使用 HTML5 canvas制作拾色器

    自制的拾色器漂亮吧,哈哈 废话不多说直接上代码,希望可以帮到需要的朋友 <html><head>    <style>        .canvas_color{p ...

  6. 赠书:HTML5 Canvas 2d 编程必读的两本经典

    赠书:HTML5 Canvas 2d 编程必读的两本经典 这两年多一直在和HTML5 Canvas 打交道,也带领团队开发了世界首款基于HTML5 Canvas 的演示文档工具---AxeSlide( ...

  7. HTML5 Canvas彩色小球碰撞运动特效

    脚本简介 HTML5 Canvas彩色小球碰撞运动特效是一款基于canvas加面向对象制作的运动小球动画特效.   效果展示 http://hovertree.com/texiao/html5/39/ ...

  8. 酷!使用 jQuery & Canvas 制作相机快门效果

    在今天的教程中,我们将使用 HTML5 的 Canvas 元素来创建一个简单的摄影作品集,它显示了一组精选照片与相机快门的效果.此功能会以一个简单的 jQuery 插件形式使用,你可以很容易地整合到任 ...

  9. 7 个顶级的 HTML5 Canvas 动画赏析

    HTML5确实是一项改革浏览器乃至整个软件行业的新技术,它可以帮助我们Web开发者很方便地在网页上实现动画特效,而无需臃肿的Flash作为支撑.本文分享7个顶级的HTML5 Canvas 动画,都有非 ...

随机推荐

  1. POJ 2208--Pyramids(欧拉四面体体积计算)

    Pyramids Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3451   Accepted: 1123   Specia ...

  2. JavaScript 中 this 的原理

    一.问题 学习 JavaScript 其中一个标志就是理解下面两种写法,会输出有不一样的结果. var obj = { foo: function () {} }; var foo = obj.foo ...

  3. jquery输入框动态查询l<li></li>列表

    1.html代码如下: 2.js代码如下: $('#search').bind('input propertychange', function () { searchKpoint(); }); fu ...

  4. Android 微信页面刷新问题

    今天测试妹纸提了个bug,Android手机用微信打开测试页面,刷新功能无效.因为开发时懒,只验证了Ios手机无异常,没有注意打安卓这个问题. 我是直接用的window.location.reload ...

  5. python和java,php,c,c#,c++的对比

    1.C语言,它既有高级语言的特点,又具有汇编语言的特点,它是结构式语言.C语言应用指针:可以直接进行靠近硬件的操作,但是C的指针操作不做保护,也给它带来了很多不安全的因素.C++在这方面做了改进,在保 ...

  6. kafka初步学习

    消息系统 什么是消息系统? 消息系统负责将数据从一个应用程序传输到另一个应用程序,因此应用程序可以专注于数据,但不担心如何共享它.分布式消息传递给予可靠消息队列的概念.消息在客户端应用程序和消息传递系 ...

  7. QOS-配置拥塞避免机制

    QOS-配置拥塞避免机制 2018年7月7日 20:29 尾丢弃及其导致的问题: 队列满时路由器进行尾丢弃,即新到的所有数据包都全部丢弃 丢弃的结果造成高延迟.高抖动.丧失服务保证.TCP全局同步.T ...

  8. vue-router核心概念

    vue用来实现SPA的插件 使用vue-router 1. 创建路由器: router/index.js new VueRouter({ routes: [ { // 一般路由 path: '/abo ...

  9. Zookeeper原理和实战开发经典视频教程 百度云网盘下载

    Zookeeper原理和实战开发 经典视频教程 百度云网盘下载 资源下载地址:http://pan.baidu.com/s/1o7ZjPeM   密码:r5yf   

  10. 南京Uber优步司机奖励政策(1月4日~1月10日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...