Right way to rotate things with a mouse in Fabric.js - javascript

This is the example:
http://jsbin.com/UHENoKi/11/
Here I use simple formula to find the angle between two points (vectors):
But as you could see at JSBin - something is broken. Where did I make a mistake?
UPDATE
Working example:
http://jsbin.com/UHENoKi/13/edit?js,output

The angle to rotate by is being calculated based on the 0,0 origin, but the square is rotating around its own center at 100, 100, so they don't match. If you move the square to 0,0, it feels OK:
var rect = new fabric.Rect({
fill: '#00FFAB',
top: 0,
left: 0,
width: 100,
height: 100,
selectable: false
});
Rather than translating to canvas coordinates in toLocal, translate into the coordinate space of the square.

Related

FabricJS - Create rectangle using 4 points (tl,tr, bl, br)?

Creating a rectangle in FabricJs is straightforward using top, left, width and height values.
After moving, scaling and rotating the rectangle around, one can get the rectangle's definitive coordinate using the aCoords of the object, returning bl, br, tl, tr x and y coordinates of the rectangles four edges.
How can one recreate the same rectangle using only these four coordinates, which also include rotation and scaling?
I was only able to recreate the rectangle after it has been moved and scaled, but not with rotations.
This above image is a screenshot of the following jsFiddle: https://jsfiddle.net/7neukojd/32/
As you can see, the left side is the original rectangle (blue), which has been scaled, moved and rotated. The right side rectangle (red) is me, trying to copy it using only the bl, br, tl and tr coordinates.
Thanks to asturur, this issue has been solved with the following code
let rectObj = canvas1.getObjects()[0];
const tl = rectObj.aCoords.tl;
const tr = rectObj.aCoords.tr;
const bl = rectObj.aCoords.bl;
let rectCopy = new fabric.Rect({
left: rectObj.aCoords.tl.x,
top: rectObj.aCoords.tl.y,
width: (new fabric.Point(tl.x, tl.y).distanceFrom(tr)),
height: (new fabric.Point(tl.x, tl.y).distanceFrom(bl)),
angle: fabric.util.radiansToDegrees(Math.atan2(tr.y - tl.y, tr.x - tl.x)),
fill: "red",
})
Source: https://github.com/fabricjs/fabric.js/discussions/6834#discussioncomment-314599

FabricJS clippath border color and move the overlay image behind clippath?

I am trying to add the clippath area(rect object) over canvas using fabricJS. Currently i set Overlay Image to the canvas and in addition to that am adding clippath area to place objects. I successfully able to place the object inside the clippath, but the problem is whatever image i place it inside clippath has opacity(means object also has transparency), i know is because i set transparent image as overlay which is always top over other object.
My query is
Can i set the clippath area alone to ignore overlay? Or atleast to set the preference like clippath is first priority and next overlay?
Currently clippath has no border and i couldn't know where the clippath is? So is there a way to set the border over clippath area?
Here is my below code
HTML
<canvas id="ex8" width="300" height="400"></canvas>
JS
(function () {
var canvas = new fabric.Canvas('ex8');
canvas.controlsAboveOverlay = true;
var clipPath = new fabric.Rect({ width: 100, height: 100, fill: 'red', top: 100, left: 100 });
canvas.setOverlayImage(
'https://i.ibb.co/88QkSMC/crew-front.png',
canvas.renderAll.bind(canvas),
{}
);
var group = new fabric.Group([
new fabric.Rect({ width: 100, height: 100, fill: 'red', globalCompositeOperation: 'xor' }),
new fabric.Rect({ width: 100, height: 100, fill: 'blue', top: 100 }),
new fabric.Rect({ width: 100, height: 100, fill: 'green', left: 100, top: 100 }),
]);
canvas.clipPath = clipPath;
canvas.add(group);
})();
Appreciate your help !!!
FIDDLE
Very interesting question.
The issue you encounter is linked to the order in which layers are being applied in Fabric.js.
As described in a related github post, the layers are applied as follows (from bottom up):
Hence, it's not that the clipPath is put on the T-shirt image (i.e. the Overlay image). It's the opposite, as the T-shirt layer is applied over the clipPath.
While it seems that the "transparency" comes from the clipPath resp. fabric group, it is actually coming from the Overlay image itself as the T-shirt in the image is transparent (the surrounding white background is not).
The opacity of the T-shirt image is also visible when hovering over it with a mouse (e.g. in file explorer as depicted below).
As for the borders, you can add the following to your code:
group.set({
borderColor: 'yellow',
cornerColor: 'yellow',
cornerSize: 6,
transparentCorners: false
});
group.setActiveObject(canvas);
Please note that the borders are only visible when the corresponding canvas item is activated. For more information, you can check this link on customization.

Raphael JS: Changing circle into a another shape using a path

