Rotate svg path around its centre d3 - javascript

I have a simple cog wheel drawn in illustrator. I've placed the svg markup in the index page and all is well. I can access it by its id.
The code below is part of a function that is executed on that time period so I don't need to worry about the time element.
I've looked around and am not understanding the examples I've found. This is what I have:
var motor=d3.select('#wheel')
motor.attr('transform', 'rotate(0, 0, 2)');
I want to rotate a couple of degrees every 300 milliseconds.

Your original code doesn't seem very functional (the commas in rotate are not needed). So taking those out, your statement is asking the svg to rotate by 0 degrees around the x, y coordinates 0, 2 (2 pixels down from the top-left corner). What you want is closer to:
var motor=d3.select('#wheel')
motor.attr('transform', 'rotate(2 ' + (objectwidth / 2) + ' ' + (objectHeight/2) + ')');

Related

Setting the correct transform-orign x and y value for a rotated element

In JavaScript/jQuery, if we wanted to rotate an element around an origin point defined by the click point, you could do this:
var angle = 0;
$('#myElement').on('click', function(event) {
const ELEMENT_X = event.pageX - $(this).offset().left;
const ELEMENT_Y = event.pageY - $(this).offset().top;
angle +=10;
$(this).css('transform-origin', ELEMENT_X + 'px ' + ELEMENT_Y + 'px');
$(this).css('transform', 'rotate(' + angle + 'deg)');
});
So it works as planned on the first click because the element is not in a rotated state. After the first rotation, the ELEMENT_X AND ELEMENT_Y are not set correctly obviously, which causes the origin point to be incorrect. Is there a formula we can apply that would find the correct x and y values to set on a click point for the CSS transform-orign property based on the current angle of the element?
I'm not too sure if this article is the same as mine: How we can calculate the correct x and y value for the rotated image?
This thing is driving me nuts. I made a JSFiddle:
https://jsfiddle.net/f251qL98/
The goal here is to make the element rotate around any point within the element that we click on. By default, the origin point is set at the center of the element. The first click works fine, but subsequent ones, the element rotates around the incorrect origin point.
But if we click on another part of the element, I'm not too sure where the origin would be located, especially if the object has been rotated. I'm sure it is some math triangle manipulation solution, but that is not my strong side. Anyhow, back to testing all try to test more possibilities.

How to move to another position and " animate " a circle in Raphael js

I have created a dot as a small circle and wanted to animate to see how it works it moving from the x : 300, y : 390 , r: 5 to 300, 130 . I have searched on the web how to animate a circle and found more about how to animate the RADIUS of it, but is not what I need. I want the same radius dot to move from one point to the otherone. I found some things about along the path / " .animateAlong()" . Is this what i need ? Which are the attribute this " along the path are expecting ?
I want the circle to move animate once the code runs. Don't want to change the position by mouse listening.
Would appreciate some clarity about it , if possible a simple code example for me to see how does it works.
You just need to set the respective attribute you want to animate, in this case cx & cy (cx, cy is center for circle, rects have x,y).
myCircleElement.animate({ cy: 150 }, 2000);

Concurrency transitions in D3 (circle following filling path)

I am trying to create simple animated gauge charts, with red points on the end of each circle. Whole example is in here https://jsfiddle.net/yhLch8fc/3/ (please do not solve text position, it's not a problem). I tried to search on stack overflow, but tutorials like Change starting point of alongPath animation are not helping me, because my path is translated by X,Y and rotated. I thing the key part of code is:
circle.transition().duration(_duration)
.attrTween('cx', arcCircleX(_myPath.node()))
.attrTween('cy', arcCircleY(_myPath.node()));
you can easy switch to similar version (code from stack overflow above):
circle.transition().duration(_duration)
.attrTween('transformation', circleTween(_myPath.node()));
I don't know why, but it seems the red circle goes to the left side. Maybe it's because the original path is translated and rotated.
(The original version was, when I try to follow filling path, but it does not work either.)
Instead of rotating the hover path, rotate the g element that contains both the path and the circle:
enter.append("g").attr("class", "hover")
.attr("transform", "translate(" + _width / 2 + "," + _width / 2 + "), rotate(-90)");
Then:
circle.transition().duration(_duration)
.attrTween('transform', circleTween(_myPath.node()));
Here's an example. Is that what you were after?

