Javascript animations in jQuery using transform.js - javascript

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)'

Related

SVG Rotate Element While Animating svgjs

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?

Drag and mouseover in snap.svg

I'm relatively new to javascript, and am learning about drag and drop using snap.svg. My problem is in the drop. I can't tell if the dragged element is over the drop target. In this code, I want to drag the circle over the square, and thought I could use mouseover. My (distilled) example may also be a simpler version of this post.
var paper = Snap(300, 300);
var square = paper.rect(100, 100, 40, 40).attr({fill:"blue"});
var circle = paper.circle(50, 50, 20).attr({fill:"red"});
circle.drag();
square.mouseover(
function() {
console.log("Over the square");
}
);
As written, the mouseover will fire when you move the pointer over the blue square, but not when you drag the red circle over the blue square. If you reverse the creation of the square and circle, the mouseover fires either way, but of course the circle is behind the square.
Evidently the event gets caught in the view hierarchy (or something) and doesn't propagate. There must be an easy way around this. Any help?
(And if the best answer is, "use jQuery," fine, but I'd love to learn how to make this work directly, since snap.svg makes dragging so easy.)
Addition: The direction I'm hoping for: the snap.svg documentation for Element.drag() says, in part, "When Element is dragged over another element, drag.over.<id> fires as well." A fine, event-based direction, which would let me (for example) highlight the drop target without a lot of fuss.
But I haven't figured out how to listen for that event! Any help or advice?
Only quick way without collision or element detection from points that I can think of, is to place an almost invisible clone in front of the object, later in the DOM that you can't really see, eg ...
paper.append( square.clone().attr({ opacity: 0.000001 }) )
jsfiddle
Depends how complex your svgs are going to be as to whether this would work I guess, you also have a slight issue if you drop the element over it, your redrag start won't get picked up, so you would need to code around that as well. I think some testing is probably going to be the most bug free solution (there are a few solutions on S.O for getElementFromPoint or hit detection type solutions).
jsfiddle workaround for point above

How can I apply opacity when I am using cache?

I am developing some app with kineticjs 5.1.0 and just starting with kineticjs.
This application can change the src attribute of an image, so the onLoad method will be called an unkown amount of times.
It also has sliders to control rotation, zoom, opacity and the intensity of some filters controlled with jquery.
However I have not been able to apply opacity and filtering at the same time.
At this moment, at load time (onLoad) I reset all transformation values (rotation , zoom, offset, filters and opacity).
leftImage.onload=function(){
layer.add(imagenIzquierda);
stage.add(layer);
imagenIzquierda.cache();
imagenIzquierda.filters([Kinetic.Filters.Brighten]);
anchoIzquierdo=this.naturalWidth;
altoIzquierdo=this.naturalHeight;
escalaIzquierda=200/altoIzquierdo;
$("#zoomIzquierdo").slider("option", "value", escalaIzquierda*100);
$("#opacidadIzquierda").slider("option","value",100);
$("#rotacionIzquierda").slider("option", "value", 0);
imagenIzquierda.position({x: anchoIzquierdo/2*escalaIzquierda,
y:altoIzquierdo/2*escalaIzquierda});
imagenIzquierda.offset({x: anchoIzquierdo/2, y: altoIzquierdo/2});
imagenIzquierda.scale({x: escalaIzquierda, y: escalaIzquierda});
imagenIzquierda.rotation(0);
imagenIzquierda.opacity(1);
layer.draw();
};
And on the sliders slide event I simple set the values, like this
$("#opacidadIzquierda").on("slide", function(event, ui){
imagenIzquierda.opacity(ui.value/100);
stage.draw();
});
My observatios are that opacity has no effect if there is a cache, but I cannot apply filters if there isn't one.
How should I go about it?
EDIT:
After much googling I came up with https://github.com/ericdrowell/KineticJS/issues/847, and a closer look at the Release Schedule tells me than indeed "opacity doesn't affect cached shapes https://github.com/ericdrowell/KineticJS/issues/847 "
What I am doint is clearing cache, saving/reseting offset, rotation and scale, applying opacity, caching, and reappling old offset, rotation and scale and filters.
The result is that now changing opacity is slow, as those calculations take place while the slider moves so as to get a 'live view'.

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;
}

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' );

Categories