这次我们的目标是画一个会和时间同步的时钟,不过没有美学感觉,样子丑的厉害。

HTML5支持canvas了,我们可以直接在页面上绘图了,我看了下canvas和GDI+的接口差不多,所以我们先了解些基本的概念和方式,然后来做一个应用吧。

我们做所有的画之情需要一个画布,html的canvas标签就是帮我们声明了一个画布。

  1. [javascript] view plaincopy
  2. <canvas id="mycanvas">
  3. </canvas>

这个默认的画布的大小是300*150,接下来的工作大多就是javaScript来做了。
首先要实例化这个画布

  1. [javascript] view plaincopy
  2. $(
  3. function() {
  4. var canvas = document.getElementById("mycanvas");
  5. $.log(canvas.width);
  6. $.log(canvas.height);
  7. var context = canvas.getContext("2d");
  8. $.log(context.canvas);
  9. $.log(context.fillStyle); //要填充的区域的颜色
  10. $.log(context.strokeStyle); //要绘制的线条的颜色
  11. $.log(context.lineCap); //笔帽样式
  12. $.log(context.lineJoin); //两条连续线段的连接样式
  13. $.log(context.lineWidth); //线段的宽度
  14. $.log(context.miterLimit); //斜联接
  15. $.log(context.shadowColor); //阴影的颜色,默认为#000000,
  16. $.log(context.shadowOffsetX); //阴影在x方向上的偏移量,默认为0,不受坐标转换的影响。
  17. $.log(context.shadowOffsetY); //阴影在y方向上的偏移量,默认为0,不受坐标转换的影响。
  18. $.log(context.shadowBlur); //阴影的模糊度,默认为0,负数值将会被忽略
  19. }
  20. );

上面的结果你可以得到一个大致的想法,就是content可以认为是我们将来作画用的画笔(估计有专业人士对强烈抗议,我直接忽略),canvas就是我们的画布。我们现在的画笔是2D的画笔,换句话说就是画平面几何的画笔。
接下来,就是我们利用这个画笔来学习怎么画了

