SVG Rotate Element While Animating svgjs - javascript

I'm using Javascript, Jquery, SVG, and SVG.js right now. I would like to rotate a circle about its origin while it's animating. The animation is doing the same thing, so I could use some sort of step function but I couldn't find anything. The problem is that with my current solution the animation is janky, it has to stop the animation, rotate the circle, and then start it again. Which in sequence has too much of a delay and causes a wiggling motion. Here's the setup code:
var draw = SVG('svg');
var innerCircle = draw.group().addClass("atom0g0").move(100,100);
innerCircle.circle(100).addClass("atom0p0").center(0, 0).attr({ fill: "white", stroke: "blue", "stroke-dasharray": "10" });
innerCircle.animate(6000).rotate(360, 0, 0).loop();
And the executing code right now, which I need to change to something is here:
var elms = $(".atom"+atom.atom_id.toString()+"g0");
for (var j=0; j < elms.length; j++) {
// this is the problem, too much of a delay, therefore causing a wiggle motion.
elms[j].instance.animate().stop();
elms[j].instance.rotate(step, 0, 0);
elms[j].instance.animate(6000).rotate(360, 0, 0).loop();
}
Here's the CodePen that I'm working on right now to make it: Current Version or Bugged Version
In short (if you just skipped to the end here) I need to rotate a circle without stopping the animation of the circle completely. I know that play(), pause() doesn't work because I can't call rotate() while the animations paused.

Accepted answer:
Try to wrap your element with one more element and animate them separately.
One of the solutions is to change this line:
elms[j].instance.rotate(Math.random()*360, 0, 0);
into that:
elms[j].instance.animate(1000).rotate(Math.random()*360, 0, 0);
This way rotation will be animated.
Codepen: https://codepen.io/soentio/pen/POVLYV
Other of the possible solutions i to utilise css for your transitions. By adding following line:
#svg > g {
transition: transform 1s ease-in-out;
}
you make sure that whenever a group (that is direct children of your svg root node) is rotated, it's gonna be animated smoothly.
CodePen: https://codepen.io/soentio/pen/gXqqNQ
Advantage of this approach is that whatever your rotation is, browser picks the shortest path.
Bonus:
I believe in superiority od css animations ( ;-) ) and inspired by your code made you a little codepen fiddle: https://codepen.io/soentio/pen/YEBgyj
Maybe your goals are to be achieved with css only?

Related

How to tween a line color in easeljs canvas

I have a series of dots with connected lines that I am animating in an easel.js canvas. The dots move around, and the lines stay connected to them as they move. As the dots move, I'm animating their color, so I want the lines to animate color as well.
I tried calling a color tween on the line, but it requires that I cache the line first.
For a circle, that's easy - I get the radius and, since its registration is in the center, its x and y coordinates and width and height are easy to calculate (for a circle with r=100 at 50,50, its cache would be cache(0,0,100,100). But for a line, I'm not sure how to reference the right coordinates for the cache statement, especially since the line start position, end position, and length are always changing.
Anyone have a way to do this?
I'm using greensock's timelinemax / tweenlite with the easeljs plugin to handle all the animations, if that's helpful.
If TweenLite handles color tweens, then you should just be able to update the "style" of your line any time:
var shape = new createjs.Shape();
var colorCommand = shape.graphics.beginStroke("#000000").command;
shape.graphics.moveTo(0,0).lineTo(100,100); // Draw the line
// Any time
colorCommand.style = "#ff0000";
// So in a tween:
TweenLite.to(colorCommand, 20, {style:"#00ffff"});
If you are using EaselJS, you can also use TweenJS, which has a ColorPlugin. Using similar code:
createjs.Tween.get(colorCommand).to({style:"#00fffff"}, 20000);
Here is a fiddle I made tweening the color of a line with TweenJS https://jsfiddle.net/lannymcnie/5zxpb944/
Cheers.

Changing opacity on Mouseover