Linear/Incremental rotation animation with transition

I'm trying to get a SVG shape to rotate using the transform attribute and the transition method in D3. Here is the jsfiddle containing an example: http://jsfiddle.net/TJd2a/
I'm using two buttons, Left and Right, to rotate the rectangle by incrementing by its angle by 45 or -45 degrees. When the shape reaches either 180 or -180 degrees, the transition rotates the shape the opposite way, rather than moving linearly to the next angle. Using console logging, I've found there is nothing wrong with the angles that my code is generating. It appears to be how D3 is dealing the transition, as the generated XML does not show the same angle as the current (eg. when at 225 degrees, D3 gives the rectangle a rotation of -135 instead).
From what I've read and understand from the documentation, I need to use a custom Tween, but I 'm not sure where to start with a custom tween as I cannot find any examples specific or similar examples to help me understand how it works.
Correct; you can use a custom tween to change the interpolator. D3 has a special interpolator for transforms, but it's not doing the right thing in your case. (I think that's probably a bug which should be fixed, so I filed issue 661.) Here's an example using interpolateString instead:
d3.select("rect").transition().attrTween("transform", function(d) {
return d3.interpolateString(
"rotate("+ d.a +")",
"rotate(" + (d.a += 45) + ")"
);
});

Calculate new width when skewing in canvas

I'm using canvas for a project and I have a number of elements that I'm skewing. I'm only skewing on the y value and just want to know what the new width of the image is after skewing (so I can align it with another canvas element). Check out the code below to see what I mean
ctx.save();
//skew the context
ctx.transform(1,0,1.3,0,0,0);
//draw two images with different heights/widths
ctx.drawImage(image,0,0,42,60);
ctx.drawImage(image,0,0,32,25);
The goal would be to know that the 42 by 60 image was now a X by 60 image so I could do some translating before drawing it at 0,0. It's easy enough to measure each image individually, but I have different skew values and heights/widths throughout the project that need to be align. Currently I use this code (works decently for images between 25 and 42 widths):
var skewModifier = imageWidth*(8/6)+(19/3);
var skewAmount = 1.3; //this is dynamic in my app
var width = (skewModifier*skewAmount)+imageWidth;
As images get wider though this formula quickly falls apart (I think it's a sloping formula not a straight value like this one). Any ideas on what canvas does for skews?
You should be able to derive it mathematically. I believe:
Math.atan(skewAmount) is the angle, in radians, that something is skewed with respect to the origin.
So 1.3 would skew the object by 0.915 radians or 52 degrees.
So here's a red unskewed object next to the same object skewed (painted green). So you have a right triangle:
We know the origin angle (0.915 rads) and we know the adjacent side length, which is 60 and 25 for your two images. (red's height).
The hypotenuse is the long side thats being skewed.
And the opposite side is the triangle bottom - how much its been skewed!
Tangent gets us opposite / adjacent if I recall, so for the first one:
tan(0.915) = opposite / 60, solving for the opposite in JavaScript code we have:
opposite = Math.tan(0.915)*60
So the bottom side of the skewed object starts about 77 pixels away from the origin. Lets check our work in the canvas:
http://jsfiddle.net/LBzUt/
Looks good to me!
The triangle in question of course is the canvas origin, that black dot I painted, and the bottom-left of the red rectangle, which is the original position that we're searching for before skewing.
That was a bit of a haphazard explanation. Any questions?
Taking Simon's fiddle example one step further, so you can simply enter the degrees:
Here's the fiddle
http://jsfiddle.net/LBzUt/33/

Categories