停止动画,使用KineticJS在mousedown上增加圆半径

时间:2013-08-31 17:25:26

标签: javascript canvas kineticjs

这是我的第一个问题,所以如果您需要任何其他信息,请告诉我。

所以我的目标是能够点击移动的圆圈并使其移动停止,当鼠标按钮向下时,其半径稳定增加(就像一个膨胀的气球)。目前我已经拥有它,所以当鼠标停下来时,半径会扩大1,然后一旦我鼠标向上移动它就会变得疯狂(我希望它能在鼠标上移动它的新半径)。

这是我的代码:

HTML

  <html>
    <head>  
    <meta>
    <link rel="stylesheet" type="text/css" href="styles/main.css" />
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.6.0.min.js"></script>
</head>
    <body>
    <div id="wrapper">      
        <div id="stage"></div>
    </div>
    <script type="text/javascript" src="scripts/main.js"></script>
    </body>
</html>

CSS

#wrapper{
    margin: 10% auto;
    width: 900px;
    text-align: center;
}
#stage{
    border: 1px solid black;
    display: block;
}

的Javascript

var circlevx = 5;
var circlevy = 5;
var runAnimation = true;
/*******************************
setting up the stage/layers
********************************/
window.onload = function(){
    var stage = new Kinetic.Stage({
        container : 'stage',
        width : 900,
        height : 600
    });
    var shapesLayer = new Kinetic.Layer();

    /**********************************
        creating the circle object
    *************************************/
    var circle = new Kinetic.Circle({
        x : stage.getWidth() / 2,
        y : stage.getHeight() / 2,
        radius : 50,
        fill : 'grey',
        stroke : 'black',
        strokeWidth : 1
    });


    /*************************************
        add the circle to the stage
    **************************************/
    //bindingBox.add(circle);
    shapesLayer.add(circle);
    stage.add(shapesLayer);

    var date = new Date();
    var time = date.getTime();
    animate(time, circle, runAnimation);
}

window.requestAnimFrame = (function(callback){
    return window.requestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function(callback){
        window.setTimeout(callback, 1000 / 60);
    };
})();   


function animate(lastTime, circle, runAnimation){   
    if(runAnimation) {      
        var stage = circle.getStage();
        var shapesLayer = circle.getLayer();
        var date = new Date();
        var time = date.getTime();
        var timeDiff = time - lastTime;

        // update
        updateCircle(timeDiff, circle);

        // draw
        shapesLayer.draw();

        // request new frame
        requestAnimFrame(function(){
            animate(time, circle, runAnimation);
        });
    }
}

function updateCircle(timeDiff, circle){
    var stage = circle.getStage().attrs;
    var circleX = circle.attrs.x;
    var circleY = circle.attrs.y;
    var circleRadius = circle.attrs.radius;
    var newRadius = circleRadius + 2;
    circleX += circlevx; 
    circleY += circlevy;
    //console.log(stage);

    //throw 'aarg';
    // ceiling condition
    if (circleY < circleRadius) {
        circleY = circleRadius;
        circlevy *= -1;
    }

    // floor condition
    if (circleY > (stage.height - circleRadius)) {
        //console.log('bottom');
        circleY = stage.height - circleRadius;
        circlevy *= -1;
    }

    // right wall condition
    if (circleX > (stage.width - circleRadius)) {
        circleX = stage.width - circleRadius;
        circlevx *= -1;
    }

    // left wall condition
    if (circleX < (circleRadius)) {
        circleX = circleRadius;
        circlevx *= -1;
    }

    circle.setPosition(circleX, circleY);
    //
    circle.on('mousedown', function(){
        runAnimation = false;
        circle.setRadius(newRadius);
    });
    circle.on('mouseup', function(){
        runAnimation = true;
        if(runAnimation) {
            var date = new Date();
            var time = date.getTime();
            animate(time, circle, runAnimation);
        }       
        console.log('mouseout');

    });
}

1 个答案:

答案 0 :(得分:0)

您可以使用动态补间来控制“气球”的扩展

首先,在Kinetic气球对象上声明这些有用的附加属性:

    balloon.X=150;
    balloon.Y=150;
    balloon.VX=0.50;
    balloon.VY=0.50;
    balloon.RAF;
    balloon.tw;

在气球mousedown上取消移动动画并启动补间以展开气球:

如果再次按下鼠标,则可以继续展开气球。

    balloon.on("mousedown",function(){
        cancelAnimationFrame(this.RAF);
        this.tw=new Kinetic.Tween({
            node:this,
            duration:3,
            radius:100
        });
        this.tw.play();
    });

然后在mouseup上暂停通胀补间并重新开始移动动画:

气球将保持其扩大的尺寸。

注意:如果您将鼠标向下移动并从气球移开以释放鼠标,则即使鼠标已启动,也不会调用此mouseup并且气球将继续展开。

    balloon.on("mouseup",function(){
        this.tw.pause();
        this.move();
    });

这是添加到气球对象以进行气球移动的RAF动画功能:

    balloon.move=function(){

        // calc new balloon position
        this.X+=this.VX;
        this.Y+=this.VY;

        // reverse if colliding
        var r=this.getRadius();
        if(this.X<r){ this.VX*=-1; this.X=r; }
        if(this.X>stageWidth-r){ this.VX*=-1; this.X=stageWidth-r; }
        if(this.Y<r){ this.VY*=-1; this.Y=r; }
        if(this.Y>stageHeight-r){ this.VY*=-1; this.Y=stageHeight-r; }

        // set the new balloon position
        this.setPosition(this.X,this.Y);
        layer.draw();

        // request a new animation loop
        var b=this;
        this.RAF=requestAnimationFrame(function(){ b.move();});
    }

这是代码和小提琴:http://jsfiddle.net/m1erickson/D7Ndc/

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Prototype</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.5.min.js"></script>

<style>
#container{
  border:solid 1px #ccc;
  margin-top: 10px;
  width:300px;
  height:300px;
}
</style>        
<script>
$(function(){

    var stageWidth=300;
    var stageHeight=300;

    var stage = new Kinetic.Stage({
        container: 'container',
        width: stageWidth,
        height: stageHeight
    });
    var layer = new Kinetic.Layer();
    stage.add(layer);

    // create a balloon object
    var balloon = new Kinetic.Circle({
        x: 150,
        y: 150,
        radius: 20,
        fill: 'skyblue',
        stroke: 'lightgray',
        strokeWidth: 3,
    });
    balloon.X=150;
    balloon.Y=150;
    balloon.VX=0.50;
    balloon.VY=0.50;
    balloon.RAF;
    balloon.move=function(){

        // calc new balloon position
        this.X+=this.VX;
        this.Y+=this.VY;

        // reverse if colliding
        var r=this.getRadius();
        if(this.X<r){ this.VX*=-1; this.X=r; }
        if(this.X>stageWidth-r){ this.VX*=-1; this.X=stageWidth-r; }
        if(this.Y<r){ this.VY*=-1; this.Y=r; }
        if(this.Y>stageHeight-r){ this.VY*=-1; this.Y=stageHeight-r; }

        // set the new balloon position
        this.setPosition(this.X,this.Y);
        layer.draw();

        // request a new animation loop
        var b=this;
        this.RAF=requestAnimationFrame(function(){ b.move();});
    }
    balloon.tw;
    balloon.on("mousedown",function(){
        cancelAnimationFrame(this.RAF);
        this.tw=new Kinetic.Tween({
            node:this,
            duration:3,
            radius:100
        });
        this.tw.play();
    });
    balloon.on("mouseup",function(){
        this.tw.pause();
        this.move();
    });

    layer.add(balloon);

    balloon.move();

    layer.draw();

}); // end $(function(){});

</script>       
</head>

<body>
    <div id="container"></div>
</body>
</html>