The ultimate goal of my project is to make my image of circle chart interactive on mouseovers. I want the pieces of the circle to change opacity to .5 (from 1) when the user hovers them. I have an image of the chart but I'm not sure how to make areas of one single image change opacity on hover. I have tried several things:
I image mapped the chart with each piece in its own map, but I wasn't sure how to change opacity of an area of one single image (css)(if its even possible)
My second approach was that i sliced the chart up into individual pieces and made their opacity .5 and saved them all separately. Then, I image mapped the single image of the chart and tried to load the individual piece on hover (css)
My final approach was saving each piece of the chart as individual images and when the image is hovered, change the opacity to .5 with css. This works perfectly except i am not sure how to position the pieces to form a perfect circle in dreamweaver.
Any direction or advise is greatly appreciated. I am willing to learn javascript or jquery to help get this done.
Thank you
EDIT Image of the chart is now attached
http://i.stack.imgur.com/KwIfY.jpg
I'm not sure if I understood the question right regarding the current answers but if you want to make the parts of the chart interactive I have 2 approaches:
To achieve the effect with pure CSS I guess you need to divide the chart in individual images as you already mentioned. The positioning is quite simple. I've used in my demo below one image an let it rotate. In your case you can cut each part of the chart individually and get the right place for them with absolute positionig.
Again as you already mentioned you can use map area to define the parts of the chart. With a plugin like this: ImageMapster you can achieve what you want. I've used this once for the following map. It's again very simple, when hovering any part of the map it's background will be replaced by another background. In your case you could save the chart with full opacity and display on hover an image of the chart with 50% opacity.
Demo
The Demo is not very clean as I didn't spent much time in position the parts perfectly but you can see how it works.
transform: rotate(45deg);
I don't know if CSS3 transition will fit to you:
http://www.w3schools.com/css/css3_transitions.asp
.chart-item { opacity: 0.5; transition:opacity 2s; }
.chart-item:hover { opacity: 1; }
Check documentation for browser support.
Maybe create a div and put each image as the background or content of one div (in order), then create a listener for the div class to change opacity upon mouseenter or mouseleave using jQuery.
Here's a simple example (pardon any mistakes):
jQuery:
$( ".somedivclass" )
.mouseenter(function() {
$(this).fadeTo(200, 0.5);
})
.mouseleave(function() {
$(this).fadeTo(200, 1);
});
Here's more info on $.mouseenter(). Here's some for $.fadeTo().
Check this demo. Hover your cursor exactly on the eyes of the owl, and you will see the opacity changing. It will not change if you hover on the rest of the image.
http://jsfiddle.net/q6d57/14/
$('.eye1').on('mouseenter mouseleave', function(e) {
$('.box2').stop(true, false).fadeToggle(1500)
});
I suggest using svg. Here is an implementation of exactly what you are trying to do, because I felt like learning d3.js today:
http://jsfiddle.net/6m26k/1/
You don't need to make the chart through code though, because you can just load the svg onto the page with html5 and use css similar to mine:
.arc.filled:hover {
opacity: .8;
cursor: pointer;
}

RaphaelJS with rgba gradient fill

