H5 Canvas | 画布中变量作用域与setInterval方法同步执行探究
Demo - 随机绘制圆环
实现思路:
- 将一个圆环的绘制分成100份,setInterval()方法定义每隔时间n绘制一段新的,每份的开始路径都是上一次的结束路径,实现步进绘制。
- 通过Math.random(),随机生成圆的坐标半径颜色。
实现方法:
- 定义画布和联系
- 设置步进属性
- 设置随机圆属性(5个参数:x,y,半径,开始,结束,方向)
- 循环执行绘画
<<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>
在不同的变量环境下出现了不同的情况:
全局变量:step, sAngle, eAngle , x, y, r;

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

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

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

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

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

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

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

- ...一共64种变化,谨慎定义Canvas中的变量作用域
关于Context的另一个测试:
在同一个画布中调用获取两个Context,但通过输出可以看到每个画布只有一个对应的Context

经过几个Demo的分析得到以下结论:
- 在调用同一个function时候,私有变量互不相干,会像C一样得到不同的副本各自存值
- Canvas的Context样式(strokeStyle/shadowColor/...)是针对该Canvas(画布)唯一的
- 如果同时调用setInterval方法,则轮流执行,1,2,1,2,1,2...以此类推
- 谨慎使用setInterval方法,同时运行多个会导致相互干扰
遗留问题:
- 如何同时绘画不同样式?

H5 Canvas | 画布中变量作用域与setInterval方法同步执行探究的更多相关文章
- 跨JavaScript对象作用域调用setInterval方法
跨JavaScript对象作用域调用setInterval方法: var id = window.setInterval(function() {foofunc.call(this);}, 200);
- 控制器controller与指令中的link、controller中变量作用域的关系
angjualrjs中的作用域与原生js中的函数嵌套原理一致,都是存在作用域的继承.若在子控制器(同样包括在指令中的link或是controllerding中定义变量,此时指令中必须未使用scope独 ...
- JS中for循环变量作用域--解决for循环异步执行的问题
被这个问题困惑了很久,终于在网上找到了答案,感谢~ 现在分享给大家~ js中如何让一个for循环走完之后,再去执行下面的语句? 这涉及for循环变量作用域的问题,js中作用域只有函数作用域和全局作用域 ...
- C/C++语言中变量作用域:局部变量,全局变量,文件级变量
C/C++语言中的变量分为全局变量和局部变量. 这样的划分方式的根据是变量的可见范围或者叫做作用域. 1 局部变量 局部变量指的是定义在{}中的变量,其作用域也在这个范围内.尽管常见的局部变量都是定义 ...
- 关于Chrome和Opera中draw Image()方法无法在canvas画布中绘制图片的问题
var c=document.getElementById("myCanvas"); var ctx=c.getContext("2d"); var img=d ...
- erlang中变量作用域
http://erlangdisplay.iteye.com/blog/315452 _开头(包括_)在erlang可以是表明,这个变量可以存任意东西,就是我们常说的全匹配,_A一般来说就是表明这个东 ...
- Python3中变量作用域nonlocal的总结
最近,在工作中踩到了一个关于Python3中nonlocal语句指定的变量作用域的坑.今天趁周六休息总结记录一下. 众所周知,Python中最常见的作用域定义如下: 但是,为了更加方便地在闭包函数 ...
- Django 模板中 变量 过滤器的使用方法
一.变量 1.变量的形式是:{{variable}}, 当模板引擎碰到变量的时候,引擎使用变量的值代替变量. 2.使用dot(.)能够访问变量的属性 3.当模板引擎碰到dot的 ...
- Javascript中this作用域以及bind方法的重写
这是一个最近遇到的笔试题,出于尊重,不会说出该公司的名字,源于自身比较少,笔试题是将bind方法用ES3重写,使用bind这个方法,导致一时半会懵了,只记得bind可以改变this的作用域. 作为查漏 ...
随机推荐
- 初见Python<6>:文件读写
1.open函数语法: python通过open函数打开文件,建立程序与文件之间的连接. open函数语法:open(filename[,mode[,buffering]]) 其中filename是指 ...
- luogu P1440 求m区间内的最小值
题目描述 一个含有n项的数列(n<=2000000),求出每一项前的m个数到它这个区间内的最小值.若前面的数不足m项则从第1个数开始,若前面没有数则输出0. 输入输出格式 输入格式: 第一行两个 ...
- luogu P2485 [SDOI2011]计算器
题目描述 你被要求设计一个计算器完成以下三项任务: 1.给定y.z.p,计算y^z mod p 的值: 2.给定y.z.p,计算满足xy ≡z(mod p)的最小非负整数x: 3.给定y.z.p,计算 ...
- BZOJ 3676 [Apio2014]回文串(回文树)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3676 [题目大意] 考虑一个只包含小写拉丁字母的字符串s. 我们定义s的一个子串t的& ...
- GIL,queue,进程池与线程池
GIL 1.什么是GIL(这是Cpython解释器) GIL本质就是一把互斥锁,既然是互斥锁,原理都是一样的,都是让多个并发线程同一时间只能有一个执行 即:有了GIL的存在,同一进程内的多个线程同一时 ...
- Generator函数(二)
for...of循环 1.for...of循环可以自动遍历Generator函数,不需要再调用next方法 function* helloWorldGenerator(){ yield 'hello' ...
- Web安全开发指南--会话管理
1.会话管理 3.1.会话管理安全规则 1 避免在URL携带session id. 2 使用SSL加密通道来传输cookie. 3 避免在错误信息和调试日志中记录session id. 4 使用框架自 ...
- sql server 博客:不胜人生一场醉
http://blog.csdn.net/baoqiangwang/article/category/604358
- 猫、路由器、交换机和PC
转载:http://duanzw102.blog.163.com/blog/static/161838173201392431722650/ 猫是 modem,是有网络供应商,比如电信公司提供的拨号工 ...
- Font Include Sass Mixin
前端开发whqet,csdn,王海庆,whqet,前端开发专家 前期以前给大家介绍过一个使用google font的mixin(详见<Google Fonts Sass Mixin>),今 ...