各种线

  1. [javascript] view plaincopy
  2. $(
  3. function() {
  4. var canvas = document.getElementById("mycanvas");
  5. var context = canvas.getContext("2d");
  6. context.strokeStyle = "rgb(255, 0, 0)";
  7. context.beginPath();
  8. context.lineCap = "butt"; //默认
  9. context.lineWidth = 10;
  10. context.moveTo(10, 10);
  11. context.lineTo(100, 10); //简单的一条线
  12. context.stroke(); //该方法真正在画布上绘制该线段
  13. context.beginPath();
  14. context.lineCap = "round"; //圆形线头
  15. context.moveTo(10, 30);
  16. context.lineTo(100, 30);
  17. context.stroke(); //该方法真正在画布上绘制该线段
  18. context.beginPath();
  19. context.lineCap = "square"; //方形线头
  20. context.moveTo(10, 50);
  21. context.lineTo(100, 50);
  22. context.stroke(); //该方法真正在画布上绘制该线段
  23. }
  24. );
  25. 各种阴影
  26. [javascript] view plaincopy
  27. $(
  28. function() {
  29. var canvas = document.getElementById("mycanvas");
  30. var context = canvas.getContext("2d");
  31. context.strokeStyle = "rgb(255, 0, 0)";
  32. context.lineWidth = 10;
  33. context.shadowColor = "#0000FF";
  34. context.beginPath();
  35. context.lineCap = "round";
  36. context.moveTo(10, 10);
  37. context.lineTo(100, 10);
  38. context.shadowOffsetX = 10;
  39. context.shadowBlur = 10;
  40. context.stroke();
  41. context.beginPath();
  42. context.lineCap = "round";
  43. context.moveTo(10, 30);
  44. context.lineTo(100, 30);
  45. context.shadowOffsetY = 10;
  46. context.shadowBlur = 10;
  47. context.stroke();
  48. }
  49. );
  50. 各种线∠连接
  51. [javascript] view plaincopy
  52. $(
  53. function() {
  54. var canvas = document.getElementById("mycanvas");
  55. var context = canvas.getContext("2d");
  56. context.strokeStyle = "rgb(255, 0, 0)";
  57. context.lineWidth = 10;
  58. context.shadowColor = "#0000FF";
  59. context.beginPath();
  60. context.lineJoin = "miter"; //两条线段的外边缘一直扩展到它们相交
  61. context.moveTo(10, 70);
  62. context.lineTo(50, 10);
  63. context.lineTo(80, 70);
  64. context.stroke();
  65. context.lineJoin = "bevel"; //以一个斜边进行连接
  66. context.moveTo(100, 70);
  67. context.lineTo(140, 10);
  68. context.lineTo(180, 70);
  69. context.stroke();
  70. context.lineJoin = "round"; //:以一个圆弧边进行连接
  71. context.beginPath();
  72. context.moveTo(200, 70);
  73. context.lineTo(240, 10);
  74. context.lineTo(280, 70);
  75. context.stroke();
  76. context.closePath(); //关闭path
  77. }
  78. );
  79. mitre的限定
  80. [javascript] view plaincopy
  81. $(
  82. function() {
  83. var canvas = document.getElementById("mycanvas");
  84. var context = canvas.getContext("2d");
  85. context.strokeStyle = "rgb(255, 0, 0)";
  86. context.lineWidth = 10;
  87. context.shadowColor = "#0000FF";
  88. context.beginPath();
  89. context.miterLimit = 1; //miterLimit 属性为斜面的长度设置一个上限。
  90. //只对线条使用设置为 "miter" 的 lineJoin 属性绘制并且两条线段以锐角相交的时候有效
  91. context.lineJoin = "miter"; //两条线段的外边缘一直扩展到它们相交
  92. context.moveTo(10, 70);
  93. context.lineTo(50, 10);
  94. context.lineTo(80, 70);
  95. context.stroke();
  96. }
  97. );
  98. 各种几何图形
  99. [javascript] view plaincopy
  100. $(
  101. function() {
  102. var canvas = document.getElementById("mycanvas");
  103. canvas.height = 500; //改变默认高度
  104. canvas.width = 500;
  105. var context = canvas.getContext("2d");
  106. context.strokeStyle = "rgb(255, 0, 0)";
  107. context.fillStyle = "#AABBCC";
  108. context.lineWidth = 2;
  109. context.shadowColor = "#0000FF";
  110. //矩形
  111. context.beginPath();
  112. context.fillRect(10, 10, 50, 50); //实体矩形:x,y,width,height
  113. context.strokeRect(70, 10, 50, 50)//空心矩形:x,y,width,height
  114. //context.move(10,100);
  115. //圆弧:x, y, radius, startAngle, endAngle, anticlockwise
  116. context.beginPath();
  117. context.arc(35, 110, 25, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false);
  118. context.stroke();
  119. //context.closePath();
  120. context.beginPath();
  121. context.arc(85, 110, 25, (Math.PI / 180) * 0, (Math.PI / 180) * 180, false);
  122. context.stroke();
  123. //context.closePath();
  124. context.beginPath();
  125. context.arc(135, 110, 25, (Math.PI / 180) * 0, (Math.PI / 180) * 180, true);
  126. context.stroke();
  127. //context.closePath();
  128. context.beginPath();
  129. context.arc(185, 110, 25, (Math.PI / 180) * 180, (Math.PI / 180) * 360, true);
  130. context.stroke();
  131. //context.closePath();
  132. context.beginPath();
  133. context.arc(235, 110, 25, (Math.PI / 180) * 90, (Math.PI / 180) * 0, false);
  134. context.fillStyle = "blue";
  135. context.fill();
  136. //context.stroke();
  137. //context.closePath();
  138. context.beginPath();
  139. context.arc(285, 110, 25, (Math.PI / 180) * 180, (Math.PI / 180) * 45, false);
  140. context.closePath();
  141. context.stroke();
  142. context.beginPath();
  143. context.arc(335, 110, 25, (Math.PI / 180) * 180, (Math.PI / 180) * 45, false);
  144. context.closePath();
  145. context.fillStyle = "blue";
  146. context.fill();
  147. context.stroke();
  148. //曲线
  149. context.beginPath();
  150. context.moveTo(10, 160); //二次贝塞尔曲线的起始点
  151. //controlX, controlY, endX, endY
  152. context.quadraticCurveTo(70, 280, 235, 140);
  153. context.stroke();
  154. context.closePath();
  155. context.beginPath();
  156. context.moveTo(10, 300); //三次贝塞尔曲线的起始点
  157. //controlX1, controlY1, controlX2, controlY2, endX, endY
  158. context.bezierCurveTo(70, 280, 50, 400, 235, 190);
  159. context.stroke();
  160. context.closePath();
  161. }
  162. );
  163. 各种变换
  164. 记得CSS3中的transform不?canvas肯定也有啊
  165. 平移
  166. [javascript] view plaincopy
  167. $(
  168. function() {
  169. var canvas = document.getElementById("mycanvas");
  170. canvas.height = 500; //改变默认高度
  171. canvas.width = 500;
  172. var context = canvas.getContext("2d");
  173. context.strokeStyle = "rgb(255, 0, 0)";
  174. context.fillStyle = "#AABBCC";
  175. context.lineWidth = 2;
  176. context.shadowColor = "#0000FF";
  177. context.moveTo(10, 10);
  178. //context.beginPath();
  179. //context.beginPath();
  180. context.fillRect(10, 10, 50, 50); //实体矩形:x,y,width,height
  181. //context.stroke();
  182. $(canvas).on(
  183. "click",
  184. { "context": context },
  185. function(e) {
  186. $.log(e.data.context);
  187. var ctx = e.data.context;
  188. ctx.translate(10, 10); //再最后的路径点上偏移10*10的位置
  189. context.fillRect(10, 10, 50, 50);
  190. context.stroke();
  191. }
  192. );
  193. }
  194. );
  195. 缩放
  196. [javascript] view plaincopy
  197. $(
  198. function() {
  199. var canvas = document.getElementById("mycanvas");
  200. canvas.height = 500; //改变默认高度
  201. canvas.width = 500;
  202. var context = canvas.getContext("2d");
  203. context.strokeStyle = "rgb(255, 0, 0)";
  204. context.fillStyle = "#AABBCC";
  205. context.lineWidth = 2;
  206. context.shadowColor = "#0000FF";
  207. context.moveTo(10, 10);
  208. //context.beginPath();
  209. //context.beginPath();
  210. context.fillRect(10, 10, 50, 50); //实体矩形:x,y,width,height
  211. //context.stroke();
  212. $(canvas).on(
  213. "click",
  214. { "context": context },
  215. function(e) {
  216. $.log(e.data.context);
  217. var ctx = e.data.context;
  218. ctx.scale(1.1, 1.1); //在最后的大小基础上缩放倍数 必须是正数
  219. context.fillRect(10, 10, 50, 50);
  220. context.stroke();
  221. }
  222. );
  223. }
  224. );
  225. 旋转
  226. [javascript] view plaincopy
  227. $(
  228. function() {
  229. var canvas = document.getElementById("mycanvas");
  230. canvas.height = 500; //改变默认高度
  231. canvas.width = 500;
  232. var context = canvas.getContext("2d");
  233. context.strokeStyle = "rgb(255, 0, 0)";
  234. context.fillStyle = "#AABBCC";
  235. context.lineWidth = 2;
  236. context.shadowColor = "#0000FF";
  237. context.moveTo(10, 10);
  238. //context.beginPath();
  239. //context.beginPath();
  240. context.fillRect(10, 10, 50, 50); //实体矩形:x,y,width,height
  241. //context.stroke();
  242. $(canvas).on(
  243. "click",
  244. { "context": context },
  245. function(e) {
  246. $.log(e.data.context);
  247. var ctx = e.data.context;
  248. ctx.rotate((Math.PI / 180) * 10); //旋转的角度,旋转的中心是canvas坐标原点
  249. context.fillRect(10, 10, 50, 50);
  250. context.stroke();
  251. }
  252. );
  253. }
  254. );

