论坛首页 Web前端技术论坛

Canvas模拟小时候一种很炫的绘图玩具

浏览 3380 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-12-05  

小时候的这个玩具是这样的:一块大齿轮圈圈,齿轮在圈内,还有其他几块小的齿轮圈圈,齿轮在圈外,小齿轮内还有很多小孔,把小齿轮放在大齿轮圈内,将铅笔插入小齿轮圈的小孔上,然后滑动铅笔,就能画出各式各样的弧线形状。

但忘记了这个玩具叫什么,有谁知道的,望告知。

 

演示地址:http://www.cssass.com/blog/index.php/2012/1335.html

 

<!doctype html>
<html>
<head>
<meta charset='UTF-8' />
<title>圈圈图</title>
<style>
*{padding:0;margin:0;}
body{background:#999}
#operationBar{position: fixed;bottom:0;width:100%;text-align:center;}
</style>
</head>
<body>
<div id="operationBar">
	<label><input class="opt" id="showCricle" type="checkbox" />圈</label>
	<label><input class="opt" id="showLine" type="checkbox" checked/>线</label>
	<label><input class="opt" id="showPoint" type="checkbox" />点</label>
	<label><input class="opt" id="showColor" type="checkbox" checked />颜色</label>
	<label><input class="opt" id="isRefresh" type="checkbox" />刷新</label>
	<label>大圈半径:<input class="opt" id="bigRadius" type="text" value="133" /></label>
	<label>小圈半径:<input class="opt" id="smallRadius" type="text" value="140" /></label>
	<label>线长:<input class="opt" id="lineLength" type="text" value="123" /></label>
	<label><input id="runBtn" type="button" value="新建"/></label>
</div>
</body>
<script>
function $id(o){
	return document.getElementById(o);
}
function extendCopy(p, c) {
  var c = c || {};
  for (var i in p) {
    c[i] = p[i];
  }
  c.uber = p;
  return c;
}
function Toy(options){
	this.setOptions(options);
	this.createPad();
	this.draw(true);
}
Toy.prototype = {
	setOptions: function(options) {
		this.options = {
			R:	133, //大圈半径
			r:	140, //小圈半径
			l:	123, //线长
			showPoint: false, //显示小点
			showCricle: false, //显示小圈
			showLine: true, //显示线条
			isRefresh: false, //每次清屏
			showColor : false, //颜色变化
			count : 1500 //绘制次数
		};
		extendCopy(options || {}, this.options);
		//实际占用区域半径的计算
		var delta = 0;
		if(this.options.R > this.options.r){
			delta = (this.options.r > this.options.l) ? 0 : this.options.l - this.options.r;
			this.radius = this.options.R + delta;
		}else{
			delta = (this.options.r > this.options.l) ? this.options.r - this.options.R : this.options.l - this.options.R;
			this.radius = this.options.r + delta;
		}
		this.radius += 10;
		this.color = {
			r : 0,
			g : 0,
			b : 255,
			a : 0.5
		};
		this.colorValue = "rgba("+this.color.r+","+this.color.g+","+this.color.b+","+this.color.a+")";
		this.angle = 0;
		this.timePlay = null;
  	},
  	changeColor : function(){
  		this.color.r += 10;
  		if(this.color.r > 255){
  			this.color.r = 0;
  			this.color.g += 10;
  		}
  		if(this.color.g > 255){
  			this.color.r = 0;
  			this.color.g = 0;
  			this.color.b += 10;
  		}
  		if(this.color.b > 255){
  			this.color.r = 0;
  			this.color.g = 0;
  			this.color.b = 0;
  		}
  		this.colorValue = "rgba("+this.color.r+","+this.color.g+","+this.color.b+","+this.color.a+")";
  	},
	createPad : function(isReset){
				if(!isReset){
					this.pad = document.createElement("canvas");
					document.body.appendChild(this.pad);
				}
				this.pad.width =  this.radius * 2;
				this.pad.height = this.radius * 2;
				this.ctx = this.pad.getContext('2d');
				this.ctx.lineJoin = 'round';
				this.ctx.lineCap = 'round';
				this.ctx.lineWidth=.5;
				this.ctx.strokeStyle = this.colorValue;
				this.ctx.fillStyle = this.colorValue;
			},
	draw : function(isFirst){
				this.ctx.save();
				if(this.options.showColor){
					this.changeColor();
					this.ctx.strokeStyle = this.colorValue;
					this.ctx.fillStyle = this.colorValue;
				}
				//大圆
				this.ctx.translate(this.radius, this.radius);
				if(isFirst){
					this.ctx.beginPath();
					this.ctx.arc(0,0,this.options.R,0,Math.PI*2,true);
					this.ctx.closePath();
					this.ctx.stroke();
				}
				//小圆
				this.ctx.rotate(-this.angle);
				this.ctx.translate(this.options.R-this.options.r,0);
				if(this.options.showCricle || isFirst){
					this.ctx.beginPath();
					this.ctx.arc(0,0,this.options.r,0,Math.PI*2,true);
					this.ctx.closePath();
					this.ctx.stroke();
				}
				//线
				this.ctx.rotate(this.angle * this.options.R/this.options.r);
				if(this.options.showLine || isFirst){
					this.ctx.beginPath();
					this.ctx.moveTo(0,0);
					this.ctx.lineTo(this.options.l,0);
					this.ctx.stroke();
				}
				//小点
				if(this.options.showPoint || isFirst){
					this.ctx.translate(this.options.l,0);
					this.ctx.beginPath();
					this.ctx.arc(0,0,1,0,Math.PI*2,true);
					this.ctx.fill();
				}
				this.ctx.restore();
				this.angle += 0.2;
				return this;
			},
	move : function(){
			var that = this,
				count = 0,
				_s = function(){
					that.clear(count == 0).draw();
					count ++;
					that.timePlay = setTimeout(_s,50);
					if(that.options.count < count) {
						clearTimeout(that.timePlay)
					};
				}
				_s();
				return this;
		},
	stop : function(){
		clearTimeout(this.timePlay);
		return this;
	},
	clear : function(isInit){
		if(this.options.isRefresh || isInit){
			this.ctx.clearRect(0,0,this.radius * 2,this.radius * 2);
		}
		return this;
	},
	reset : function(options){
		this.setOptions(options);
		this.createPad(true);
		this.draw(true);
		return this;
	}
}
function getOpt(){
	return {
		R : $id("bigRadius").value - 0 || 133,
		r : $id("smallRadius").value - 0 || 140,
		l : $id("lineLength").value - 0 || 123,
		showPoint: $id("showPoint").checked,
		showCricle: $id("showCricle").checked,
		showLine: $id("showLine").checked,
		isRefresh: $id("isRefresh").checked,
		showColor : $id("showColor").checked
	}
}
$id("runBtn").onclick = function(){
	new Toy(getOpt()).move();
}
var opt = getOpt();
var temp1 = new Toy(opt),
	temp2 = new Toy(opt).move();
var inputs = document.getElementsByClassName("opt");
for (var i = inputs.length - 1; i >= 0; i--) {
	inputs[i].onchange = function(){
		temp1.reset(getOpt());
	}
};
</script>
</html>
 
   发表时间:2012-12-05   最后修改:2012-12-05

附图


 
  • 大小: 30.8 KB
0 请登录后投票
   发表时间:2012-12-05  
这个数学上叫摆线
0 请登录后投票
   发表时间:2012-12-17  
这玩具名字叫 繁花规
0 请登录后投票
   发表时间:2012-12-20  
刚开始接触html5,感谢楼主分享源码,先顶贴,再细读
0 请登录后投票
   发表时间:2012-12-28  
嗯,繁花规
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics