canvas 多个小球绕椭圆轨道转动

canvas实现小球绕轨道转动,并点击某一个后可以加速运动到指定位置,第一次使用canvas做动画,代码有些乱 = =,话不多说看代码,拷贝添加图片可以直接运行

canvas椭圆轨道运动

// An highlighted block
<style>
*{
     
 padding:0;
 margin:0;
 }
 body,html{
     
 width:100%;
 background-color:#000;
 }
 canvas{
     
 margin:0 auto;
 }
 
</style>
<body>
 <canvas id="canvas" width="1000" height="600" >
 您的浏览器不支持canvas>
</body>
<script>
var R=50;
var time=0;
var isClick=false;
var canvasWidth=1000;
var canvasHeight=600;
var originX=500;
var originY=300;
var langAxis=450;
var shortAxis=200;
var stopTime=1200;

var canvas=document.getElementById('canvas')
var cxt = canvas.getContext('2d')

//定义运动的小球
var m1=new Image();
var m2=new Image();
var m3=new Image();
m1.src="./img/m1.jpg"
m2.src="./img/m2.jpg"
m3.src="./img/m3.jpg"
var ballArr=[
    {
     img:m1,x:0,y:0,rad:0},
    {
     img:m2,x:0,y:0,rad:0},
    {
     img:m3,x:0,y:0,rad:0}
]

var running= setInterval(function(){
     
	drawAnimation()
	},1000/60)
	
//画椭圆函数
function drawEls(){
     
	cxt.strokeStyle = "red";
	cxt.lineWidth = 5;
	var step = (langAxis>shortAxis) ? 1/langAxis : 1/shortAxis;
	cxt.beginPath();
	cxt.moveTo(originX+langAxis,originY);
	for(let i=0;i<2*Math.PI;i+=step){
     
		cxt.lineTo(originX+langAxis*Math.cos(i),originY+shortAxis*Math.sin(i));
	}
	cxt.closePath();
	cxt.stroke();
}
//画小球运动
function drawAnimation(steps,stopRad){
     
	cxt.clearRect(0,0,canvasWidth,canvasHeight);
	drawEls();//画椭圆
	steps=steps||1; //步长
	var step=(langAxis>shortAxis) ? 1/langAxis : 1/shortAxis;
	step*=steps; //加速
	time+=step; 
	if(stopRad){
     
        // 当球转到正前方时 停止转动 由于计算精度问题取差的绝对值小于0.1(也可以是其他的数)
        if(Math.abs((time%(2*Math.PI))-((2*Math.PI-stopRad)+Math.PI/2))<0.1){
     
            time =(2*Math.PI-stopRad)+Math.PI/2 //转到正前方
            window.clearInterval(running)
            //停顿一段时间后继续运动
            setTimeout(()=>{
     
                running= setInterval(function(){
     
                    drawAnimation()
                    },1000/60)
                    isClick=false
            },stopTime)
        }
	}
    var balllength=ballArr.length
    var k=0.2/100 //近大远小效果的参数
    var c=0.4
    for(let i=0;i<balllength;i++){
     
        //计算每个小球的起始角度
        ballArr[i].rad = 2*Math.PI*(i/balllength)>0 ? 2*Math.PI*(i/balllength) : 2*Math.PI;
        //计算小球中心位置坐标
        ballArr[i].x=originX+langAxis*Math.cos(time+ballArr[i].rad);
        ballArr[i].y=originY+shortAxis*Math.sin(time+ballArr[i].rad);

        //小球运动轨迹
        cxt.drawImage(
            ballArr[i].img,
            originX+langAxis*Math.cos(time+ballArr[i].rad)-R*(ballArr[i].y*k+c),//为使小球中心在线上,减掉小球半径
            originY+shortAxis*Math.sin(time+ballArr[i].rad)-R*(ballArr[i].y*k+c),
            2*R*(ballArr[i].y*k+c),
            2*R*(ballArr[i].y*k+c)
        )
    }
}
//点击时触发
function stopRun(moveRad){
     
	window.clearInterval(running);
	running = setInterval(function(){
     
	  drawAnimation(10,moveRad)
	  },1000/60)
}
//监听点击事件
window.onload = function(){
     
	var x=0;
	var y=0;
	canvas.addEventListener('click',e=>{
     
        //当前鼠标点击的坐标
        x=e.pageX-canvas.getBoundingClientRect().left; 
        y=e.pageY-canvas.getBoundingClientRect().top;
        var chooseIndex=-1;
        var moveRad=0;
        //判断点击的区域是否在图形内
        for(let i in ballArr){
     
            if(Math.pow((x-ballArr[i].x),2)+Math.pow((y-ballArr[i].y),2)<Math.pow(R,2)){
     
                chooseIndex = i;
                moveRad=ballArr[i].rad;
                break;
            }
        }
        if(chooseIndex>=0 && !isClick) {
     
            isClick=true;
            stopRun(moveRad);
        }
    })
}
</script>

你可能感兴趣的:(canvas,js,html)