About image rotation once element with specific id is clicked - javascript

Logo and elements from ul once clicked rotates image. By default image is already rotated by certain degrees, then on each click image rotates to necessary value.
So far I was using the following:
$("#objRotates").css('opacity','.2');
var value = 0;
var prev_value = 0;
$( "li" ).click(function() {
var text=$(this).text();
if(text==="text1"){value=0;}
if(text==="text2"){value=33;}
if(text==="text3"){value=66;}
if(prev_value != value){
$("#objRotates").animate({opacity:'1'});
$("#objRotates").rotate({
animateTo:value,
easing: $.easing.easeInOutExpo,
center: ["25px", "150px"],
callback: function(){$("#objRotates").animate({opacity:'0.2'});}
});
}
prev_value = value;
});
Above code is the one that was used before, where images start position was 0 and its animation was triggered from link text.
Using jqueryRotate.js examples(here)
How do I change the code, so that images start position is certain degrees and animation starts if element with specific ID is clicked?
Give at least clue..Cause for now, looking at my old code, I am lost. Thanks in advance.
SIMPLIFIED FIDDLE

Ok, so I've created a couple of samples for you to check out. The first one is very basic and I've simplified the code a little to make it easier to understand. This one just uses completely static values and a static elementId for the event, which I'm pretty sure answers your question based on your response to my comment yesterday. http://jsfiddle.net/x9ja7/594/
$("#elementId").click(function () {
var startingAngle = 45;
var endingAngle = 90;
var elementToRotate = "img";
$(elementToRotate).rotate({
angle: startingAngle,
animateTo: endingAngle
});
});
But I wanted to give another example as well that would be dynamic and repeatable for multiple elements. With the code above, you would have to copy/paste the same code over and over again if you want to perform this animation by clicking different elements. Here's an alternative. In this example, you set all of your parameters in the data attributes in the clickable element, then the function is completely repeatable, you only have to write it once. Less code = everyone happy! Here's the example: http://jsfiddle.net/x9ja7/595/
//#region Default starting angles
$("#image1").rotate({ angle: 90 });
$("#image2").rotate({ angle: 20 });
//#endregion
$(".rotateAction").click(function () {
//#region Optional parameter - used in the optional callback function
var $self = $(this);
//#endregion
var startingAngle = Number($(this).attr("data-startingangle"));
var endingAngle = Number($(this).attr("data-endingangle"));
var elementToRotate = $(this).attr("data-elementtorotate");
//#region If the current angle is the ending angle, reverse the animation - this can be removed if you want, I thought it may be cool to show some of the things you can do with this.
var currentAngle = $(elementToRotate).getRotateAngle();
if ( currentAngle[0] === endingAngle) {
startingAngle = Number($(this).attr("data-endingangle"));
endingAngle = Number($(this).attr("data-startingangle"));
}
//#endregion
$(elementToRotate).rotate({
angle: startingAngle,
animateTo: endingAngle
//#region This is optional - uncommenting this code would make the animation single-use only
//, callback: function () { $self.off().removeClass("clickable"); }
//#endregion
});
});
Hope this helps. If you need any other assistance, please let me know.

Related

Multistage of svg transform animation with Snap SVG

