Demo - 随机绘制圆环

实现思路:

  • 将一个圆环的绘制分成100份,setInterval()方法定义每隔时间n绘制一段新的,每份的开始路径都是上一次的结束路径,实现步进绘制。
  • 通过Math.random(),随机生成圆的坐标半径颜色。

实现方法:

  1. 定义画布和联系
  2. 设置步进属性
  3. 设置随机圆属性(5个参数:x,y,半径,开始,结束,方向)
  4. 循环执行绘画

<<index.html>>

<!DOCTYPE html>
<html> <head>
<meta charset="utf-8">
<style type="text/css">
#canvas {
border: 1px black solid;
}
</style>
</head> <body>
<canvas id="canvas" width="1000" height="400">您的浏览器不支持canvas</canvas>
<input type="button" onclick="InitDraw()" value="draw">
<script type="text/javascript">
function InitDraw() {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var ctx2 = canvas.getContext('2d'); var step;
// var sAngle;
// var eAngle;
var x, y, r;
var add, stepTime, counterClockwise;
// 步进属性
step = 0;
add = Math.PI * 2 / 100;
stepTime = 20;
// 随机圆属性
sAngle = 0;
eAngle = sAngle + add;
counterClockwise = false;
x = Math.random() * 800 + 100;
y = Math.random() * 200 + 100;
r = Math.random() * 50 + 50;
ctx.strokeStyle = "#" + (Math.random() * 0x1000000 << 0).toString(16);
ctx.shadowColor = "#" + (Math.random() * 0x1000000 << 0).toString(16);
console.log(ctx.strokeStyle);
console.log(ctx2.strokeStyle);
ctx.lineWidth = 1.0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 10; // 画圆
var drawID = setInterval(Draw, stepTime); function Draw() {
if (step < 100) {
// 绘制路径并画
ctx.beginPath();
ctx.arc(x, y, r, sAngle, eAngle, counterClockwise);
ctx.stroke();
ctx.closePath();
// 步进
sAngle = eAngle;
eAngle += add;
// console.log("drawID:" + drawID + ",step:" + step);
// console.log(ctx.strokeStyle);
step++;
} else {
clearInterval(drawID);
}
} }
</script>
</body> </html>

在不同的变量环境下出现了不同的情况:

  1. 全局变量:step, sAngle, eAngle , x, y, r;

    在执行绘图过程中持续变化的参数是step,sAngle,eAngle,再次调用时回到函数InitDraw();重新定义六个全局变量以及画笔样式,则重新开始绘图。上一个step和画笔样式都停留在按下button的一刻

  2. 全局变量:sAngle, eAngle; 局部变量:var step, x, y, r;

    在控制台输出情况可以看到,当起始位置为全局变量时相互干扰的非常厉害,但因为step是局部变量,调用的是不同的副本,最后两个圈均执行到了99。并且可以看到控制台中drawID是间隔出现的,对两次setInterval方法轮流执行,也就造成了sAngle位置是跳跃的虚点。

  3. 局部变量:var step ,sAngle, eAngle, x, y, r;

    但要注意的是在该示例中共用同一个画布和联系(ctx),在这里画笔的颜色和样式被刷新成为新的。那么应该如何在同一画布中同时绘画不同样式?

  4. 全局变量:step; 局部变量:var sAngle, eAngle, x, y, r;

    在第二次点击出现的圈绘到约半圈时停止

    点击button重新执行InitDraw();step=0; 从打印信息可以看到两个不同的setInterval方法对step变量相互干扰,直到step有机会到达99时停止绘图。

  5. ...一共64种变化,谨慎定义Canvas中的变量作用域

关于Context的另一个测试:

在同一个画布中调用获取两个Context,但通过输出可以看到每个画布只有一个对应的Context

经过几个Demo的分析得到以下结论:

  • 在调用同一个function时候,私有变量互不相干,会像C一样得到不同的副本各自存值
  • Canvas的Context样式(strokeStyle/shadowColor/...)是针对该Canvas(画布)唯一的
  • 如果同时调用setInterval方法,则轮流执行,1,2,1,2,1,2...以此类推
  • 谨慎使用setInterval方法,同时运行多个会导致相互干扰

遗留问题:

  • 如何同时绘画不同样式?

