I have multiple images and want to rotate images in 3d and 2d one by one display.
HTML is like
<div><img src="1.jpg"></div>
<div><img src="2.jpg"></div>
<div><img src="3.jpg"></div>
etc
So I want to display image by previous image flip out and next flip in.
I have tried below code
To hide:
$hide.animate({
transform: 'rotate(180deg)',
opacity: 0.1
},
1500,
'easeInOutBack',
function () {
$(this).hide();
});
To Show:
$show.show().animate({ transform: 'rotate(180deg)', opacity: 1.0 },1500,'easeInOutBack');
But it is not working. I am using jquery and jquery ui only.
you don't animate rotation with jQuery, let CSS do that for you.
try this:
js:
$hide.addClass('hide').removeClass('show');
$show.removeClass('hide').addClass('show');
css:
.show, .hide{transition:all 0.3s ease;}
.hide{opacity:0.1;transform:rotate(0deg);}
.show{opacity:1;transform:rotate(1800deg);}
hope that helps.
EDIT:
if you still wish to use jQuery and not CSS, i'd suggest a plugin such as http://nnattawat.github.io/flip/
EDIT2:
if you still don't want the CSS approach, and not a jQuery plugin, i suggest you take a look here:
CSS rotation cross browser with jquery.animate()
"CSS-Transforms are not possible to animate with jQuery, yet. You can
do something like this [code sample]"
i also created a fiddle to demonstrate this approach: http://jsfiddle.net/jhcvb2ty/
Basic animates can't animate non-numeric CSS properties.
so use step function in animate then it works.
See example: http://jsfiddle.net/kevalbhatt18/epp06LL3/2/
$('#box').animate({ transformValue: -180 }, {
step: function(now,fx) {
$(this).css('transform','rotatex('+now+'deg)');
},
duration:'slow'
},'linear');
EDIT:
See example: http://jsfiddle.net/kevalbhatt18/u2ptr4jp/4/
Now simply add div inside parent span it will work for all.
Note: only first class you should know i.e in this example we have
box class so if we are at last box then it will flip to first box
$("div").click(function() {
var that = this;
$(this).animate({
transformValue: -180
}, {
step: function(now, fx) {
$(this).css('transform', 'rotatey(' + now + 'deg)');
},
complete: function() {
$(that).hide();
//$('#box').removeAttr( 'style' );
var nextObject = $(that).next()
var nextClass = nextObject.attr('class')
console.log($('#parent').children().hasClass(nextClass));
if ($('#parent').children().hasClass(nextClass)) {
var flipNext = nextClass;
console.log("true")
} else {
console.log("false")
var flipNext = "box";
console.log(flipNext);
}
secondFlip(flipNext, that);
},
duration: 'slow'
}, 'linear');
});
function secondFlip(nextID, that) {
$('.' + nextID).show();
$('.' + nextID).animate({
transformValue: 180
}, {
step: function(now, fx) {
$(this).css('transform', 'rotatex(' + now + 'deg)');
},
complete: function() {
},
duration: 'slow'
}, 'linear');
}
Edit: rotation issue solved
see this example: http://jsfiddle.net/kevalbhatt18/u2ptr4jp/6/
Final Output:
After so many tray I found solution.
see this example:http://jsfiddle.net/kevalbhatt18/oh07zuh0/
hear i find transformation degree.
(function ($) {
$.fn.rotationDegrees = function () {
var matrix = this.css("-webkit-transform") || this.css("-moz-transform") || this.css("-ms-transform") || this.css("-o-transform") || this.css("transform");
if (typeof matrix === 'string' && matrix !== 'none') {
var values = matrix.split('(')[1].split(')')[0].split(',');
var a = values[0];
var b = values[1];
var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
} else {
var angle = 0;
}
return angle;
};
}(jQuery));
Related
I'm a jQuery newbie - but have managed to modify a roulette wheel script to spin a "pie" image for a homepage I'm working on.
It works great - but the client also want to add an arrow on either side that will advance the pie one section upon click - so clockwise for one arrow, counter-clockwise for another.
Is there a way to specify a partial spin?
Any guidance is much appreciated! I'm trying to meet a ridiculous deadline and am struggling with this.
Here's the page:
http://bluetabby.com/rr/index13.html
Here's the jQuery code so far - the functions I need to figure out are leftArrow and rightArrow:
$( document ).ready(function() {
window.WHEELOFFORTUNE = {
cache: {},
init: function () {
console.log('controller init...');
var _this = this;
this.cache.wheel = $('.wheel');
this.cache.wheelSpinBtn = $('.wheel');
this.cache.leftArrow = $('.leftarrow');
this.cache.rightArrow = $('.rightarrow');
//mapping is backwards as wheel spins clockwise //1=win
this.cache.wheelMapping = ['Mitzvahs','Galas','Florals','Props','Weddings'].reverse();
this.cache.wheelSpinBtn.on('load', function (e) {
e.preventDefault();
if (!$(this).hasClass('disabled')) _this.spin();
});
this.cache.rightArrow.on('click', function (e) {
e.preventDefault();
if (!$(this).hasClass('disabled')) _this.spin();
});
},
spin: function () {
console.log('spinning wheel');
var _this = this;
//disable spin button while in progress
this.cache.wheelSpinBtn.addClass('disabled');
/*
Wheel has 10 sections.
Each section is 360/10 = 36deg.
*/
var deg = 1000 + Math.round(Math.random() * 1000),
duration = 6000; //optimal 6 secs
_this.cache.wheelPos = deg;
//transition queuing
//ff bug with easeOutBack
this.cache.wheel.transition({
rotate: '0deg'
}, 0).delay(1000)
.transition({
rotate: deg + 'deg'
}, duration, 'easeOutCubic');
//move marker
_this.cache.wheelMarker.transition({
rotate: '-20deg'
}, 0, 'snap');
//just before wheel finish
setTimeout(function () {
//reset marker
_this.cache.wheelMarker.transition({
rotate: '0deg'
}, 300, 'easeOutQuad');
}, duration - 500);
//wheel finish
setTimeout(function () {
// did it win??!?!?!
var spin = _this.cache.wheelPos,
degrees = spin % 360,
percent = (degrees / 360) * 100,
segment = Math.ceil((percent / 5)), //divided by number of segments
win = _this.cache.wheelMapping[segment - 1]; //zero based array
console.log('spin = ' + spin);
console.log('degrees = ' + degrees);
console.log('percent = ' + percent);
console.log('segment = ' + segment);
console.log('win = ' + win);
//re-enable wheel spin
_this.cache.wheelSpinBtn.removeClass('disabled');
}, duration);
},
resetSpin: function () {
this.cache.wheel.transition({
rotate: '0deg'
}, 0);
this.cache.wheelPos = 0;
}
}
window.WHEELOFFORTUNE.init();
});//]]>
Thanks for any pointers!
I looked through your code and figured out you are using transit.js to do the spinning animations. Essentially, the object's css (transform "rotate") is being updated over a certain amount of time (like jQuery's animate).
You can extend your wheel of fortune object with spinright and spinleft functions (or whatever name you prefer), which you can bind to the keys/buttons that you'll create. Your code would look something like this:
WHEELOFFORTUNE.spinright = function() {
// get current degree of wheel and convert to integer
var degree = parseInt( this.cache.wheel.css('rotate'), 10 );
this.cache.wheel.transition( { "rotate": (degree + 73) + "deg" },1000 );
}
WHEELOFFORTUNE.spinleft = function() {
var degree = parseInt( this.cache.wheel.css('rotate'), 10 );
this.cache.wheel.transition( { "rotate": (degree - 73) + "deg" },1000 );
}
Then you can bind these functions to buttons or call the functions directly in console:
WHEELOFFORTUNE.spinright()
WHEELOFFORTUNE.spinleft()
Note: 73deg looks to be about the amount that 1 section is, but you'll probably have to play around with the numbers. You may also want to cache the degrees in your object as well. You probably will also need to figure out a way to center on each section per button press.
Cheers!
I'm developing an accordion plugin, and it's mostly done except for one bug where for the first few steps of the slideUp/slideDown, the accordion is 1px taller than it's meant to be, causing a visual bug. I've narrowed it down to the fact that the first step in the slideUp animation doesn't do anything, and I can't figure out why. Here's an example:
console.log('Start');
var diff = 0;
var upNow = 100;
var downNow = 0;
$.fx.interval = 1000;
var duration = $.fx.interval * 100;
$("#div1").slideUp({
easing: 'linear',
duration: duration,
step: function(now) {
if (now != 0 && now > 90) {
console.log("Slide Up: " + now);
upNow = now;
}
}
});
$("#div2").slideDown({
easing: 'linear',
duration: duration,
step: function(now) {
if (now != 0 && now < 10) {
downNow = now;
diff = 100 - (upNow + downNow);
console.log("Slide Down: " + now);
console.log("Slide Difference:" + diff);
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style='height: 100px; background-color: red;' id='div1'>
</div>
<div style='height: 100px; background-color: blue; display: none;' id='div2'>
</div>
http://jsfiddle.net/hbh6U/
The problem is that I need these to be in sync, and I can't figure out why they're not, or how to get them in sync. One idea I've had is to skip the first step of the slideDown animation, but I'm not sure how to do that either. Has anyone got any ideas, or faced this bug before?
The problem comes down to this line in jQuery's internal defaultPrefilter method:
tween.start = prop === "width" || prop === "height" ? 1 : 0;
This causes the animation for the second div (from 1px to 100px) to be shorter than that of the first div (from 0 to 100px).
To solve this modify your step function like this:
function linearStep(now, animation){
var animationStart = animation.start;
if (animationStart === 1){
animationStart = 0;
}
animation.now = (animation.end - animationStart ) * animation.pos + animationStart;
}
It overwrites the calculated now value by doing the same calculation with a fixed animationStart, which is 0 instead of 1.
This will break if the animation actually starts at 1, but there'd be other ways to handle it then.
Side-by-side Fiddle: http://jsfiddle.net/Nd3w2/3/
i don't exactly know where is this issue coming from... Sunday morning... not too much time to investigate... But i found two possible solution based on your fiddle...
First one was to wrap these two DIVs in another DIV with overflow:hidden.
Second one... probably more appropriate is to call "slide" function only on one of the divs and then update the size of second one in callback, something like that:
console.log('Start');
var diff = 0;
var upNow = 100;
var downNow = 0;
$.fx.interval = 1000;
var duration = $.fx.interval * 100;
$("#div1").slideUp({ easing: 'linear', duration: duration, step: function(now)
{
if(now != 0 && now > 90)
{
console.log("Slide Up: " + now);
upNow = now;
}
$("#div2").height(100- $("#div1").height());
}});
Also remove "disply:none" form div2 styles...
It fixes the issue and is a bit more elegant solution in my opinion... Calling two separate animation functions can lead to possible sync problems... Hope that helps...
Is there a way to make element fade in or fade out using Raphael.js? My code is something like:
var elem = paper.circle(10, 10, 10)
elem.hide();
Is there an attribute to .hide() to make fade effect, something like:
var elem = paper.circle(10, 10, 10)
elem.hide({'duration':5000});
You can animate opacity for fade effect
var elem = paper.circle(10, 10, 10);
elem.animate({ opacity : 0 }, 1000, function () { this.hide() });
To fadeIn,
elem.show().animate({ opacity : 1 }, 1000);
You can do it without animations also: http://jsfiddle.net/3jsFe/1/
You need to take the elem.node
$(elem.node).fadeOut(2000, function() {
$(elem.node).fadeIn(2000);
});
I've managed to get this far and it works great for solid width divs but can't work out how to manipulate it to work when the width of the div changes.
Question: How do I make this function take into account the different div widths after each 'round'?
var horizontalScroller = function($elem) {
var left = parseInt($elem.css("left"));
var temp = -1 * $('#horizontalScroller li').width();
if(left < temp) {
left = $('#horizontalScroller').width();
$elem.css("left", left);
}
$elem.animate({ left: (left-60) }, 2000, 'linear', function () {
horizontalScroller($(this));
});
}
$(document).ready(function() {
var i = 0;
$("#horizontalScroller li").each(function () {
$(this).css("left", i);
i += $(this).width();
horizontalScroller($(this));
});
});
Working example (with fixed width): http://jsfiddle.net/GL5V3/
Working example (with different widths): http://jsfiddle.net/wm9gt/
Well this was mildly fun, understood how your code works, but before I did that...
I rewritten it to this: (working fiddle)
function horizontalScroller(ulSelector) {
var horizontalSpan=0;
var collection=[];
function animate(index) {
var cur=collection[index];
var left=parseInt(cur.elem.css('left'));
if(left < cur.reboundPos) {
left+=horizontalSpan;
console.log(left);
cur.elem.css('left',left);
}
cur.elem.animate(
{ left: (left-60) },
2000,
'linear',
function () {animate(index)}
);
}
$(ulSelector).find('li').each(function() {
var $this=$(this);
var width=$this.width();
$this.css('left',horizontalSpan);
collection.push({reboundPos: -1 * width, elem: $this});
horizontalSpan+=width;
animate(collection.length-1);
});
console.log(collection);
console.log(horizontalSpan);
}
$(document).ready(function() {
horizontalScroller('#horizontalScroller');
});
Then I went back to your code and did this:
var horizontalSpan = 0;// swapped i for a "global" variable
var horizontalScroller = function($elem) {
var left = parseInt($elem.css("left"));
var temp = -1 * $elem.width();// updated to the correct width
if(left < temp) {// now out of bounds is properly calculated
left += horizontalSpan;// proper "wrapping" with just one addition
$elem.css("left", left);
}
$elem.animate({ left: (left-60) }, 2000, 'linear', function () {
horizontalScroller($(this));
});
}
$(document).ready(function() {
$("#horizontalScroller li").each(function () {
$(this).css("left", horizontalSpan);// horizontalSpan!!!
horizontalSpan += $(this).width();// horizontalSpan!!!
horizontalScroller($(this));
});
});
If you've got questions or want to tweak it a bit. I'd be happy you to help you along. But my hopes are that you will manage on your own.
P.S. My initial comment was rude, you're horizontal scrolling is ok thumbs up (but you were hoping the values for some of those .width() calls to be way different)
Can this be done ? Basically I want to animate an absolute-positioned image with right:xxxPX, let's say. Well, when the animation is in progress, can I add a "trail" effect to it?
Thanks,
Adrian
This should work:
var box = $('#box'),
// Create some clones (these make up the trail)
clones = $.map(Array(10), function(item, i){
return box.clone().css('opacity', 1 / (i + 1)).hide().insertAfter(box);
});
box.animate({
top: 100,
left: 200
}, {
duration: 1000,
step: function(now, fx) {
// On each step, set a timeout for each clone,
// making it move to the required position.
var prop = fx.prop;
$.each(clones, function(i, clone){
clone = $(clone).show();
setTimeout(function(){
clone.css(prop, now);
}, 50 * i);
});
}
});
Demo: http://jsbin.com/ifobe3