I'm building a small UI which provides users progress of downloading or loading certain information. Here is the codes so far
http://jsfiddle.net/pge1wukj/4/
var s = Snap("svg");
var movepath = s.select("#movePath").attr({
"fill":"none"
});
var dapath = s.select("#dapath").attr({
stroke: "#cdcdcd",
"stroke-width": 5,
});
var dapoints = [242,334.5, 372,334.5, 372,390, 320.5,390.5 ,308.5,421.5 ,293.5,391.5 ,242,391]
var circle = s.select("circle");
var poly = s.select("polygon");
$("a").click(function(){
circle.animate({
opacity: 0
},100);
poly.polyAnimate(dapoints,100,mina.linear,function(){
moveAlongPath(poly,{x:308,y:421},s.halfArc(308,421,135,382,50,0),100);
});
dapath.animate({
d:"M135,382.5c0,52.159,85,79.031,170.001,79.498 C 390.3,462.466,475.598,436.344,475,382.5",
},100,function(){
dapath.animate({d:"M135,382.5c0,0,85.999-0.467,171,0c85.299,0.468,169,0,169,0"
},100,function(){
dapath.animate({
d:"M135,382.292c0,0,85.999-22.759,171-22.292c85.299,0.468,169,22.292,169,22.292"
},100,function(){
dapath.animate({
d:"M136,382.415c0,0,90.999,13.118,176,13.585c85.299,0.468,164-13.585,164-13.585"
},100,function(){
dapath.animate({
d:"M135,382.5c0,0,85.999-0.467,171,0c85.299,0.468,169,0,169,0"
},500,mina.bounce,function(){
var pathclone = dapath.clone().attr({
stroke: "blue",
strokeDashoffset: 500,
strokeDasharray: 500
});
var datext = s.text(100,330,"90").attr("style","text-align: center");
var banner = s.group(poly,datext);
moveAlongPath(banner,{x:136,y:382.415},movepath,3600);
var tick = 0;
var interval = setInterval(function(){
tick += 1;
var red = Math.random()*255;
var blue = Math.random()*255;
var green = Math.random()*255;
var hex = Snap.rgb(red,green,blue);
var dadatext = $("text").text(tick+" %")
if(tick % 10 == 0){
dadatext.attr({"font-size":"30px","fill":hex});
};
if (tick >= 100){clearTimeout(interval)};
},36);
pathclone.animate({
"stroke-dashoffset":0,
},5300);
var paths = Snap.set().push(dapath,pathclone);
paths.animate({
d:"M135,382.5c0,0,30,17,42,17c10,0.208,298-17,298-17"
},300,function(){
paths.animate({
d:"M135,382.5c0,0,287,17.208,297,17c12,0,43-17,43-17"
},2900,function(){
paths.animate({d:"M135,382.5c0,0,287,17.208,297,17c12,0,43-17,43-17"},100,function(){
paths.animate({
d:"M135,382.5c0,0,85.999-0.467,171,0c85.299,0.468,169,0,169,0"
},200,function(){
$("a").off("click");
/* End of animation */
/* Ready for next transformation*/
banner.animate({
transform: "rotate(180deg)"
},200);
})
})
});
})
});
});
})
})
});
});`
At the end of the animation, the banner should rotate 180 deg on the sharp point. However it doesn't animate as i expected. Is there any solution to this ? transforming animation is intimidating and i don't fully understand it....
I think what you are missing is that you need to provide the original transform to include, otherwise it will assume you are just replacing that transform.
So with this line...
banner.animate({ transform: 'rotate(180)' },200);
What this really means is, I'm going to overwrite any current transforms and animate to a new one of rotate(180).
What you probably want is...keep any existing transforms, and now rotate(180) as well.
So you probably want something more like this...transform() with no parameters will give us the existing transform. So we can combine.
transform -> existingtransform then apply additional transform
This would look like the following.
banner.animate({ transform: banner.transform() + " s-1,1" },200);
I'm not quite sure of the rotation effect you are after (did you mean it to go upside down or back to front?), but 's-1,1' may have been what you were thinking of.
jsfiddle example
Edit: jsfiddle with alternate rotation.
Note, for this, you need to take into account 'where' the polygon is, in relation to the group, as its offset as you have moved it (and then also moved the group).
Edit: The rotation center point is quite difficult, as we have the polygon points offset (not centred around 0) and then translated. Also the group they are in is translated, so you've kinda of got 3 things going on.
To try and help understand getting the actual points, I have rewritten the rotation animation.
banner.animate({ transform: banner.transform() + "r180," + banner.getBBox(1).cx + ',' + banner.getBBox(1).y2 },200);
We get the bounding box, which calculates the centre for us. The pivot point is mid length cx, and the lowest y point is y2.
I suspect there is an easier way to get the whole thing working to reduce the transform complexity in the overall code, but there's a bit too much to break down for a question here.
jsfiddle with getBBox

Animate polygon points snap.svg

it's the first time I tried to animate polygon points with snap.svg and I have the felling I'm doing something wrong there.
Here is my code :
var fdr = Snap('#fdright');
var time1_stp0 = [363.617,262.895, 363.562,367.4, 273.145,315.191, 273.145,315.191];
var time1_stp1 = [363.617,262.895, 363.562,367.4, 273.145,315.191, 273.145,210.688];
var timeline1 = fdr.polygon(time1_stp0).attr({fill:'red',opacity:'0.5'});
timeline1_anim = function(){
timeline1.animate({"points":time1_stp1},3000,mina.linear);
}
timeline1_anim();
As soon as the page is loaded, my polygon disappears (I guess it's because my function is called right after the creation of the polygon). I checked the html, my polygon's still there but here is what i get :
<polygon fill="#ff0000" style="opacity: 0.5;" points="363.617"></polygon>
I don't get what might be the issue, so if someone's got an answer i'll be glad to hear it.
EDIT : I tried to add "toString()" but it's still not working :
timeline1_anim = function(){
timeline1.animate({"points":time1_stp1.toString()},3000,mina.linear);
}
I think there's a bug in Snaps polygon animation.. its listed here There is a patch submitted linked from there.
However, you can get around this easily by animating the array values though if needed.
timeline1_anim = function(){
Snap.animate(time1_stp0, time1_stp1,
function( val ){
timeline1.attr({ points: val })
},
2000);
}
jsfiddle
If you are doing a lot of them, you could write a small plugin to include it...
Snap.plugin( function( Snap, Element, Paper, global ) {
Element.prototype.polyAnimate = function( destPoints, duration, easing, callback ) {
var poly = this;
Snap.animate( this.attr('points'), destPoints,
function( val ){ poly.attr({ points: val }) }, duration, easing, callback)
};
});
timeline1.polyAnimate( time1_stp1, 2000, mina.linear, function() { alert('finished')})
jsfiddle

Javascript class on path element

I'm creating a interactive map with svg and I have converted the svg format to a javasript file (rahpael). I want to put a class on a path element, to create a hover effect, but I can't seem to get it to work:
var path_cz = rsr.path("M513.4,537l-329,19.3L209.5,666c0,0,9.5,36.8,51.5,48.8l108,22.7c13.3-16.7,119-43.4,175.6-8.7l165.7-58.6 c0,0,210.2-54.5,113.6-150.5c-33.3-27.3-61.9-50.4-61.9-50.4l-72.8-5.5l-46.9,2l-154,6.7l-2.6,21L513.4,537z").attr({fill: '#4F217C',parent: 'farver','stroke-width': '0','stroke-opacity': '1'}).data('id', 'path_cz');
I've tried .attr("class","classname"); and some other stuff inside .attr, but still nothing..
Any suggestions would be appreciated, thx :)
As you are using Raphael JS, the easiest way to do this is to hook into the hover method that Raphael supplies out of the box and update it that way.
$(document).ready(function() {
var rsr = Raphael(0, 0, 1000, 1000);
var path_cz = rsr.path("M513.4,537l-329,19.3L209.5,666c0,0,9.5,36.8,51.5,48.8l108,22.7c13.3-16.7,119-43.4,175.6-8.7l165.7-58.6 c0,0,210.2-54.5,113.6-150.5c-33.3-27.3-61.9-50.4-61.9-50.4l-72.8-5.5l-46.9,2l-154,6.7l-2.6,21L513.4,537z").attr({fill: '#4F217C',parent: 'farver','stroke-width': '0','stroke- opacity': '1'}).data('id', 'path_cz');
path_cz.hover(function() {
path_cz.node.setAttribute('class', 'one');
}, function() {
path_cz.node.setAttribute('class', 'two');
});
});
For an example, here is a fiddle: http://jsfiddle.net/n9Mt6/1/

How to add click event on rectangle in Graphiti.js

I want to register click event on rectangle in graphiti. i tried this
var innerrect = new graphiti.shape.basic.Rectangle(100, 20);
innerrect.onClick = function(){
alert("Hi");
}
rect.addFigure(innerrect , new graphiti.layout.locator.BottomLocator(rect));
canvas.addFigure(rect, 100, 100);
but wont work. plz let me know abut it?
create your own shape inherited from Rectangle like this.
This looks at the first moment a little bit unconfortable, but normaly you write
your own shapes with a lot of custom code. In this case it is a one time effort to crate a new class.
Keep in mind that the examples are a good starting point. There is a an examples with a click event listener as well.
MyFigure = graphiti.shape.basic.Rectangle.extend({
NAME : "MyFigure",
init : function()
{
this._super();
this.createPort("output");
this.setDimension(30,30);
this.setResizeable(false);
this.value=false;
this.colors={};
this.colors[true]="#00f000";
this.colors[false]="#f00000";
this.setBackgroundColor(this.colors[this.value]);
},
/**
* #method
* Change the color and the internal value of the figure.
* Post the new value to related input ports.
*
*/
onClick: function(){
this.value = !this.value;
this.setBackgroundColor(this.colors[this.value]);
var connections = this.getOutputPort(0).getConnections();
connections.each($.proxy(function(i, conn){
var targetPort = conn.getTarget();
targetPort.setValue(this.value);
conn.setColor(this.getBackgroundColor());
},this));
}
});

gameQuery collision detection

it is the first time for me to explore jQuery and gameQuery for building games using JavaScript, so am asking about sth that might look very naive, but really i cant get it.
i am developing a game like Space Invader, the detection for collision between player missile and enemies not working.
This is my code:
the definition for my Enemy class
function Enemy(node){
this.node = $(node);
this.pts_value = 0;
return true;
}
this is the code i use to add ten enemy sprite next to each other. the enemies move together to the left and the right
$.each(new Array(10), function(index, value) {
$("#enemy_group").addSprite("enemy2_"+index,{animation: enemies[2],
posx: index * 55, posy: 0, width: 48, height: 48})
$("#enemy2_"+index).addClass("enemy");
$("#enemy2_"+index)[0].enemy = new Enemy($("#enemy2_"+index));
$("#enemy2_"+index)[0].pts_value = 150;
});
so when i need to move the enemies, i move the enemies together, i move the group that includes all the sprites "#enemy_group"
if(ENEMY_TO_RIGHT){
var enemiesNewPos = (parseInt($("#enemy_group").css("left"))) + ENEMY_SPEED;
if(enemiesNewPos < PLAYGROUND_WIDTH - 550){
$("#enemy_group").css("left", ""+enemiesNewPos+"px");
} else {
ENEMY_TO_RIGHT = false;
}
} else {
var enemiesNewPos = (parseInt($("#enemy_group").css("left"))) - ENEMY_SPEED;
if(enemiesNewPos > 0){
$("#enemy_group").css("left", ""+enemiesNewPos+"px");
} else {
ENEMY_TO_RIGHT = true;
}
}
finally for collision detection, i want to remove the enemy sprite that the players missile has hit, each missile sprite has an added class names ".playerMissiles"
$(".playerMissiles").each(function(){
var posy = parseInt($(this).css("top"));
if(posy < 0){
$(this).remove();
return;
}
$(this).css("top", ""+(posy - MISSILE_SPEED)+"px");
//Test for collisions
var collided = $(this).collision(".enemy, .group");
if(collided.length > 0){
//An enemy has been hit!
collided.each(function(){
$(this).setAnimation(enemies[0], function(node){$(node).remove();});
})
}
});
i was following the documentation tutorial on the gameQuery website.
any help appreciated, thanks,
I can't see any problem with your code. I can only give you a few pointers:
Did you create "enemy_group" with the addGroup function?
Is "enemy_group" nested in something special like a custom div ? for the collision detection to work you need a chain of parent composed only of sprites and groups (and tiles map)
Is "enemy_group" nested in a sprite, if so it's a bad idea because you will need to add the selector for this sprite in your methode call and this sprite will be included in the colliding element list.
The same goes for the ".playerMissiles"
Just to be sure what version of gameQuery and jQuery do you use? The last version from gitHub is unstable and I wouldn't recomend using it, user 0.5.1 instead.
You could use jquery collision plugin, so you avoid doid the logic by yourself.
Hope this helps. Cheers

Categories

Resources