When I'm animating on Titanium a view, it doesn't retain its values. Let say for example I have a view named bar with height=0. I would like to animate so I made this code..
aniBar1 = Ti.UI.createAnimation({
curve: Ti.UI.ANIMATION_CURVE_EASE_OUT,
duration : 250,
height : 50,
top : 0
});
bar.animate(aniBar1);
This do the trick but when I do the second animation after some events, lets say
aniBar2 = Ti.UI.createAnimation({
curve: Ti.UI.ANIMATION_CURVE_EASE_OUT,
duration : 250,
height : 150,
top : 0
});
I want it to animate from the height 50 to 150 but it doesn't do that. When I execute second animation. It shrink down to 0 do the animation.
Is there a way to retain the values when animating? I tried to set the new values on callback but I can do callbacks.
Your help will be appreciated. Thanks in advance!
you need to set new value in its complete event...
aniBar1 = Ti.UI.createAnimation({
curve: Ti.UI.ANIMATION_CURVE_EASE_OUT,
duration : 250,
height : 50,
top : 0
});
aniBar1.addEventListener('complete',function(e){
bar.height = 50;
});
bar.animate(aniBar1);
Related
I am trying to create a infinite star rain animation, all stars are SVG's.
I tried this to create the animation:
(function($) {
TweenMax.set(".astar", {
x:function(i) {
return i * 50;
}
});
TweenMax.to(".astar", 5, {
ease: Linear.easeNone,
x: "+=500", //move each box 500px to right
modifiers: {
x: function(x) {
return x % 500; //force x value to be between 0 and 500 using modulus
}
},
repeat: -1
});
})(jQuery);
The repeat process is not smooth as you can see on this Codepen:
https://codepen.io/daniellwdb/pen/NXogoB
Is there any JS or GSAP solution to make the animation smooth so that it will look like stars keep spawning from the left and move to the right?
With your current setup, I think the easiest way to pull this off would be to duplicate your starfield so that the beginning of your next loop is identical to the end of your first one. Let's say this is your starfield SVG:
|...o.|
|o....|
|..o..|
Your new "duplicated" starfield would essentially be:
|...o.|...o.|
|o....|o....|
|..o..|..o..|
So when you move that duplicated image from left to right 100%, what you see in the last "frame" is identical to what it will return to when it loops.
Here's a fiddle that shows this concept in action: https://jsfiddle.net/yarp4oLs/5/
I have two identical starfield images that are 200x200 (so 400x200 when side-by-side) and they are displayed in a "viewport" container that is 200x200. Then I just slide them to the left 200px and repeat. Instant stars!
I am creating a long single page website and using ScrollMagicJS v1.3.0 to trigger events and to make some elements sticky. I would like to create a variety of other transition effects as one scrolls down the page.
Here's a jsfiddle that replicates the horizontal scrolling of my site.
scrollControl = new ScrollMagic({
vertical: false,
});
var myScrollScene = new ScrollScene({
triggerHook: 0,
offset: 0,
triggerElement: '#shot-0-1',
duration: '100vw',
pushFollowers: true
})
.setPin('#shot-0-1')
.addTo(scrollControl);
For instance, I want to create fade-to-black, flare-to-white, and cross-dissolve transitions between pages.
I understand some of the basic principles of HTML5 transitions, how to make one image dissolve into another, but I haven't been able to figure out a clever way to do it using the ScrollMagic scrolling.
Things I've considered: The next page slides under the current page and then transitions from 1.0 to 0 opacity using ScrollMagic triggers?
But how to do it in a way non-hacky and consistent with ScrollMagic's framework?
This has been asked and answered in the ScrollMagic's issues section:
https://github.com/janpaepke/ScrollMagic/issues/269
here's a copy:
A common misconception is that you need to do everything with the ScrollMagic pin functionality.
If the content isn't moving within the scroll flow anyway (it stays in position and is faded out or moved to side or sth. like that) you can have it as "fixed" right from the beginning.
That saves a lot of work and confusion.
The only reason to use ScrollMagic's pinning functionality is when an element should sometimes scroll naturally with the DOM and sometimes it shouldn't.
So if you have elements that are in place and should just be replaced by others, have them fixed the whole time.
Like this: https://jsfiddle.net/janpaepke/6kyd6ss0/1/
If it is indeed a case were you should use ScrollMagic's pinning method, then do the animation inside of a wrapper, that you pin.
Like this: https://jsfiddle.net/janpaepke/6kyd6ss0/3/
Here's the solution I settled on.
scrollControl = new ScrollMagic({
vertical: false,
});
vw = $(window).width();
console.log("width:" + vw + "px");
// pin frame 2
var myScrollScene = new ScrollScene({
triggerHook: 0,
triggerElement: '#shot-2',
// This pin is considerably longer than average
offset: 0,
// duration = stickyLength + disolve_duration
duration: 1.5 * vw + 'px'
})
.setPin('#content-2', {
pushFollowers: false
})
.addTo(scrollControl)
.addIndicators({
zindex: 100,
suffix: 'pin2'
});
// move frame 3 up early and pin it
var myScrollScene = new ScrollScene({
triggerHook: 0,
triggerElement: '#shot-2',
offset: 0,
// duartion = 1.5, but why?
duration: 1.5 * vw + 'px'
// the faux pin doesn't actually expand the container the way SM does
// so the results are a little strange
})
.on("start end", function (e) {
$('#content-3').css({left: 0, position:'fixed'});
})
.on("enter leave", function (e) {
$('#content-3').css({left: 0, position:'relative'});
})
.addTo(scrollControl)
.addIndicators({
zindex: 100,
suffix: 'pin3faux'
});
var dissolve = TweenMax.to('#content-2', 1, {
autoAlpha: 0
});
// dissolve frame 2 to frame 3
var myScrollScene = new ScrollScene({
triggerHook: 0,
// Note that though we are fading frame 2, we are
// using the arrival of frame 3 the trigger
triggerElement: '#shot-2',
// The sets the rapidity of the dissolve
// offset = stickyLength
offset: 0.33 * vw + 'px',
// The sets the rapidity of the dissolve
duration: 1 * vw + 'px'
})
.setTween(dissolve)
.addTo(scrollControl)
.addIndicators({
zindex: 100,
suffix: 'dissolve'
});
I used a pushFollowers: false on a pin and z-index to slide the next frame (also pinned) behind the first. Then a Tween to dissolve into the second frame. The result is a nice cinematic dissolve feature with adjustable duration.
Hope it is useful to others.
https://jsfiddle.net/wmodes/b4gdxeLn/
This is a last ditch attempt to try to achieve what I need from this slider. I have implemented a jquery content slider called 'Super Simple Slider' on my website. I have never used this before and so far it has been super simple. However I need the first slide of the slider to display for slightly longer than all of the other slides. 10 seconds. However after much research I can not find a way to do this. Can anybody see a workaround so I can make this happen? Can I perhaps use pure JavaScript along with the jQuery to make this happen?
Below is the jQuery for the slider
<script>
$(function(){
$('.slider').sss({
slideShow : true, // Set to false to prevent SSS from automatically animating.
startOn : 0, // Slide to display first. Uses array notation (0 = first slide).
transition : 400, // Length (in milliseconds) of the fade transition.
speed : 7000, // Slideshow speed in milliseconds.
showNav : true // Set to false to hide navigation arrows.
});
});
</script>
I think the best way to do it is to make some (easy) changes in the plugin:
1. Add an option (to keep it configurable) : speedOnFirst (for example)
In the plugin settings:
var settings = $.extend({
slideShow : true,
startOn : 0,
speed : 3500,
speedOnFirst : 3500, // <--- HERE
transition : 400,
arrows : true
}, options);
2. Change the timeout in reset_timer function
Check if target == 0 (it means it's the first slide), and then, base your timeout on settings.speedOnFirst instead of settings.speed
reset_timer = settings.slideShow ? function() {
clearTimeout(timer);
speed = (0 !== target) ? settings.speed : settings.speedOnFirst; // <--- HERE
timer = setTimeout(next_slide, speed); // <--- Change second param here
} : $.noop;
3. Call your plugin
$('.slider').sss({
slideShow : true,
startOn : 0,
transition : 400,
speed : 7000,
speedOnFirst : 10000, // <--- Delay for your first slide
showNav : true
});
>> See working demo here
NB: In the demo, the slides changes quickly so as you can see the difference with the first one, juste change the values with whatever you need.
You will need to customize the plugin to accomplish what you need.
Look at the non minified version (sss.js) and add the following logic:
Add an extra option:
var settings = $.extend({
slideShow: true,
startOn: 0,
speed: 3500,
transition: 400,
arrows: true,
firstSlideSpeed:10000 // new setting for first slide speed
}, options);
Change the slide logic:
reset_timer = settings.slideShow ? function () {
clearTimeout(timer);
var slideSpeed = ((target === 0) && settings.firstSlideSpeed) ? settings.firstSlideSpeed : settings.speed; // changed here
timer = setTimeout(next_slide, slideSpeed); // changed here
} : $.noop;
This should do the trick for you.
Hope it helps!
I have a number of divs positioned absolutely on a background image.
On the page will also be some buttons. When those are clicked different variables will trigger, shrinking and growing these divs.
Here is the javascript I'm currently using...
$(document).ready(function() {
var title = 1;
$(".button1").click(function() {
title = 1;
});
$(".button2").click(function() {
title = 2;
});
$(document).click(function(e) {
console.log(title);
if (title==1){
$('.london').animate({ backgroundColor:'green', width:'50', height:'50' }, 300);
} else if (title==2){
$('.london').animate({ backgroundColor:'red', width:'40', height:'40' }, 300);
}
});
});
As they are absolutely positioned they are scaled from the corner they are positioned with.
see an example here.
What I need to do is shrink and grow these divs from their center point. The only solutions I've seen seem overly complicated.
I guess I could add a negative margin of half the divs width in the jQuery to counteract this? I'll try that if there are no better solutions
Thanks for any help.
bboybeatle, your "negative margin of half the divs width" idea is spot on, and not at all difficult to implement. Just include the required marginTop and marginLeft settings in the two animations.
$(function() {
var cssMap1a = {
backgroundColor: 'green'
};
var cssMap1b = {
width: 50,
height: 50,
marginTop: -10,
marginLeft: -10
};
var cssMap2a = {
backgroundColor: 'red'
};
var cssMap2b = {
width: 30,
height: 30,
marginTop: 0,
marginLeft: 0
};
$(".button1").click(function () {
$('.london').css(cssMap1a).animate(cssMap1b, 300);
});
$(".button2").click(function () {
$('.london').css(cssMap2a).animate(cssMap2b, 300);
});
});
And here's a fiddle. Fiddles are not difficult to set up. Hopefully this will help you next time you need to ask a question here.
As you will see :
"London" and the buttons are moved to a better position for demo purposes
The colour changes are separated out as separate css maps. They didn't work in the fiddle when included in the animation maps. jQuery needs a plugin to animate colours.
Thanks very much for that #Roamer-1888, I actually used some variables to make it slightly easier to apply the margin. I will remember that technique of putting multiple css properties in a variable..
Heres a snippet of my code I ended up using...
londonMargin = london/2 - london;
$('.london').animate({ width:london, height:london, marginLeft:londonMargin, marginBottom:londonMargin }, 300);
Just for fun I put together a little FIDDLE that has a function to which you pass an element name, the x and y coordinates of the center, and it will position the element in the larger element.
JS
var myelement = $('.boxdiv');
var myelement2 = $('.boxdiv2');
putmycenter( myelement, 90, 90 );
putmycenter( myelement2, 160, 280 );
function putmycenter (element, x, y)
{
var boxdivxcentre = element.width()/2;
var boxdivycentre = element.height()/2;
var boxdivposx = (x - boxdivxcentre);
var boxdivposy = (y - boxdivycentre);
element.css({
"top" : boxdivposy + 'px',
"left" : boxdivposx + 'px'
});
}
I've created a quick test to show what I'm trying to do:
http://jsfiddle.net/zY3HH/
If you click the "Toggle Width" button once, a square will take one second to grow to full width. Click it again, and it will take one second to shrink down to zero width.
However, click the "Toggle Width" button twice in rapid succession - the second time when the square has grown to only a small fraction of its total width (like 10%) - you'll notice that the animation still takes a full second to return the square to zero width, which looks awkward, IMO.
While that behavior is expected, I'd like the latter animation to happen in an amount of time that's proportional to the width that it's covering. In other words, if you click "Toggle Width" a second time when the square is at 10% of its total width, I'd like it to take about 1/10th of a second to shrink back to zero width.
It should be relatively easy (I think) to make the value of the duration property dynamic, calculated when the jQuery click handler is run, to measure the current width of the square and determine the duration accordingly.
However, am I missing a better way to do this? Does jQuery provide an easy way, or expose some sort of method or property to make this easier?
I don't think jQuery has any built-in utility for doing this. The math required to do what you want is fairly straightforward, however, so I'd suggest just going that route. Something like:
var expanded = false;
$('input').click(function() {
$('div').stop();
var duration;
if (expanded) {
duration = ($('div').width() / 100) * 1000;
$('div').animate({ width: '0' }, { queue: false, duration: duration });
expanded = false;
} else {
duration = ((100 - $('div').width()) / 100) * 1000;
$('div').animate({ width: '100px' }, { queue: false, duration: duration });
expanded = true;
}
});
Here's a working example: http://jsfiddle.net/zY3HH/2/
If you've got some free time on your hands, maybe you could make the duration interpolation logic a bit more generic and package it up as a jQuery extension/plugin.
This is what you want - http://jsfiddle.net/FloydPink/qe3Yz/
var expanded = false;
$('input').click(function() {
var width = $('div').width(); //gives the current width of the div as a number (without 'px' etc.)
if (expanded) {
$('div').animate({
width: '0'
}, {
queue: false,
duration: (width/100 * 1000)// (current width/total width * 1 sec in ms) });
expanded = false;
} else {
$('div').animate({
width: '100px'
}, {
queue: false,
duration: 1000
});
expanded = true;
}
});