效果如图
由于各个浏览器可能会存在requestAnimationFrame的兼容问题
所以用了个兼容的库
库的代码如下
window.requestNextAnimationFrame =
(function () {
var originalWebkitRequestAnimationFrame = undefined,
wrapper = undefined,
callback = undefined,
geckoVersion = 0,
userAgent = navigator.userAgent,
index = 0,
self = this;
// Workaround for Chrome 10 bug where Chrome
// does not pass the time to the animation function
if (window.webkitRequestAnimationFrame) {
// Define the wrapper
wrapper = function (time) {
if (time === undefined) {
time = +new Date();
}
self.callback(time);
};
// Make the switch
originalWebkitRequestAnimationFrame = window.webkitRequestAnimationFrame;
window.webkitRequestAnimationFrame = function (callback, element) {
self.callback = callback;
// Browser calls the wrapper and wrapper calls the callback
originalWebkitRequestAnimationFrame(wrapper, element);
}
}
// Workaround for Gecko 2.0, which has a bug in
// mozRequestAnimationFrame() that restricts animations
// to 30-40 fps.
if (window.mozRequestAnimationFrame) {
// Check the Gecko version. Gecko is used by browsers
// other than Firefox. Gecko 2.0 corresponds to
// Firefox 4.0.
index = userAgent.indexOf('rv:');
if (userAgent.indexOf('Gecko') != -1) {
geckoVersion = userAgent.substr(index + 3, 3);
if (geckoVersion === '2.0') {
// Forces the return statement to fall through
// to the setTimeout() function.
window.mozRequestAnimationFrame = undefined;
}
}
}
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback, element) {
var start,
finish;
window.setTimeout( function () {
start = +new Date();
callback(start);
finish = +new Date();
self.timeout = 1000 / 60 - (finish - start);
}, self.timeout);
};
}
)
();
然后是代码主体部分
paused是一个动画开关
update函数作用是检测碰撞及更新视图
<!DOCTYPE html>
<head>
<title>Video</title>
<style>
body {
background: #dddddd;
}
#canvas {
background: #ffffff;
cursor: pointer;
margin-left: 10px;
margin-top: 10px;
-webkit-box-shadow: 3px 3px 6px rgba(0,0,0,0.5);
-moz-box-shadow: 3px 3px 6px rgba(0,0,0,0.5);
box-shadow: 3px 3px 6px rgba(0,0,0,0.5);
}
#controls {
margin-top: 10px;
margin-left: 15px;
}
</style>
</head>
<body>
<div id='controls'>
<input id='animateButton' type='button' value='Animate'/>
</div>
<canvas id='canvas' width='750' height='500'>
Canvas not supported
</canvas>
</body>
</html>
<script type="text/javascript" src="./js/requestNextAnimationFrame.js"></script>
<script type="text/javascript">
var canvas=document.getElementById("canvas")
var context=canvas.getContext("2d")
var paused=true
var discs=[
{x:150,
y:250,
lastX:150,
lastY:250,
velocityX:-3.2, //横坐标速率
velocityY:3.5, //纵坐标速率
radius:25,
innerColor:"rgba(255,255,0,1)",
middleColor:"rgba(255,255,0,0.7)",
outerColor:"rgba(255,255,0,0.5)",
strokeStyle:"gray"
},
{
x: 50,
y: 150,
lastX: 50,
lastY: 150,
velocityX: 2.2, //横坐标速率
velocityY: 2.5, //纵坐标速率
radius: 25,
innerColor: 'rgba(100,145,230,1.0)',
middleColor: 'rgba(100,145,230,0.7)',
outerColor: 'rgba(100,145,230,0.5)',
strokeStyle: 'blue'
},
{
x: 150,
y: 75,
lastX: 150,
lastY: 75,
velocityX: 1.2,
velocityY: 1.5,
radius: 25,
innerColor: 'rgba(255,0,0,1.0)',
middleColor: 'rgba(255,0,0,0.7)',
outerColor: 'rgba(255,0,0,0.5)',
strokeStyle: 'orange'
}
]
var numDiscs=discs.length; //圆的个数
var animateButton=document.getElementById("animateButton")
function update(){
var disc=null
for(var i=0;i<discs.length;i++){
disc=discs[i]
if(disc.x+disc.velocityX+disc.radius>canvas.width||disc.x-disc.radius+disc.velocityX<0){ //碰撞检测
disc.velocityX=-disc.velocityX
}
if(disc.y+disc.velocityY+disc.radius>canvas.height||disc.y-disc.radius+disc.velocityY<0){ //碰撞检测
disc.velocityY=-disc.velocityY
}
disc.x+=disc.velocityX
disc.y+=disc.velocityY
}
}
function draw(){
var disc=null
for(var i=0;i<discs.length;i++){
disc=discs[i]
gradient=context.createRadialGradient(disc.x,disc.y,0,disc.x,disc.y,disc.radius)
gradient.addColorStop(0.3,disc.innerColor)
gradient.addColorStop(0.5,disc.middleColor)
gradient.addColorStop(1.0,disc.outerColor)
context.save()
context.beginPath()
context.arc(disc.x,disc.y,disc.radius,0,Math.PI*2,false)
context.fillStyle=gradient
context.strokeStyle=disc.strokeStyle
context.fill()
context.stroke()
context.restore()
}
}
function animation(time){
if(!paused){
context.clearRect(0,0,canvas.width,canvas.height)
draw()
update()
window.requestNextAnimationFrame(animation)
}
}
animateButton.onclick=function(e){
paused=!paused
if(paused){
animateButton.value="Animation"
}else{
window.requestNextAnimationFrame(animation)
animateButton.value="Pause"
}
}
</script>
网友评论