Raphael JS - Rotate whole set resulting in weird rotation - javascript

[EDITED because I made progress]
I have this wheel with text that spans linearly.
Here's the JS Fiddle to show the visual and my code:
http://jsfiddle.net/DarcFiddle/F3gsD/10/
So I create a set:
paper.setStart();
// draw draw draw
var set = paper.setFinish();
Then here's a method to rotate it:
var degree = 0;
function rotateSet() {
degree = degree + 90;
set.animate({ transform: ["R", degree, canvasCenter, canvasCenter]}, 500 );
}
You can try this by clicking the "Rotate" button from the JSFiddle.
But as you can see, the element also rotate on its own center, which break the structure.
What can I do to prevent this?
Thanks

I did it with double rotation
http://jsfiddle.net/DarcFiddle/F3gsD/12/
So, I loop the set and do two r transformation. First one is the center of the circle and second one is rotate back only the text as suggested by Ian in the comment above.
set.forEach(function(e) {
var textDegree = Math.round( Raphael.angle(e.attr("x"), e.attr("y"), x, y) );
if(e.attr("text-anchor") === "end") {
textDegree = textDegree - 180;
}
e.animate({
transform: ["r", degree, x, y, "r", textDegree, e.attr("x"), e.attr("y")]
}, 500);
});

Related

How to make the background change color smoothly in rainbow style?

I'm using P5.js library and I want to make the background of the canvas change color in rainbow style smoothly and continuously.
How can I do this? Thanks a lot in advance
Something like this
You could use the HSB colorMode. This allows you to basically "cycle" through the color wheel by using numbers from 0 to 360 (ie specify a degree on the color wheel). Using this idea, you can draw many rectangles on your canvas, spanning from the top of the canvas to the bottom (amount of rectangle specified by inc). Each rectangle will have a particular color.
Thus, joining all these rectangles will allow you to create a gradient-like effect.
By continuously providing an offset to your color (and restricting it within the bounds or 0 to 360) you can cycle through the color wheel.
See code below:
function setup() {
createCanvas(400, 400);
}
let cOffset = 0;
function draw() {
const inc = height/100;
colorMode(HSB);
for(let y = 0; y < height; y += inc) {
let h = y / height * 360;
fill(abs(h-cOffset)%360, 100, 100);
noStroke();
rect(0, y-inc, width, y);
}
cOffset += 5;
}
See working version here:
https://editor.p5js.org/NickParsons/sketches/1xfjY-ZoE

How to rotate one object at another (slowly)

I have been looking around for this function and thus far I just can't find any I can make any sense of. I already have a rotating function to make it equal to the position but slowly is proving to be a bit harder with 0-360 and all.
I am using a html canvas 2d context to render the objects on a Cartesian coordinate system .
I would like object1 to face at positionX and positionY at a turn rate (R) , fairly straightforward.
there is no need for me to supply any code since your likely going to make your own anyways. But I will anyways here you go:
let faceAt = function (thisObject,positionX,positionY) {
let desiredLocationX = positionX - thisObject.transform.x;
let desiredLocationY = positionY -thisObject.transform.y;
thisObject.transform.rotation = Math.degrees(Math.atan2(desiredLocationY, desiredLocationX));
};
The (Math.degrees) function converts radians to degrees.
This thread says it all : https://www.google.ca/amp/s/jibransyed.wordpress.com/2013/09/05/game-maker-gradually-rotating-an-object-towards-a-target/amp/
This question is quite unclear. But, I'm assuming you essentially just want to rotate an element around an arbitrary point on a HTML5 canvas.
On a canvas, you can only draw one element at a time. You can't really manipulate singular elements - for example, you can't rotate an element by itself. Instead, you'd need to rotate the entire canvas. This will always rotate around the centre of the canvas, but if you move the canvas origin, then you will draw on a different part of the canvas; thus allowing you to rotate around a point.
Check out the following example. You can click anywhere on the canvas to make the square rotate around that point. Hopefully this is what you are after:
let cv = document.getElementById("cv");
let ctx = cv.getContext("2d");
let angle = 0;
//Variables you can change:
let speed = 1; //Degrees to rotate per frame
let pointX = 250; //The x-coord to rotate around
let pointY = 250; //The y-coord to rotate around
ctx.fillStyle = "#000";
setInterval(()=>{ //This code runs every 40ms; so that the animation looks smooth
angle = (angle + speed) % 360; //Increment the angle. Bigger changes here mean that the element will rotate faster. If we go over 360deg, reset back to 0.
ctx.clearRect(0, 0, 400, 400); //Clear away the previous frame.
//Draw the point we are rotating around
ctx.beginPath();
ctx.arc(pointX,pointY,5,0,2*Math.PI);
ctx.fill();
ctx.closePath();
ctx.save(); //Save the state before we transform and rotate the canvas; so we can go back to the unrotated canvas for the next frame
ctx.translate(pointX, pointY); //Move the origin (0, 0) point of the canvas to the point to rotate around. The canvas always rotates around the origin; so this will allow us to rotate around that point
ctx.rotate(angle*Math.PI/180); //Rotate the canvas by the current angle. You can use your Math.degrees function to convert between rads / degs here.
ctx.fillStyle = "#f00"; //Draw in red. This is also restored when ctx.restore() is called; hence the point will always be black; and the square will always be red.
ctx.fillRect(0, 0, 50, 50); //Draw the item we want rotated. You can draw anything here; I just draw a square.
ctx.restore(); //Restore the canvas state
}, 40);
//Boring event handler stuff
//Move the point to where the user clicked
//Not too robust; relys on the body padding not changing
//Really just for the demo
cv.addEventListener("click", (event)=>{
pointX = event.clientX - 10;
pointY = event.clientY - 10;
});
#cv {
border:solid 1px #000; /*Just so we can see the bounds of the canvas*/
padding:0;
margin:0;
}
body {
padding:10px;
margin:0;
}
<canvas id="cv" width="400" height="400"></canvas><br>
Click on the canvas above to make the rectangle rotate around the point that was clicked.

