html5 椭圆运动(canvas画布实现)
使用html5的canvas标签实现任意元素椭圆运动
实现原理实际上就是椭圆的两个方程:
让椭圆的一个轴的值x周期性匀速增加或减少,算出另外一个坐标点y的值由椭圆的XY坐标和长半轴长和短半轴长,求任意角度椭圆的坐标
X=acosp,Y=bsinp(p为角度参数,a为长半轴,b为短半轴)
示例代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<canvas id="test" width="600" height="200" style="border: 1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<canvas id="test1" width="400" height="600" style="background: url(1.gif) no-repeat 50px 100px;
border: 1px solid #c3c3c3; transform: rotate(30deg); left: 50%; top: 200px; position: absolute;">
Your browser does not support the canvas element.
</canvas>
<script type="text/javascript">
function yundong(a, b, contextId, contextFun) {
//a:椭圆长半轴长度
//b:椭圆短半轴长度
//context:canvas对象
//contextFun:canvas对象方法
var c = document.getElementById(contextId);
var am = a * a;
var bm = b * b;
if (!c.getContext("2d")) {
return;
}
var cxt = c.getContext("2d");
var x = -1, y = 0;
var reverses = false;
cxt.translate(-1, b);
setInterval(function () {
//清空画布
cxt.clearRect(0, 0, c.offsetWidth, c.offsetHeight);
if (x == (2 * a + 1)) {
reverses = true;
}
if (x == -1) {
reverses = false;
}
if (reverses) {
y = Math.sqrt((1 - (x - 1 - a) * (x - 1 - a) / (am)) * bm) - Math.sqrt((1 - (x - a) * (x - a) / (am)) * bm);
cxt.translate(-1, y);
x--;
} else {
y = Math.sqrt((1 - (x - a) * (x - a) / (am)) * bm) - Math.sqrt((1 - (x - 1 - a) * (x - 1 - a) / (am)) * bm);
cxt.translate(1, -y);
x++;
}
contextFun(cxt);
}, 0)
}
function yundong1(a, b, speed, contextId, contextFun) {
//a椭圆长半轴长
//b:椭圆短半轴长
//speed运动速度
//contextId要行椭圆运动的画布
//contextFun运动时的回调,draw画的具体内容
var c = document.getElementById(contextId);
if (!c.getContext("2d")) {
return;
}
var angleStart = -Math.PI;
var cxt = c.getContext("2d");
var x = -1, y = 0;
var reverses = false;
cxt.translate(-1, b);
var step = Math.PI / 180;
var timmer = setInterval(function () {
angleStart = angleStart + step;
cxt.clearRect(0, 0, c.offsetWidth, c.offsetHeight);
x = a * (Math.cos(angleStart) - Math.cos(angleStart - step));
y = b * (Math.sin(angleStart) - Math.sin(angleStart - step));
cxt.translate(x, y);
contextFun(cxt);
}, speed);
var obj = {
start: function () {
timmer = setInterval(function () {
angleStart = angleStart + step;
cxt.clearRect(0, 0, c.offsetWidth, c.offsetHeight);
x = a * (Math.cos(angleStart) - Math.cos(angleStart - step));
y = b * (Math.sin(angleStart) - Math.sin(angleStart - step));
cxt.translate(x, y);
contextFun(cxt);
}, speed);
},
stop: function () {
clearInterval(timmer);
}
}
return obj;
}
//方法1示例
yundong(200, 50, 'test', function (cxt) {
cxt.beginPath();
cxt.fillStyle = "#ccc";
cxt.arc(100, 50, 15, 0, Math.PI * 2, true);
cxt.closePath();
cxt.fill();
})
//方法2示例
var rst = yundong1(100, 200, 20, 'test1', function (cxt) {
cxt.beginPath();
cxt.fillStyle = "#ccc";
cxt.arc(50, 100, 15, 0, Math.PI * 2, true);
cxt.closePath();
cxt.fill();
})
var stop = false;
document.getElementById('test1').onclick = function () {
if (!stop) {
rst.stop();
stop = true;
} else {
rst.start();
stop = false;
}
};
</script>
</html>
静水缘首页
文章分类
最新文章
- nodejs私钥加密公钥解密的一个例子
- uniapp和微信小程序判断程序运行在开发或者测试或者线上版本的方法分别是什么
- electron使用electron-builder打包后模块包含exe文件执行失败
- Compile is disallowed on the main thread, if the buffer size is larger than 4KB
- better-sqlite3简介及常用操作
- nodejs 操作数据库的库
- nodejs使用http-proxy库实现多个域名代理和同时代理websocket的例子,代理包含https和http两种协议
- iis配置反向代理
- javascript伪多线程代码
- ip所在地址段判断