transform,transform的参数比较多,也比较难理解,简单的说transform是最自由的变形方式,下面给出些参考

  1. [javascript] view plaincopy
  2. //以下两段代码结果一致
  3. context.transform(1, 0, 0, 1, 10, 10)
  4. context.translate(10, 10);
  5. //以下两段代码结果一致
  6. context.transform(10, 0, 0, 10, 0, 0);
  7. context.scale(10, 10);
  8. //以下三段代码结果一致
  9. context.transform(Math.cos((Math.PI / 180) * 10), Math.sin((Math.PI / 180) * 10), -Math.sin((Math.PI / 180) * 10), Math.cos((Math.PI / 180)) * 10, 0, 0);
  10. context.transform(-Math.sin((Math.PI/180)*10),Math.cos((Math.PI/180)*10),Math.cos((Math.PI/180)*10),Math.sin((Math.PI/180)*10), 0,0);
  11. context.rotate(10);

组合

  1. [javascript] view plaincopy
  2. $(
  3. function() {
  4. var canvas = document.getElementById("mycanvas");
  5. canvas.height = 100;
  6. canvas.width = 100;
  7. var context = canvas.getContext("2d");
  8. context.fillStyle = "#AABBCC";
  9. context.fillRect(10, 10, 50, 50);
  10. //默认 新图形会覆盖在原有内容之上
  11. context.globalCompositeOperation = "source-over";
  12. context.fillStyle = "blue";
  13. context.arc(70, 30, 25, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false);
  14. context.fill();
  15. $("span").html(context.globalCompositeOperation);
  16. $(canvas).toggle(
  17. function() {
  18. canvas.width = 100;
  19. // 原有内容之下绘制新图形
  20. context.clearRect(0, 0, 500, 500);
  21. context.beginPath();
  22. context = canvas.getContext("2d");
  23. context.fillStyle = "#AABBCC";
  24. context.fillRect(10, 10, 50, 50);
  25. context.globalCompositeOperation = "destination-over";
  26. context.fillStyle = "blue";
  27. context.arc(70, 30, 25, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false);
  28. context.fill();
  29. $("span").html(context.globalCompositeOperation);
  30. },
  31. function() {
  32. canvas.width = 100;
  33. //新图形会仅仅出现与原有内容重叠的部分。其它区域都变成透明的
  34. context.clearRect(0, 0, 500, 500);
  35. context.beginPath();
  36. context.fillStyle = "#AABBCC";
  37. context.fillRect(10, 10, 50, 50);
  38. context.globalCompositeOperation = "source-in";
  39. context.fillStyle = "blue";
  40. context.arc(70, 30, 25, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false);
  41. context.fill();
  42. $("span").html(context.globalCompositeOperation);
  43. },
  44. function() {
  45. canvas.width = 100;
  46. //原有内容中与新图形重叠的部分会被保留,其它区域都变成透明的destination-in
  47. context.clearRect(0, 0, 500, 500);
  48. context.beginPath();
  49. context = canvas.getContext("2d");
  50. context.fillStyle = "#AABBCC";
  51. context.fillRect(10, 10, 50, 50);
  52. context.globalCompositeOperation = "destination-in";
  53. context.fillStyle = "blue";
  54. context.arc(70, 30, 25, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false);
  55. context.fill();
  56. $("span").html(context.globalCompositeOperation);
  57. },
  58. function() {
  59. canvas.width = 100;
  60. //只有新图形中与原有内容不重叠的部分会被绘制出来source-out
  61. context.clearRect(0, 0, 500, 500);
  62. context.beginPath();
  63. context = canvas.getContext("2d");
  64. context.fillStyle = "#AABBCC";
  65. context.fillRect(10, 10, 50, 50);
  66. context.globalCompositeOperation = "source-out";
  67. context.fillStyle = "blue";
  68. context.arc(70, 30, 25, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false);
  69. context.fill();
  70. $("span").html(context.globalCompositeOperation);
  71. },
  72. function() {
  73. canvas.width = 100;
  74. //原有内容中与新图形不重叠的部分会被保留
  75. context.clearRect(0, 0, 500, 500);
  76. context.beginPath();
  77. context = canvas.getContext("2d");
  78. context.fillStyle = "#AABBCC";
  79. context.fillRect(10, 10, 50, 50);
  80. context.globalCompositeOperation = "destination-out";
  81. context.fillStyle = "blue";
  82. context.arc(70, 30, 25, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false);
  83. context.fill();
  84. $("span").html(context.globalCompositeOperation);
  85. },
  86. function() {
  87. canvas.width = 100;
  88. //新图形中与原有内容重叠的部分会被绘制,并覆盖于原有内容之上
  89. context.clearRect(0, 0, 500, 500);
  90. context.beginPath();
  91. context = canvas.getContext("2d");
  92. context.fillStyle = "#AABBCC";
  93. context.fillRect(10, 10, 50, 50);
  94. context.globalCompositeOperation = "source-atop";
  95. context.fillStyle = "blue";
  96. context.arc(70, 30, 25, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false);
  97. context.fill();
  98. $("span").html(context.globalCompositeOperation);
  99. },
  100. function() {
  101. canvas.width = 100;
  102. //原有内容中与新内容重叠的部分会被保留,并会在原有内容之下绘制新图形
  103. context.clearRect(0, 0, 500, 500);
  104. context.beginPath();
  105. context = canvas.getContext("2d");
  106. context.fillStyle = "#AABBCC";
  107. context.fillRect(10, 10, 50, 50);
  108. context.globalCompositeOperation = "destination-atop";
  109. context.fillStyle = "blue";
  110. context.arc(70, 30, 25, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false);
  111. context.fill();
  112. $("span").html(context.globalCompositeOperation);
  113. },
  114. function() {
  115. canvas.width = 100;
  116. //两图形中重叠部分作加色处理
  117. context.clearRect(0, 0, 500, 500);
  118. context.beginPath();
  119. context = canvas.getContext("2d");
  120. context.fillStyle = "#AABBCC";
  121. context.fillRect(10, 10, 50, 50);
  122. context.globalCompositeOperation = "lighter";
  123. context.fillStyle = "blue";
  124. context.arc(70, 30, 25, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false);
  125. context.fill();
  126. $("span").html(context.globalCompositeOperation);
  127. },
  128. function() {
  129. canvas.width = 100;
  130. //两图形中重叠的部分作减色处理darker
  131. context.clearRect(0, 0, 500, 500);
  132. context.beginPath();
  133. context = canvas.getContext("2d");
  134. context.fillStyle = "#AABBCC";
  135. context.fillRect(10, 10, 50, 50);
  136. context.globalCompositeOperation = "darker";
  137. context.fillStyle = "blue";
  138. context.arc(70, 30, 25, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false);
  139. context.fill();
  140. $("span").html(context.globalCompositeOperation);
  141. },
  142. function() {
  143. canvas.width = 100;
  144. //重叠的部分会变成透明
  145. context.clearRect(0, 0, 500, 500);
  146. context.beginPath();
  147. context = canvas.getContext("2d");
  148. context.fillStyle = "#AABBCC";
  149. context.fillRect(10, 10, 50, 50);
  150. context.globalCompositeOperation = "xor";
  151. context.fillStyle = "blue";
  152. context.arc(70, 30, 25, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false);
  153. context.fill();
  154. $("span").html(context.globalCompositeOperation);
  155. },
  156. function() {
  157. canvas.width = 100;
  158. //只有新图形会被保留,其它都被清除掉
  159. context.clearRect(0, 0, 500, 500);
  160. context.beginPath();
  161. context = canvas.getContext("2d");
  162. context.fillStyle = "#AABBCC";
  163. context.fillRect(10, 10, 50, 50);
  164. context.globalCompositeOperation = "copy";
  165. context.fillStyle = "blue";
  166. context.arc(70, 30, 25, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false);
  167. context.fill();
  168. $("span").html(context.globalCompositeOperation);
  169. alert("演示结束");
  170. }
  171. );
  172. }
  173. );
  174. 字体(看文档说canvas的字体支持CSS样式的描写,但是,我不知道怎么样让canvas的font支持CSS3的在线字体)
  175. [javascript] view plaincopy
  176. <script src="js/jquery-1.7.1.min.js" type="text/javascript"></script>
  177. <link rel="stylesheet" type="text/css" href="http://fonts.googleapis.com/css?family=Tangerine">
  178. <script type="text/javascript">
  179. $.log = function(msg) {
  180. console.log(msg);
  181. }
  182. $(
  183. function() {
  184. var canvas = document.getElementById("mycanvas");
  185. canvas.height = 200;
  186. canvas.width = 200;
  187. var context = canvas.getContext("2d");
  188. context.font = "20px 新宋体";
  189. context.fillText("这是实心新宋体", 10, 30);
  190. context.strokeText("这是空心新宋体", 10, 60);
  191. context.font = "20px Tangerine serif";
  192. context.fillText("Hello HTML5", 10, 100);
  193. context.strokeText("Hello HTML5", 10, 150);
  194. }
  195. );
  196. </script>