I am trying to create a gradient fill with RaphaelJS that uses rgba colors. In other words, I want both the start and end points to have a degree of transparency. For instance, 20% black to 0% black. How is this done?
This fiddle is how I expect that this would be accomplished but as you can see, the bottom black is completely opaque. http://jsfiddle.net/4aPj2/
r.circle(50,50,50).attr({fill:'90-rgba(0,0,0,0)-rgba(0,0,0,0.2)',opacity:0})
Ok,
previous answer is a red herring for anyone looking at this question. I just spent half a day digging around through the raphaeljs source code. It's not this simple. So Raphaeljs actually already has some built in support for this and anything you try to modify like above won't work as the built in support will override it later.
The support that Raphaeljs currently has allows you to set the transparency of the final color-stop using the opacity attribute and the fill-opacity, so for example this:
r.circle(50,50,50).attr({fill:'90-#000000-#0000ff',opacity:0})
would translate in the real world to a circle with 100% opacity in the first color stop(black) in the center and 0% opacity in the final stop(blue). Another example :
r.circle(50,50,50).attr({fill:'90-#000000-#ffffff',opacity:0.5})
would produce a real world circle with 100% opacity black in the center and 50% white opacity around the outer of the circle on the final stop.
There is no current way in Raphaeljs to support different opacities on both color stops but if you desperately needed to do this this source line you would need to modify would be here :
$(stops[stops.length - 1], {"stop-opacity": value});
It's located at 6265 in the current version of Raphaeljs (2.1.0).
I hope this helps someone avoid the hours of debugging RaphealJS source code I just spent....
There is a workaround, but that involves editing raphael.js
Locate the code block:
el.appendChild($("stop", {
offset: dots[i].offset ? dots[i].offset : i ? "100%" : "0%",
"stop-color": dots[i].color || "#fff"
}));
And replace it using:
el.appendChild($("stop", {
offset: dots[i].offset ? dots[i].offset : i ? "100%" : "0%",
"stop-color": dots[i].color || "#fff",
"stop-opacity": R.is(dots[i].opacity, "undefined") ? 1 : dots[i].opacity
}));
Update: Later figured out that I had accidentally missed a one-line change from my patch.
Next, locate the following line within the function R._parseDots
par[2] && (dot.offset = par[2] + "%");
and replace it with
dot.opacity = dot.color.opacity;
par[2] && (dot.offset = par[2] + "%");
With the above code, you can easily use something like myRect.attr("fill", "90-rgba(255,0,0,0.25)-rgba(0,255,0,0.75)-rgba(0,0,255,0.25)"); But note that the solution is for SVG output, VML does not support this. VML only supports a single opacity on gradient at 0% position and optionally a second opacity for the last opacity at 100% position. There would be a few more code changes for VML that I am not including here.
The code can be seen in action in the fiddle http://jsfiddle.net/shamasis/SYdJW/

How to create an animation sequence using RaphaelJS

so here is my question
I am using RaphaelJS to build an animation in the HTML5 canvas, the thing is I don't quite understand how do I create the animation events and how do I trigger them. The documentation isn't very helpful. Thanks
Firstly as pointed out you aren't utilising HTML5 Canvas, raphael actually uses SVG. Creating animations with raphaelJS is actually quite easy. You can just adapt the line bellow to your needs.
raphaelObject.animate({ attribute: value } , time , easing );
The raphaelObject is what you are trying to animate e.g. a shape you made earlier
attribute is what you are animating e.g. color
value is what you are changing it to e.g. "red"
time is how long the animation should take (milliseconds)
easing describes the nature of the animation, to start with use "<>" which performs a simple animation as you might expect. The easing 'bounce' causes the animation to well, bounce. Examples of different easings here: http://raphaeljs.com/easing.html
Here is an example where we are animating the object 'icon' by rotating it 90 degrees and changing its colour to red. The animation will take 300 milliseconds and will have a fancy bounce effect.
icon.stop().animate({
transform: "r90",
fill: "red"
}, 300 , 'bounce' );

Javascript animations in jQuery using transform.js

i'm performing some animations with transitions using the plugin demo'd here http://www.binpress.com/app/demo/app/145
However i'm using multiple transitions on the same element.
Basically i have an animation with 5 circles working as satellite objects around a central point. The central point has a little arrow and as you hover over any of the satellite points it transforms using this plugin to the satellite circle being hovered over.
Here's an example of what i'm doing, simplified.
jQuery(".applications").bind('mouseover', function(){
console.log('fired the second animation');
jQuery(".midpointer").animate({
transform: 'rotate(190deg)'
});
});
jQuery(".hosting").bind('mouseover', function(){
console.log('fired the second animation');
jQuery(".midpointer").animate({
transform: 'rotate(190deg)'
});
});
Now the problem with this, is that after the first animation any subsequent hovers do not rotate the element. So i'm assuming I need to do some form of reset, I had been looking at .stop() in jQuery but to little avail.
Anyone shed any light on this for me?
I believe that you rotate 190deg from the starting position each time you do a mouse over, not relative to the current rotation of the object.
According to the documentation, you can use += to add to the current rotation:
transform: '+=rotate(190deg)'

Categories