3
\$\begingroup\$

I'm experimenting with moving shapes in JavaScript with a canvas tag.

I have one half circle (only stroked) which rotates on set intervals.

I've written the code so many more can be added. I can give starting rotations and a lot of other handy parameters.

I've tried this with twelve circles and it looks exactly like I want. Problem is, the animation slows down and the framerate goes down quite fast. And it uses heaps and heaps of memory. Any ideas on how to optimize this code to not consume so much?

Demo: http://jsfiddle.net/xaddict/fLE8z/

JS code:

var kin;
var canvas;
var context;
var pi = Math.PI;
var linearSpeed = 0.5*pi; // pixels / second
var linearDistEachFrame;
var myCircle;

function Circle(x, y, rot, radius, borderWidth, strokestyle){
    this.x = x;this.y = y;
    this.radius = radius;
    this.borderWidth = borderWidth;
    this.rot = rot
    this.goalrot = rot;
    this.strokestyle = strokestyle;
}

function randomizeThis(object){
    object.goalrot += pi;
}

function updateCircle(object){
    if(object.goalrot > object.rot){ //if goal rotation is bigger than current rotation
        object.rot += linearDistEachFrame;
    }else{ // if goal rotation is equal or smaller than current
            if(object.goalrot >= 2* pi){object.goalrot -= 2* pi;}
            object.rot = object.goalrot;
    }
}

function drawCircle(object){
    context.beginPath();
  context.arc(object.x, object.y, object.radius, object.rot, object.rot+pi, false);
  context.fillStyle = "none"; context.fill();
  context.lineCap = "round";
  context.lineWidth = object.borderWidth;
  context.strokeStyle = object.strokestyle;context.stroke();
}

function drawCirc(context,x,y,radius,clip){
    context.beginPath();
    context.arc(x,y,radius, 0, 2*pi, false);
    if(clip == true){context.clip();}
}

window.onload = function(){
    kin = new Kinetic_2d("canvas");
    canvas = kin.getCanvas();
    context = kin.getContext();

    myCircle =         new Circle(421,320,1.0*pi,    153,    12,"#FAA61A");//FAA61A

    kin.setDrawStage(function(){
        //update
        linearDistEachFrame = linearSpeed * kin.getTimeInterval() / 1000;
        updateCircle(myCircle);

        //clear
        kin.clear();

        //draw
        context.save();
        drawCirc(context,281,222,58,true);
        drawCircle(myCircle);
        context.restore();
    });

    kin.startAnimation();

    setTimeout(function(){randomizeThis(myCircle);setInterval("randomizeThis(myCircle)",4000);clearTimeout(this);},6000);
};

Thanks for all help!

\$\endgroup\$
  • \$\begingroup\$ You may be interested to know that your code performs differently between Firefox and Chrome. The statement context.fillStyle = "none"; should instead be context.fillStyle = "rgba(0,0,0,0)";. \$\endgroup\$ – Barbarrosa Jan 1 '13 at 5:40
2
\$\begingroup\$

There is no need to recalculate the linearDistEachFrame during each update. You may want to precompute 2 * Math.PI as well.

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ I've changed the Math.PI part so now there is a variable 'pi' which is set. Where would you place linearDistEachFrame? Doesn't it change every frame? \$\endgroup\$ – xaddict Nov 2 '11 at 8:01
  • \$\begingroup\$ I've changed the fiddle to use linear distance as a global variable: jsfiddle.net/xaddict/fLE8z \$\endgroup\$ – xaddict Nov 2 '11 at 8:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.