Animating the drawing of a line in the canvas with fabric.js - javascript

I can draw a line in the canvas using:
var myLine = new fabric.Polyline([{x:200,y:200},{x:200,y:200}])
var canvas = new fabric.Canvas('c');
canvas.add(myLine);
However, I want to animate the drawing. I tried:
myLine.animate("points","[{x:200,y:200},{x:10,y:10}]",{onChange: canvas.renderAll.bind(canvas)})
But it's not working, and I couldn't see any way to animate the drawing of the line using fabric.js - I know I can use canvas methods directly but I am curious is fabric.js offers something more concise.

I made a jsFiddle based on http://fabricjs.com/polygon-animation/ and I change it into a fabricjs Polyline. You can set the start and end values from here:
var startPoints = [
{x: 1, y: 1},
{x: 2, y: 2}
];
var endPoints = [
{x: 1, y: 1},
{x: 200, y: 200}
];

No solution suited me so far so here a js-fiddle with what i came up with. Its based on the prev solution by Nistor Christian:
I Made a simple function which accepts the Canvas (in case you want to use this on more than one canvas), color, the original Line-Koordinates (StartXY, EndXY) and the new Line-Koordinates (NewStartX,NewStartY).
function animateLine(canvasInstance,color,
startX,startY,endX,endY,
newStartX, newStartY,newEndX,newEndY)

Related

Countdown animation circular - CreateJS / EaselJS / TweenJS

I am quite new with createJS - I want to achieve like a countdown timer animation:
I stumbled upon this issue which have this fiddle - I want to achive something like this but I want to create an arc shape:
I tried adjusting the code and changed the point values but it only gave me a diamond one instead of a perfect curve.
Do I need to point every values to achieve a perfect circle like:
points = [{x: 50, y: 0}, {x: 51, y: 1}, {x:52, y: 2}, ...etc]
Or is there other way (maybe a function or plugin) that does this stuff? I wasn't able to find anything on their documentation
You might be interested in using an arc() graphic, along with the EaselJS "Command" approach to graphics:
1) Create a full arc
var s = new createjs.Shape().set({x:100,y:100});
s.strokeCmd = s.graphics.s("red")
.ss(10,"round")
.arc(0,0,80,0,Math.PI*2)
2) Store off the last "command"
var cmd = s.command; // This will be the arc command
3) Set the command endAngle to 0. You can do this in the arc() method too
cmd.endAngle = 0;
4) In your animation, increment the endAngle over time. In this example I normalize 100 to mean 100% of the radius (Math.PI*2)
var index = 0;
function tick(event) {
index += 1; // Fake Percent
cmd.endAngle = index/100 * Math.PI*2;
stage.update(event);
}
Here is a quick fiddle: https://jsfiddle.net/lannymcnie/pgeut9cr/
If instead you just want to animate the circle over a fixed period, you can tween the endAngle value. Here is an example using TweenJS: https://jsfiddle.net/lannymcnie/pgeut9cr/2/
createjs.Tween.get(cmd)
.to({endAngle:Math.PI*2}, 2000, createjs.Ease.quadInOut);
Cheers,

How do you animate a line using EaselJS and TweenJS

My goal is to have a line animate from point A to point B using the Tween function.
The drawing library I am using is EaselJS and for Tweening I am using TweenJS.
Is this possible using the moveTo function to animate a straight line from point A to point B?
My current setup is as follows:
var line = new createjs.Shape();
line.beginStroke('cyan');
line.setStrokeStyle(3);
line.moveTo(100, 100);
My goal is to animate this path from x100 y100 to x0 y0.
Animation Example:
I have tried this using the following and nothing happens:
var line = new createjs.Shape();
line.beginStroke('cyan');
line.setStrokeStyle(3);
line.moveTo(100, 100);
createjs.Tween.get(line).to({x: 0, y: 0}, 1000, createjs.Ease.sineInOut);
Nothing happens.
Draw Example:
However if I use this I get the line as expected but it is not animated:
var line = new createjs.Shape();
line.beginStroke('cyan');
line.setStrokeStyle(3);
line.moveTo(100, 100);
line.lineTo(0, 0);
This draws a line as expected.
Is there some way to use the lineTo method with the tweening method I am missing? I have checked the documentation of both Easel and TweenJS and can't find an example or any clear instructions on how to do this or if this is not possible.
Any help is appreciated.
The easiest approach is to use a Graphics command. The .command property returns the last created graphics command, which you can then manipulate with a tween:
var cmd = line.graphics.lineTo(100,100).command;
createjs.Tween.get(cmd).to({x:0}, 1000);
Here's a working example: https://jsfiddle.net/gskinner/17Lk8a9s/1/
Demo: http://jsfiddle.net/thpbr1vt/3/
Attention! Performance.
var stage = new createjs.Stage("canvas");
var vpoint = new createjs.Point( 100, 100);
var line = new createjs.Graphics();
line.beginStroke( 'cyan' );
line.moveTo( vpoint.x, vpoint.y );
var s = new createjs.Shape(line);
stage.addChild(s);
createjs.Tween.get(vpoint).to({x: 0, y: 0}, 1000, createjs.Ease.sineInOut);
createjs.Ticker.addEventListener("tick", tick);
function tick() {
line.lineTo( vpoint.x, vpoint.y );
stage.update();
}