I currently have created a ball bouncing
var ball = paper.circle(700,275,25,25)
var a = 50;
ball.attr({
fill: "180-black-red"
});
In this function the ball bounces to the top. I then tried to make it change shape by doing ball.animate and the path. But this is not working.
function bounce_normal(){
ball.animate({cy: 220, cx: 275}, 500, 'ease-out' );
ball.animate({ path: "M190.5,320.5A20,20,0,1,1,190.1,320.5Z"});
}
I also tried to remove the cy and cx values however it still doesn't change shape. Is there a way to solve this?
Update
I now learnt I need to use a path for by ball.
var ball = paper.path("M190.5,320.5A20,20,0,1,1,190.1,320.5Z")
var a = 50;
ball.attr({
fill: "180-black-red"
});
Is there anyway of learning what that path means so i can animate the pathm ie: making it bounce ?

Animation text in a snake way with canvas

I find this website -> http://bit.ly/1FCtQSQ and he has this animation scroll, which I am not interested, however in the middle of the scroll animation, a text snake animation appears. I want very badly to know how I can do this, just to learn.
I researched all plugins that curve texts, such as:
Arctext.js
CircleType
This one
Also, i tried 'still' the code from http://bit.ly/1FCtQSQ, but is minified, i know this guys are using the timelinemax, which uses the canvas, i tried to copy the code, but didn't work, as you can see here in the bottom of this question.
So i came here as the last resource.
Could someone give me an explanation with a working example, or maybe a plugin which i can study the code?
I know this is not the best way to find a answer to my question, but i don't have money to pay for codementor, hackhands, airpair or something like this.
Thanks!
Pen: http://codepen.io/anon/pen/GJjjxG
Code that i copy:
<h1 class="snake">Animate this like a snake!</h1>
var animation = new TimelineMax({
paused: !0,
ease: Linear.easeNone
});
var T = 0;
var f = 30;
animation.add(
TweenMax.to(e(".snake").parent(), f, {
left: -5e3
}), T);
Thanks.
The KonvaJS (formerly KineticJS) canvas library has some nice text-along-path code with a liberal MIT license:
https://github.com/konvajs/konva/blob/f6e2cf19a30dec2f94f50152f20c35988b1bf99e/src/plugins/TextPath.js
The KonvaJS TextPath code works like this:
Start with a path made up of curves and lines defined using the same syntax that SVG uses to define path.
Calculate waypoints along that path.
Fit characters one-by-one along the path using the calculated waypoints.
Use transformations to position the characters properly. (using context.translate & context.rotate to match the letter to the angle of the path / curve.)
You can cause the text to animate along the curve by beginning the text further & further beyond the first waypoint on the curve.
Example code using the KonvaJS libarary:
var stage = new Konva.Stage({
container: 'container',
width: 1000,
height: 1000
});
var layer = new Konva.Layer();
// add the layer to the stage
stage.add(layer);
var textpath = new Konva.TextPath({
x: 0,
y: 50,
fill: '#333',
fontSize: 16,
fontFamily: 'Arial',
text: 'Now is the time for all good men to come to the aid of their party -- An phrase from an old touch-typing test.',
data: 'M 100 200 C 200 100 300 0 400 100 C 500 200 600 300 700 200 C 800 100 900 100 900 100'
});
layer.add(textpath);
layer.draw();
body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #F0F0F0;
}
<script src="https://cdn.rawgit.com/konvajs/konva/0.9.0/konva.min.js"></script>
<div id="container"></div>

In Raphael SVG, does translating a path mean "move the center" not "move the origin"?

Here's the code:
Raphael('holder', 400, 400, function() {
this.circle(200, 200, 100)
this.circle(200, 200, 140)
this.circle(0, 0, 1).translate(300, 200).scale(10).attr({fill: 'green'})
this.circle(300, 200, 5).attr({fill: 'red'})
this.path('M300,200 L400, 200').attr({stroke: 'red', 'stroke-width': 3})
this.path('M0,0 L1,0').attr({stroke: 'blue'}).translate(300, 200).scale(100, 100)
})
Here's the result in Chrome:
Notice that the blue line's M0 0 is not at 300,200!
What I expect is that the two paths would be coincident. When I translate(300, 200) I expect that M0, 0 will place the pen at 300,200. But it doesnt! It places the pen somewhere else such that the center of the resulting path winds up at 300,200.
So, how can I make a path and position it's M0 0 absolutely within the paper?
(Or, do I have to compute the center of my path and offset all the path values by that center? Please do not say "yes")
Your problem is that you use .scale(100, 100) on your blue line which resizes the whole line horizontally in both directions FROM the center point of (300, 200);
Simply exchange your last line with:
this.path('M0,0 L100,0').attr({stroke: 'blue'}).translate(300, 200);
to have the blue line cover the red one
Here is a fiddle for the solution: http://jsfiddle.net/QfAsY/
You can scale with a center, so scale(100, 100, 0, 0) is the solution.

Categories