Rotating an ellipse about a specific axis

I know that the the default rotation in javascript canvas method rotates the image about the Z axis.
Is there a way to show an ellipse about the Y and X axis?
I want something similar to this:
Thank you very much
Something like this is what you're after.
Keep in mind, this is mostly pseudo-code!
var width = 24;
var direction = -1;
function draw() {
// Draw a circle
stroke(50);
fill(100);
ellipse(x, y, width, 24);
width = width + direction; // direction is either 1 or -1
// flip direction
if (Math.abs(width) > 24) {
direction *= -1;
}
}

Three.js Points Rotation

I'm working on a particle system project. I want to add a little delay to my Points Object rotation in three.js. I'm currently using D3.js linear scale which gives 1:1 rotation. For example, if you quickly move your cursor all the way to right, my Points Object will match your cursor movement speed. What I want is to ease in the rotation so the rotation would finish ~1sec after you move your cursor all the way to the right. Here is my current code.
var rotYScale = d3.scale.linear().domain([0, window.innerWidth]).range([25,-25]);
var rotXScale = d3.scale.linear().domain([0, window.innerHeight]).range([15,-15]);
d3.select("body").on("mousemove", function() {
particleSystem.rotation.y = rotYScale(d3.mouse(this)[0]) * Math.PI / 180;
particleSystem.rotation.x = rotXScale(d3.mouse(this)[1]) * Math.PI / 180;
});`
I got it to work by using Tween.js. This is the code I added.
var tween = new TWEEN.Tween(particleSystem.rotation).to({ x: scaledX, y: scaledY, z: 0})
tween.easing( TWEEN.Easing.Quadratic.Out)
tween.start();

jQuery Circles animation on circle path

I'm trying to make big circle and move divs along the circle's circumference.
Each div must change the content inside the big circle.
The number of div(s) must be dependent on how many are fetched from database (from table category).
I tried to do this and modified the code by putting .eq() but the problem with .eq is that next circle will appear after that circle, all put in the same place. I want them all to appear at the same time like this without repeating functions
Updated your fiddle:
http://jsfiddle.net/wyW2D/1/
Used:
var t = -1.6;
var t2 = -1.6;
var x = 0;
var t = [-1.6, -1.6, -1.6], // starting angle in radians for each circle
delta = [0.05, 0.03, 0.02], // change in radians for each circle
// e.g the first moves fastest, the last
// slowest. if this gets too big, the
// movement won't look circular, since the
// animation is really a bunch of straight lines
finish = [1.4, 1.0, 0.6]; // the stopping point in radians for each
// circle. if the circle size changes, this
// may need to change
function moveit(i) {
t[i] += delta[i]; // move the angle forward by delta
var r = 300; // radius (the .inner div is 600 x 600)
var xcenter = -30; // center X position: this reproduces the .inner horizontal
// center but from the body element
var ycenter = 420; // center Y position: same here but vertical
// Basic trig, these use sin/cos to find the vert and horiz offset for a given
// angle from the center (t[i]) and a given radius (r)
var newLeft = Math.floor(xcenter + (r * Math.cos(t[i])));
var newTop = Math.floor(ycenter + (r * Math.sin(t[i])));
// Now animate to the new top and left, over 1ms, and when complete call
// the move function again if t[i] hasn't reached the finish.
$('div.circle'+(i+1)).animate({
top: newTop,
left: newLeft,
},1, function() {
if (t[i] < finish[i]) moveit(i);
});
// You can slow down the animation by increasing the 1, but that will eventually
// make it choppy. This plays opposite the delta.
}
// Start the ball rolling
$("document").ready(function(e) {
moveit(0);
moveit(1);
moveit(2);
});
This was a quick change to reduce the code to one function that used arrays (t, delta, finish) to keep track of the three circles. It could be improved to accept arbitrary circles, of any size, at any starting / ending angle.
Also, this kind of animation is much easier with CSS. It is simple to specify and has much better performance.

Categories