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' );
Related
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?
I'm creating an Rpg in Phaser, and I'm trying to make a Flash effect happen over a Sprite -that means turning the Sprite all white for a moment and then returning to its original color-.
So my question is: what's the best way of achieving this effect?. I've tried two solutions so far, but i'm missing something:
Solution 1:
I tried tweening the tint parameter of the sprite, like this:
this.game.add.tween(enemy).to({
tint: 0xffffff,
}, 100, Phaser.Easing.Exponential.Out, true, 0, 0, true);
But it doesn't work since setting the tint to 0xffffff is the same as setting it to its default color.
Solution 2:
My second possible solution is adding a white square that has the same size of the sprite, and using the actual sprite as a mask for the square:
var flash = this.game.add.graphics(0, 0);
flash.beginFill(0xffffff);
flash.drawRect(enemy.x, enemy.y, enemy.width, enemy.height);
flash.endFill();
flash.mask = enemy // enemy is my Sprite
/* .. code for tweening the flash */
The problem with this solution is that the mask needs to be a PIXI.Graphics object; and I'm using a Sprite object.
So please, any guidance would be appreciated.
In the version of Pixi that Phaser 2.2.2 uses there is a 'tintCache' which basically rounds the tint value, then caches the result. This means you can't do subtle tint ramping like you're trying to do with a tween. We removed this in Phaser 2.3, so it will be available from then, but as of now it's still in dev.
Also you can tint to a 'near white' colour - only 0xffffff precisely resets the tint. But a value very close to that would still be set ok and probably have the desired result.
If you're using WebGL I would still use a tint with 'as near as white as possible' colour values and tween them. You could disable the tint cache for yourself by copying that part of the changed code from the Phaser dev branch.
In Canvas mode it's expensive though as it has to recalculate the pixels every single time you update it.
If you need to worry about Canvas performance then honestly I would create a new PNG that matches your sprite, colour it in all-white and display it over the top of your main sprite as needed and alpha it out. It's less than ideal because of the extra assets required, but it would be the fastest in canvas mode for sure. All depends on your game though is that's acceptable or not.
Edit: Also occurred to me that you could probably achieve what you need by using a blend mode too, such as lighten. You'd duplicate your main sprite, set the blend mode on it, display it over the top of your sprite and fade it out. This would work fine in Canvas at least.
You can use a ColorMatrixFilter on the Sprite. In Phaser, you may have to manually load in the PIXI script first:
game.load.script('filter', 'js/filters/ColorMatrixFilter.js');
Use this for white:
var filter = new PIXI.ColorMatrixFilter();
filter.matrix = [1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1];
this.game.filter = [filter];
You can also tween the matrix values if you want a smooth transition.
I've constructed a "wheel of fortune" using Raphael.js and now wish to animate this wheel to some arbitrary degree of rotation. I perform this animation using Raphael.js's animate function:
degrees += 360;
var duration = 1000;
wheel.animate({transform:"r"+degrees+" 250 250"},duration,"cubic-bezier(0,0,1,1)",null);
In this snippet I've specified a constant duration and a linear cubic-bezier which is nothing like the real spin of a wheel. Given some change in rotation how can I best animate this change so as to model the physics of a wheel being spun and then friction bringing the wheel to a stop at the final degree of rotation?
If you're asking for different constants to pass to your cubic-bezier function, I'd recommend taking a look at cubic-bezier.com, which lets you play around with different combination of curves. The site itself only applies the function to linear movement (not rotation), but it should give you a nice starting point to tinker with some different values.
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;
}
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)'