H5 Canvas | 画布中变量作用域与setInterval方法同步执行探究的更多相关文章

  1. 跨JavaScript对象作用域调用setInterval方法

    跨JavaScript对象作用域调用setInterval方法: var id = window.setInterval(function() {foofunc.call(this);}, 200);

  2. 控制器controller与指令中的link、controller中变量作用域的关系

    angjualrjs中的作用域与原生js中的函数嵌套原理一致,都是存在作用域的继承.若在子控制器(同样包括在指令中的link或是controllerding中定义变量,此时指令中必须未使用scope独 ...

  3. JS中for循环变量作用域--解决for循环异步执行的问题

    被这个问题困惑了很久,终于在网上找到了答案,感谢~ 现在分享给大家~ js中如何让一个for循环走完之后,再去执行下面的语句? 这涉及for循环变量作用域的问题,js中作用域只有函数作用域和全局作用域 ...

  4. C/C++语言中变量作用域:局部变量,全局变量,文件级变量

    C/C++语言中的变量分为全局变量和局部变量. 这样的划分方式的根据是变量的可见范围或者叫做作用域. 1 局部变量 局部变量指的是定义在{}中的变量,其作用域也在这个范围内.尽管常见的局部变量都是定义 ...

  5. 关于Chrome和Opera中draw Image()方法无法在canvas画布中绘制图片的问题

    var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); var img=d ...

  6. erlang中变量作用域

    http://erlangdisplay.iteye.com/blog/315452 _开头(包括_)在erlang可以是表明,这个变量可以存任意东西,就是我们常说的全匹配,_A一般来说就是表明这个东 ...

  7. Python3中变量作用域nonlocal的总结

    最近,在工作中踩到了一个关于Python3中nonlocal语句指定的变量作用域的坑.今天趁周六休息总结记录一下. 众所周知,Python中最常见的作用域定义如下:   但是,为了更加方便地在闭包函数 ...

  8. Django 模板中 变量 过滤器的使用方法

    一.变量       1.变量的形式是:{{variable}}, 当模板引擎碰到变量的时候,引擎使用变量的值代替变量.    2.使用dot(.)能够访问变量的属性    3.当模板引擎碰到dot的 ...

  9. Javascript中this作用域以及bind方法的重写

    这是一个最近遇到的笔试题,出于尊重,不会说出该公司的名字,源于自身比较少,笔试题是将bind方法用ES3重写,使用bind这个方法,导致一时半会懵了,只记得bind可以改变this的作用域. 作为查漏 ...

随机推荐

  1. LAMP搭建Discuz论坛

    搭建Discuz论坛 1.  准备LAMP环境 LAMP是Linux,Apache,MySql和PHP的缩写,是Discuz论坛系统依赖的基础运行环境 1.安装Apache2 Ubuntu需要安装Ap ...

  2. [BZOJ2226][SPOJ5971]LCMSum(莫比乌斯反演)

    2226: [Spoj 5971] LCMSum Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1949  Solved: 852[Submit][S ...

  3. 【推导】【NTT】hdu6061 RXD and functions(NTT)

    题意:给定一个n次多项式f(x)的各项系数,让你求f(x-Σai)的各项系数. http://blog.csdn.net/v5zsq/article/details/76780053 推导才是最关键的 ...

  4. 【动态规划】POJ1664-放苹果

    非常经典的划分数问题,即相当于把m个物体分成至多n组,求出分组总数. [思路]当前状态dp[i][j]表示将i个物体分成至多j组的分组总数.对于当前状态,有以下两种情形: (1)j组中有组为空,则这种 ...

  5. (疯狂java)第二课

    (本文章只是为了好玩,没有别的意思,有理解错误之处,恳请提醒,谢谢) 三.数据类型和运算符 想了一下今天看的内容好像依然大脑停留在用C语言去理解java,感觉有点奇怪,为啥本章叫数据类型和运算符,上来 ...

  6. [HihoCoder1259]A Math Problem

    题目大意: 有一个函数f(n),满足3f(n)*f(2n+1)=f(2n)*(1+3f(n)),f(2n)<6f(n). 我们用g(t)表示f(i)%k=t的i的个数,其中1<=i< ...

  7. 深度学习的GDB调试命令和经验记录

    调试的指令很简单: cd $CAFFE_ROOT, 1. gdb ./build/tools/caffe 2. 设置运行参数 set args train --solver=xxxxsolver.pr ...

  8. ES6 函数参数的默认值

    基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采取变通的方法. function log(x,y){ y = y||'world'; console.log(x,y); } log('k ...

  9. (Mark)操作系统原理

    Q:什么是中断?A:中断嘛,举个容易理解的例子吧.   比如莲莲和唐唐在下象棋,眼看莲莲就快招架不住了,正当此紧要关头,唐唐的女友来了,非要唐唐陪她上街买衣服不可(唐唐晕倒:-) ),于是唐唐不得不同 ...

  10. php根据汉字获取拼音(php基于拼音搜索实现原理)

    php根据汉字获取拼音(php基于拼音搜索实现原理) 代码一:获取字符串汉字首字母,兼容GBK和UTF-8 <?php function getfirstchar($s0){   //获取单个汉 ...