我们尝试写一圈旋转的文字,吧上面的知识点合起来看看效果

  1. [javascript] view plaincopy
  2. $(
  3. function() {
  4. var canvas = document.getElementById("mycanvas");
  5. canvas.height = 500;
  6. canvas.width = 500;
  7. var context = canvas.getContext("2d");
  8. context.translate(150, 150);
  9. context.scale(0.7, 0.7);
  10. context.font = "12px Tahoma";
  11. for (var i = 0; i < 12; i++) {
  12. context.fillText((i + 3) % 12 == 0 ? 12 : (i + 3) % 12, 150, 10);
  13. context.rotate((Math.PI / 6));
  14. }
  15. }
  16. );

在具体绘制的时候,定位总是让我这样没有空间感的人感觉痛苦,所以我现在canvas上画上很多格子,帮助我进行布局

  1. [javascript] view plaincopy
  2. $(
  3. function() {
  4. var canvas = document.getElementById("mycanvas");
  5. canvas.height = 500;
  6. canvas.width = 500;
  7. var context = canvas.getContext("2d");
  8. context.lineWidth = 1;
  9. context.strokeStyle = "rgb(211,211,211)";
  10. for (var i = 0; i < 50; i++) {
  11. $.log(i);
  12. context.moveTo(i * 10, 0);
  13. context.lineTo(i * 10, 500);
  14. context.stroke();
  15. }
  16. for (var i = 0; i < 50; i++) {
  17. $.log(i);
  18. context.moveTo(0, i * 10);
  19. context.lineTo(500, i * 10);
  20. context.stroke();
  21. }
  22. }
  23. );

