Raphael js: Scale and translate elements in a set proportionally - javascript

It seems that if you scale a set in raphael, it will scale the elements inside, but not translate them proportionally. So for instance if I have two squares next to each other in my set, and I scale the set up, the squares begin overlapping each other instead of the second square moving over as it resizes in order to stay right next to the first square. Is there a way to get this behavior in raphael?

As Ian mentioned, the key is to set the X,Y origin for the scale. By default, when you scale an element, it uses the geometric center of the element as the origin to scale from:
path.transform('S1.5'); // Scale 1.5x in both axis
So if you scale a set of objects, it will scale each individual element from it's own individual geometric center.
But you can optionally set an X and Y origin for the scale:
path.transform('S1.5,1.5,0,0'); // Scale 1.5 in X and 1.5 in Y, with origin set at the Paper's 0,0 as the origin.
Therefore, if you have a set of elements, and all of them are scaled using the Paper's 0,0 as their scale origin, then they will all scale proportionally to each other.

Related

Getting the coordinates of a point inside an overlapping rectangle

I have two colored rectangles, both being represented by a 2D array that directly corresponds to their coordinates(ex. [0][0] is the same as (0,0)). Things such as the width, height, and origin of each rectangle are known.
As of now, I want their colors to "blend" in the area they intersect. Detecting if a point is within both rectangles is easy enough, and I have the point's coordinates relative to the origin of my first rectangle as it is the one I am iterating through for color blend checking.
My problem is getting the point's coordinates relative to the second rectangle so I may get that rectangle's color at that point. Here is a visual example of what I mean.
Visual representation of the problem. The black dot is a point on both Rect 1 and 2.
Note that relative to the canvas, the top left corner of Rect 1 is always considered (0,0), and Rect 2 will always appear "on top" of Rect 1.
My idea is to do a simple math equation to get the X and Y coordinates of the point on Rect 2, but so far it has not worked out.

is there any way to draw canvas images with relative positioning

I was trying to have a wheel on a canvas with multiple equal size segments similar to wheel of fortune. On the circumference of the wheel, i.e arc of each segment, I want to have an image attached that needs to rotate with wheel.
I was able to draw multiple images, but they have be positioned with respect to (0, 0) (top-left) of the canvas only. Is there any way to position them relative to some point instead of the origin? In my case the centre of the circle (300, 300)?
You can translate the origin of your canvas by calling .translate(x, y) method of the canvas drawing context; in your example both x and y would be 300.
See https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations for more information on canvas transformations.

Trig / javascript to calculate padding required to accommodate image rotation without clipping

I have a known rect (grey) the outer parent element that contains an image element (orange). It's overflow is hidden.
I want to calculate the padding required to allow the image element(known width and height) to be rotated to a known angle (for this e.g. lets say 30 degrees).
It has proven to be relatively easy to calculate this if i were able to allow the parent(grey) element to expand to accommodate, but i can't.
create list of 4 image edge points p0,p1,p2,p3
rotate them the same way as the image will be rotated
double a=x-x0,b=y-y0,c,s;
c=cos(alfa);
s=sin(alfa);
x=a*c-b*s+x0;
y=a*s+b*c+y0;
x,y is the point
x0,y0 is center of rotation
alfa is the rotation angle
compute min,max of rotated points x,y coordinates this gets you the bounding box
summary
let (x0,y0) be the original image gray box size (X,Y) from your image
let (x1,y1) be the original image size (xa,xb) from your image
let (x2,y2) be the rotated image bounding box size (xmax-xmin,ymax-ymin) from bullet 3
if ((x2<=x0)&&(y2<=y0)) the image fits so stop
let mx=x0/x2 and my=y0/y2 be the needed scales to fit the image
do not zoom:
if (mx>1.0) mx=1.0;
if (my>1.0) my=1.0;
now select the correct scale m
m=mx; if (m>my) m=my;
now the m holds the scale needed to apply on rotated image to fit the gray area
do not forget to center the image ...

Velocity.js - rotation around center

I'm using Velocity.js for animation.
What's the proper way to move an SVG image, while rotating it around the center at the same time?
You do not need to do per frame animation if you can define the motion using combination of rotations and linear movements.
As it comes out, your issue is that you are not able to fully manage the origin of rotation.
NOTE : The following is applicable to not only velocity but all css transformations in general.
The origin of rotation is the top-left corner of the item to be rotated
Now, if you want to move the object without moving the origin, you can use the translateX, translateY properties. eg
.velocity({ translateX: "+=200", translateY: "25%"})
In order to move the object as well as the origin, you need to set or move its x and y position parameters. eg
.velocity({ x: "+=200", y: "25%" })
Rotation around center
As an example, if you want to rotate an object on its center,you need to
Translate the object by -w/2 and -h/2 where the width and height is w and h.
Rotate the object
Rotation around an external point
In case where you need to rotate the object around an item, simply first translate the object away from its origin by a suitable distance and then rotate it.
This PEN shows both examples where the green rectangle is rotated around its center and the blue one around an external point by combining translation and position correctly.
Velocity.js uses CSS transforms to do it's rotation. Because of this, all you actually need to do is set transform-origin: center; in your CSS. This changes the point around which all actions will happen.
Trying to match the rotational movement and shifting your X and Y accordingly will be a slower animation and more prone to bugs.
More information about transform-origin can be found here.

KineticJS - Rescaling images/shapes after zoom

So basically I have an application which zooms in by scaling every layer and adjusting the position of the layers. However I have a bunch of circles (and images) on some layers which I need to keep the size the same regardless of the zoom level (ie regardless of the scale of the layer).
Is there a way to set the scale of every shape/image in a layer without iteration? I've looked at using a Group but there is no universal way to set a universal scale.
If not, would there be an efficient way to do this without iteration?
Put the non-scaling objects in a separate group and then rescale (and optionally reposition) that group based on the scaling factor of the groups layer.
Demo: http://jsfiddle.net/m1erickson/2X7eK/
var scaleFactor=2;
// scale the entire layer by 2X
layer.setScale(scaleFactor);
// unscale just the noGroup back to original size
noGroup.setScale(1/scaleFactor);
// reposition just the noGroup back to it's original position
// before the layer was resized
noGroup.setPosition(noGroup.getX()/scaleFactor,noGroup.getY()/scaleFactor);

Categories