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. 解决PHPExcel长数字串显示为科学计数

    在excel中如果在一个默认的格中输入或复制超长数字字符串,它会显示为科学计算法,例如身份证号码,解决方法是把表格设置文本格式或在输入前加一个单引号. 使用PHPExcel来生成excel,也会遇到同 ...

  2. [Atcoder Grand Contest 004] Tutorial

    Link: AGC004 传送门 A: …… #include <bits/stdc++.h> using namespace std; long long a,b,c; int main ...

  3. 【强连通分量缩点】【拓扑排序】【dp预处理】CDOJ1640 花自飘零水自流,一种相思,两处闲愁。

    题意: 在n个点m条边的有向图上,从1出发的回路最多经过多少个不同的点 可以在一条边上逆行一次 题解: 在同一个强连通分量中,显然可以经过当中的每一个点 因此先将强连通分量缩点,点权为强连通分量的点数 ...

  4. [Bug]IE11下,forms认证,出现无法保存cookie的问题

    目录 ie11 解决方案 ie11 在ie11下,访问服务器上的网站地址,莫名其妙的多出一串东西,这一串字符串是由于客户端禁用cookie造成sessionid无法写入cookie,所以就拼在url上 ...

  5. Java Excel 插入图片

    在POI中有HSSFPatriarch对象,该对象为画图的顶级管理器,它的createPicture(anchor, pictureIndex)方法就能够在Excel插入一张图片.所以要在Excel中 ...

  6. mongo 误操作恢复数据

    场景:我往同一个集合里面插入 三条数据  aa:aa  bb:bb  cc:cc .后来我后悔了,不想插入 bb:bb,通过oplog重放过滤好 bb:bb这条数据. 原理: 1.通过 oplog.r ...

  7. --secure-file-priv option so it cannot execute this statement

    MYSQL导入数据出现The MySQL server is running with the --secure-file-priv option so it cannot execute this ...

  8. SQL性能调优基础教材

    一.数据库体系结构 1.       Oracle数据库和实例 数据库:物理操作系统文件或磁盘的集合. 实例:一组Oracle后台进程/线程以及一个共享内存区,这些内存由同一个计算机上运行的线程/进程 ...

  9. scrapy处理需要跟进的url

    在做scrapy爬虫的时候经常会遇到需要跟进url的情况,网站a有许多url,但是我们需要跟进这些url,进一步获取这些url中的详细内容. 简单的说就是要先解析出所有需要的url,然后跟进这些url ...

  10. centos使用密钥替换密码登录服务器

    一.首先登陆centos,切换用户,切换到你要免密码登陆的用户,进入到家目录,以下我以admin为例,命令:su admincd ~ 二.创建钥匙,命令:ssh-keygen -t rsa,一路按Y搞 ...