前面的准备工作都完成了,现在我们来综合下,完成一个具有时分秒的会动的钟

  1. $(
  2. function() {
  3. clock();
  4. setInterval(clock, 1000);
  5. }
  6. );
  7. function clock() {
  8. var canvas = document.getElementById("mycanvas");
  9. canvas.height = 500;
  10. canvas.width = 500;
  11. var context = canvas.getContext("2d");
  12. context.beginPath();
  13. context.lineWidth = 1;
  14. context.strokeStyle = "rgb(211,211,211)";
  15. for (var i = 0; i < 50; i++) {
  16. $.log(i);
  17. context.moveTo(i * 10, 0);
  18. context.lineTo(i * 10, 500);
  19. context.stroke();
  20. }
  21. for (var i = 0; i < 50; i++) {
  22. $.log(i);
  23. context.moveTo(0, i * 10);
  24. context.lineTo(500, i * 10);
  25. context.stroke();
  26. }
  27. context.beginPath();
  28. context.strokeStyle = "rgb(255,0,0)";
  29. context.arc(250, 250, 200, (Math.PI / 180) * 0, (Math.PI / 180) * 360, false);
  30. context.stroke();
  31. context.save(); //存储当前画布坐标系状态
  32. context.beginPath();
  33. context.font = "14px Tahoma"
  34. context.translate(255, 255); //将坐标系坐标原点移至图中间
  35. context.strokeStyle = "#FFFFFF";
  36. for (var i = 0; i < 12; i++) {
  37. context.fillText((i + 3) % 12 == 0 ? 12 : (i + 3) % 12, 180, 0);
  38. context.rotate((Math.PI / 6));
  39. }
  40. context.restore();
  41. context.save();
  42. context.beginPath();
  43. context.lineWidth = 5;
  44. context.translate(255, 255); //将坐标系坐标原点移至图中间
  45. for (i = 0; i < 60; i++) {
  46. if (i % 5 != 0) {
  47. context.beginPath();
  48. context.moveTo(180, 0);
  49. context.lineTo(190, 0);
  50. context.stroke();
  51. }
  52. context.rotate(Math.PI / 30);
  53. }
  54. context.restore();
  55. var now = new Date();
  56. var sec = now.getSeconds();
  57. var min = now.getMinutes();
  58. var hr = now.getHours() >= 12 ? now.getHours() - 12 : now.getHours();
  59. context.save();
  60. context.translate(255, 255); //将坐标系坐标原点移至图中间
  61. // - (Math.PI / 6) * 3 是因为0度在3点这里
  62. context.rotate(hr * (Math.PI / 6) + (Math.PI / 360) * min + (Math.PI / 21600) * sec - (Math.PI / 6) * 3);
  63. context.lineWidth = 14;
  64. context.beginPath();
  65. context.moveTo(-20, 0);
  66. context.lineTo(150, 0);
  67. context.stroke();
  68. context.restore();
  69. context.save();
  70. context.translate(255, 255); //将坐标系坐标原点移至图中间
  71. context.rotate(min * (Math.PI / 30) + (Math.PI / 1800) * sec - (Math.PI / 6) * 3)
  72. context.lineWidth = 10;
  73. context.beginPath();
  74. context.moveTo(-28, 0);
  75. context.lineTo(160, 0);
  76. context.stroke();
  77. context.restore();
  78. context.save();
  79. context.translate(255, 255); //将坐标系坐标原点移至图中间
  80. context.lineWidth = 1;
  81. context.rotate(sec * (Math.PI / 30) + (Math.PI / 1800) * sec - (Math.PI / 6) * 3)
  82. context.lineWidth = 10;
  83. context.beginPath();
  84. context.moveTo(-28, 0);
  85. context.lineTo(160, 0);
  86. context.stroke();
  87. context.restore();
  88. }