How to flyover a scene in three.js?

I am developing an application to show a property and its elements such as walls, doors, etc. I need to control camera to zoom to specific objects on the scene. However, I need to move camera slowly between objects and not quick movement. I have an example here:
http://interactivebuildings.planning.nsw.gov.au/planning-residential
In this example, when you click an object from the list, camera flies to that object.
How can I do a fly in Three.js?
Thanks.
Its called tweening.
There are a few tweening libraries for JS.
My preferred tweening library is TweenLite or TweenMax by Greensock
To do what I think you want, you would just tween the properties of the camera in your scene.
This what I have used. Works very well using tween.js http://www.createjs.com/#!/TweenJS.
function test () {
var position = {X: 200, Y: 200, Z: 200, lookX: 0, lookY: 0, lookZ: 0};
tween = new TWEEN.Tween(position).to({X: 0, Y: 300, Z: 0, lookX: 0, lookY: 0, lookZ: 0}, 2000);
tween.easing(TWEEN.Easing.Circular.InOut);
tween.onUpdate(function(){
camera.position.set(position.X,position.Y,position.Z);
camera.lookAt( {x:position.lookX, y:position.lookY, z:position.lookZ } );
});
tween.start();
}
test();
animate();
TWEEN.update(time);

Getting the Jcrop coordinates back into Jcrop through javascript variable?

If I set a variable like this:
var coords = jcrop_api.tellSelect();
It returns my current Jcrop selections coordinates in an x,y,x2,y2,h,w format.
Now if I want to set my coordinates back to that, I could go:
jcrop_api.animateTo(coords)
But the animateTo function only takes an array of 4, [x, y, w, h]
When I try to do the above way, it eventually breaks the code.
So how do I change my variable coords to fit this format?
Thanks
The API functions you mention at least at the 0.9.12 version of the plugin..
jcrop_api.tellSelect() returns an object like this:
{
x: 0,
y: 0,
x2: 10,
y2: 10,
w: 10,
h:10
}
and jcrop_api.animateTo needs one array like [x,y,x2,y2], so, try this:
var c = jcrop_api.tellSelect();
jcrop_api.animateTo([c.x,c.y, c.x2, c.y2]);

Positioning A Set in Raphael Paper

Is there any way to group bunch of elements of paper in one set and only position that set in the paper?
For example At This Example I was trying to put some circles in side a rectangle and just position the rectangle in each part of the paper. Can you please let me know how to do it?
var paper = Raphael('my-canvas', 500, 300);
paper.canvas.style.backgroundColor = '#F00';
var rect = paper.rect(5, 5, 100, 100);
var st = paper.set();
st.push(
rect.circle(10, 10, 5),
rect.circle(30, 10, 5));
You can do this via a transform on the set (you could also do it with another attribute like x,y but only if the elements use that specific attribute).
Its worth noting, that although you can apply a transform to the set, it is in effect applying the transform to each element in the set. Ie there is no specific 'set' or 'group' element in Raphael (there is in Snap.svg which is its updated brother, but doesn't quite have the same backwards compatibility). So there is no true hierarchy of groups, where they could have separate transforms which cascade down.
var paper = Raphael('my-canvas', 500, 300);
paper.canvas.style.backgroundColor = '#F00';
var rect = paper.rect(5, 5, 100, 100);
var st = paper.set();
st.push(
paper.rect(5, 5, 100, 100),
paper.circle(10, 10, 5).attr({ fill: 'blue' }),
paper.circle(30, 10, 5).attr({ fill: 'green' })
);
st.transform('t20,20');
st.animate({ transform: 't100,100' }, 2000);
Its worth looking at the Raphael docs for transforms if not sure here
jsfiddle
Instead of using a set, you can create a new div, add a new paper element to this div and then change the position of the div.
If you are using jquery, it could look something like this:
$(".body").append('<div id="setContainer"></div>');
paper = new Raphael(document.getElementById("setContainer"), 500, 300);
paper.canvas.style.backgroundColor = '#F00';
var rect = paper.rect(5, 5, 100, 100);
var circle = paper.circle(10, 10, 5);
var circle2 = paper.circle(30, 10, 5);
// then you can adjust the position of the div, for example to 100,100
$("#setContainer").css("top", 100);
$("#setContainer").css("left", 100);
The advantage of using this approach rather than a set is that it gives you more flexibility for the way you want to manipulate the elements you are grouping together.
You can even wrap a function around this code in order to define the id of the container programatically if you wanted to create several instances of the same group of elements.

Categories

Resources