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的作用域. 作为查漏 ...
随机推荐
- 计蒜客NOIP2018模拟1
https://www.jisuanke.com/contest/1152 T1:最失败的一道题,其实就是道水题,好几种写法,一种都没想出来. 题意转化后就是:每个数可以选a[i]和a[i]-k,最后 ...
- JZYZOJ 1382 光棍组织 状压dp
http://172.20.6.3/Problem_Show.asp?id=1382 水得过分了,本来以为要用lzx学长的写法写,抱着试试看的想法写了个特暴力的dp+dfs,过了,真是... ...
- BZOJ 3127 [Usaco2013 Open]Yin and Yang(树点分治)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3127 [题目大意] 给出一棵01边权树,求存在多少条路径,使得路径上0和1的数量相同, ...
- 【最小割】【Dinic】Gym - 101201G - Maximum Islands
题意:方格内有些位置是水域,有些位置是陆地,有些位置是被云彩遮挡住了:让你自己规定被云彩遮挡住的地方是陆地还是水域,使得陆地个数最多.(均为四连通块) 显然与陆地邻接的云彩填成水比较优.其他云彩格子填 ...
- JAVA EE 项目常用知识 之AJAX技术实现select下拉列表联动的两种用法(让你真正理解ajax)
ajax 下拉列表联动的用法. ajax的定义: AJAX 是一种用于创建快速动态网页的技术. 通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新.这意味着可以在不重新加载整个网页的 ...
- FreeMarker输出$
FreeMarker如何输出$(美元符号) 使用${'$'} 如需要输出${user.id} 则${'$'}{user.id}
- Unity3D 避免玩家作弊
如果你的Unity项目快上线了,我强烈建议你看一下Anti-Cheat这个插件.因为IOS和Android分别越狱和Root后玩家可以使用 @八门神器 @烧饼修改器 等一些列作弊的软件来修改游戏内存, ...
- google的开源项目总结
转自http://www.feng5166.com/blog/424.html google的开源项目值得我们一用的,这些项目很有意义,甚至可以直接用在我们自己的工作上!学习编程的的一个比较好的方式就 ...
- 重写alert方法完成类似gmail的友好提示
当在网页中调用aelrt()方法的时候,系统会自动显示友好的提示方式 . 下面是css样式控制代码: /*----------------------------------------------- ...
- 较详细的介绍JNI
JNI其实是Java Native Interface的简称,也就是java本地接口.它提供了若干的API实现了和Java和其他语言的通信(主要是C&C++).也许不少人觉得Java已经足够强 ...