本文转自shyleoking 51CTO博客,原文链接:http://blog.51cto.com/shyleoking/864007

使用HTML5的canvas做一个会动的时钟相关推荐

  1. css3 做一个会动的菜单 menu 按钮动画效果

    css3 做一个会动的菜单 menu 按钮动画效果 需要做一个会的动画按钮效果,小前端部知道如何实现,我看了一眼需要的效果,给他写了一个简单的 demo. 设计师给了俩图片,一个是 三 这样的菜单图标 ...

  2. php 影院选座js代码,在react中用canvas做一个电影院选座功能

    又到了每日分享了.这次分享的是:在react中用canvas做一个电影院选座功能. 前言:项目采用create-react-app脚手架,就是做了一个效果所以只有一个页面但是也用了react-rout ...

  3. Html5基于Canvas画一个动态时钟

    文章目录 前言 一.前期准备 二.绘制刻度 1.流程 2.效果图 三.绘制文字 1.流程 2.效果图 四.绘制指针 1.取得当前时间 2.绘制秒针 3.绘制分针 4.绘制时针 5.效果图 五.绘制圆心 ...

  4. html数独游戏制作,使用HTML5的dragdrop做一个数独游戏

    数独是很好玩的游戏,之前我用jQuery做了一个数独游戏,因为用javaScript来实现drag和drap非常麻烦,jQuery的UI提供了一套非常不错的drag和drap(以后就简称DnD算了), ...

  5. android canvans 画3d,如何用Canvas做一个3D球

    先前在博客园看过Waxes同学在博客园做的3D球的Demo,地址在这 把他的Demo pull了下面,很多数学公式,即便在他的博客园里也有两个公式无法解释.因此,这里就写一篇自己思路的文章,教大家如何 ...

  6. js:使用canvas做一个图片标注功能

    canvas相关库的选择 名称 star(2021.3) 文档 备注 fabricjs 18.2k http://fabricjs.com/ -------- konva 6k https://kon ...

  7. 使用JS和Canvas做一个html5小游戏

    这是一个很简单的html5游戏,通过学习原博文自己做了些改造, 现在附上原博文的链接 这是游戏的截图: 1.有计算抓住的怪物的数量 2.有背景,英雄,怪物. 第一步:建立html文件和js文件 建立一 ...

  8. canvas做一个简单气泡图

    数据结构: [{name: '土豆',num: 200,}, {name: '西瓜',num: 80,}, {name: '黄瓜',num: 85,}, {name: '粉丝',num: 70,}, ...

  9. 【百战GAN】二次元宅们,给自己做一个专属动漫头像可好!

    大家好,欢迎来到专栏<百战GAN>,在这个专栏里,我们会进行算法的核心思想讲解,代码的详解,模型的训练和测试等内容. 作者&编辑 | 言有三 本文资源与生成结果展示 本文篇幅:68 ...

最新文章

  1. 伍六七带你学算法 入门篇——最后一个单词的长度
  2. 三层交换机不能完全取代路由的作用
  3. phpcms调用栏目描述_phpcms标签整理_当前栏目调用
  4. mysql数据库表空间最大值_mysql 数据库取最大值
  5. Windows Azure Cloud Service (17) Role Endpoint
  6. python win32gui安装_python-无法安装win32gui
  7. 破解keil 2k限制,注册码生成
  8. 10.众里寻他千百度- Find命令和文件后缀
  9. Octopus系列之更新历史记录
  10. js小例子(标签页)
  11. ENVI Flaash大气校正与6S大气校正(Landsat8OLI)
  12. 你的主机中的软件中止了一个已建立的连接
  13. 一篇文章从了解到入门shell
  14. tv3描述文件代理服务器,超强悍技术贴!Apple TV3复活DNS的刷机全教程
  15. 【重要通知】红帽RHCE7.0版本考试即将下线
  16. vtk 曲线 样式_VTK笔记——拟合样条曲线(Parametric Spline)-Go语言中文社区
  17. CentOS7 配置R语言及Rstudio-serve
  18. android chrome无法运行,Android 测试 Chrome 浏览器能正常启动 Chrome 浏览器,但是不能进行操作,求大神!!...
  19. 全网最硬核 JVM TLAB 分析 1. 内存分配思想引入
  20. js中数组的高逼格操作(filter、sort、map、reduce)

热门文章

  1. [GDUT 决赛]--GCD,LCM——我是好人(数论)
  2. 微软职位内部推荐-Sr. SW Engineer for Privacy Id
  3. Net Framework 2.0 MSI returned error code 1603解决方法
  4. 如何使用VirtualBox与GNS3搭建思科设备实验环境
  5. Python 正则(1)
  6. Cannot set property 'render' of undefined
  7. 从首页问答标题到问答详情页
  8. CAPI3 HTTP文件服务器搭建(共享目录版)
  9. 使用虚拟机运行Ubuntu时,主机与宿主机共享文件的方法。
  10. 删除windows上的oracle产品