I am using velocity.js to deal with animations and its for the most part great. I have a basic demo on codepen that displays a simple toggle button, however the js to make it animate is seemingly very cumbersome.
Whats the best way to deal with toggling animation like that in my example?
var open = false;
$('.filter').click(function(e){
e.preventDefault();
var el = $(this);
if(!open){
el.find('.filter__line:first').velocity({translateY: [0, -5]}, 200, function(){
$(this).addClass('filter__line--thick').velocity({rotateZ: '45deg'}, 200);
});
el.find('.filter__line:last').velocity({translateY: [0, 5]}, 200, function(){
$(this).addClass('filter__line--thick').velocity({rotateZ: '-45deg'}, 200);
});
open = true;
} else {
el.find('.filter__line:first').velocity({rotateZ: '0deg'}, 200, function(){
$(this).removeClass('filter__line--thick').velocity({translateY: [-5, 0]}, 200);
});
el.find('.filter__line:last').velocity({rotateZ: '0deg'}, 200, function(){
$(this).removeClass('filter__line--thick').velocity({translateY: [5, 0]}, 200);
});
open = false;
}
});
http://codepen.io/matt3224/pen/zGgKwP?editors=011
Thanks
I used Velocity for a long time and ran into those sort of problems a lot. I would highly suggest GSAP if you're doing any sort of complex animations. GSAP timelines allow you to easily play, pause, and reverse a series of animations and the syntax is nice and clean. You can find more info on the GSAP website.
I made a quick demo using this technique on Codepen.
Here's what the script looks like:
$(document).ready(function(){
var top = $('.part-1');
var mid = $('.part-2');
var btm = $('.part-3');
var tl = new TimelineMax().pause();
tl.to(mid, 0.3, {x:100, opacity:0})
.to(top, 0.3, {rotation:18, transformOrigin:"left top"},"second")
.to(btm, 0.3, {rotation:-18, transformOrigin:"left bottom"},"second");
var active = false;
$('h1').click(function(){
if(!active){
tl.play();
active = true;
} else {
tl.reverse();
active = false;
}
}); // end of click
}); // end of ready
Related
Here, I am trying to apply bounce animation to my dynamically generated messages called by API but no effect is coming. Also, I tried using effect() but it was also of no use. Here is the link to my Codepen. Link
$(document).ready(function () {
$("#getMessage").on("click",function () {
//(".message").effect("bounce", {times:300}, 300);
move();
});
var divObj = null;
function init () {
divObj = document.getElementById("message");
// $("#message").toggle("bounce", {times: 6}, "slow");
divObj.style.position = "relative";
divObj.style.top = "0px";
}
function move () {
divObj.style.top = parseInt(divObj.style.top) + 10 + "px";
}
});
What you've supplied above isn't too far off from the result(s) you're looking for. Essentially the {times:300} you are supplying is far too many for the speed/ratio - resulting in no visible animation.
From what I have just tested, any bounces >10 with the speed #300 seem to display in an abnormal manner.
Please see this codepen: http://codepen.io/anon/pen/BWyqpY
Give this a try:
$("#getMessage").on("click",function () {
$(".message").effect("bounce",{times:3},300);
// I'm not sure if you still want this method.
move();
});
I'm new in titanium and I have a strange problem with animate, the code is like this.
var animateRight = Ti.UI.createAnimation({
left : 150,
curve:Titanium.UI.ANIMATION_CURVE_EASE_IN_OUT
});
var animateStart = Ti.UI.createAnimation({
left : 0,
curve:Titanium.UI.ANIMATION_CURVE_EASE_IN_OUT
});
$.menu.addEventListener('click', function(){
if($.container.left >= 10){
//$.container.left = 0;
$.container.animate(animateStart);
}
else{
//$.container.left = 150;
$.container.animate(animateRight);
}
});
menu is a button, when I touch it, the menu should move to right, and if a touch it again the menu should move to left, so if a use "$.container.left = 150;",the action in the menu work well, but if use animate the menu never return to original position.
I think that the problem is for the animate, but I'm not sure, somebody can I help me ?
Thanks.
Animation is perfectly fine.I think there is something wrong with your condition.Checkout whether both conditions work by showing an alert
Thanks
you can use Boolean variable to control animation like :
var is_container_change = false;
var animateRight = Ti.UI.createAnimation({
left : 150,
curve:Titanium.UI.ANIMATION_CURVE_EASE_IN_OUT
});
var animateStart = Ti.UI.createAnimation({
left : 0,
curve:Titanium.UI.ANIMATION_CURVE_EASE_IN_OUT
});
$.menu.addEventListener('click', function(){
if(is_container_change){
$.container.animate(animateStart);
}
else{
$.container.animate(animateRight);
}
is_container_change = !is_container_change
});
I'm developing some page when I use Raphael liblary to draw some items.
my App
So my problem is in that when I'm moving to some rect it growing up but when my mouse is on text which is positioning on my rect, it loss his hover. You can see it on my app example.
var paper = new Raphael(document.getElementById('holder'), 500, object.length * 100);
drawLine(paper, aType.length, bType.length, cType.length, cellSize, padding);
process = function(i,label)
{
txt = paper.text(390,((i+1)* cellSize) - 10,label.devRepo)
.attr({ stroke: "none", opacity: 0, "font-size": 20});
var a = paper.rect(200, ((i+1)* cellSize) - 25, rectWidth, rectHeight)
.hover(function()
{
this.animate({ transform : "s2"}, 1000, "elastic");
this.prev.animate({opacity: 1}, 500, "elastic");
this.next.attr({"font-size" : 30});
},
function()
{
this.animate({ transform : "s1" }, 1000, "elastic");
this.prev.animate({opacity: 0}, 500);
this.next.attr({"font-size" : 15});
});
}
I have tried e.preventDefault(); on hover of this.next and some other solutions but it's doesn't work.
Any help would be appreciated.
Most people will suggest you place a transparent rectangle over the box and the labels and attach the hover functions to that instead. (If memory serves, you have to make the opacity 0.01 instead of 0 to prevent the object from losing its attached events.) This works fine, but I don't love this solution; it feels hacky and clutters the page with unnecessary objects.
Instead, I recommend this: Remove the second function from the hover, making it functionally a mouseover function only. Before you draw any of the rectangles and labels, make a rectangular "mat" the size of the paper. Then, attach the function that minimizes the label as a mouseover on the mat. In other words, you're changing the trigger from mousing out of the box to mousing over the area outside of it.
I left a tiny bit of opacity and color on the mat to be sure it's working. You can just change the color to your background color.
var mat = paper.rect(0, 0, paper.width, paper.height).attr({fill: "#F00", opacity: 0.1});
Now, you want to make a container for all the rectangles so you can loop through them to see which need to be minimized. I made an object called "rectangles" that contains the objects we're concerned with. Then:
mat.mouseover(function () {
for (var c = 0; c < rectangles.length; c += 1) {
//some measure to tell if rectangle is presently expanded
if (rectangles[c].next.attr("font-size")) {
rectangles[c].animate({
transform : "s1"
}, 1000, "elastic");
rectangles[c].prev.animate({opacity: 0}, 500);
rectangles[c].next.attr({"font-size" : 15});
}
}
});
Then I just removed the mouseout function from the individual rectangles.
jsBin
To be clear, this will have some downsides: If people run the mouse around really fast, they can expand several rectangles at the same time. This is remedied as soon as the mouse touches the mat. I think the functionality looks pretty nice. But the invisible mats is always an option.
I wrote a small extension to Raphael - called hoverInBounds - that resolves this limitation.
Demo: http://jsfiddle.net/amustill/Bh276/1
Raphael.el.hoverInBounds = function(inFunc, outFunc) {
var inBounds = false;
// Mouseover function. Only execute if `inBounds` is false.
this.mouseover(function() {
if (!inBounds) {
inBounds = true;
inFunc.call(this);
}
});
// Mouseout function
this.mouseout(function(e) {
var x = e.offsetX || e.clientX,
y = e.offsetY || e.clientY;
// Return `false` if we're still inside the element's bounds
if (this.isPointInside(x, y)) return false;
inBounds = false;
outFunc.call(this);
});
return this;
}
To keep it small and simple, when clicking a button, all the the divs should slide away in random directions and another set of new divs should be displayed.
Basic demo of what the jQuery code is like:
$(document).ready(function() {
$("#toggle_value").click(function(){
$("#div1").show("fast");
$("#div2").show("fast");
$("#div3").show("fast");
});
});
But its all about randomizing the effects. Any solutions?
I would do something like this:
http://jsfiddle.net/8uKt3/13/
$(document).ready(function() {
var $div = $('div'),
pos = [0, 0, 0, 500, 250, 100, 50, -500, -750, -1000, -1500], // Define your numbers
mypos1,
mypos2,
$me;
$("#toggle_value").click(function(){
$div.each(function(){
$me = $(this);
// Choose a value from each array randomly
mypos1 = pos[Math.floor(Math.random() * pos.length)];
mypos2 = pos[Math.floor(Math.random() * pos.length)];
// animate in a random direction in a random quantitya
$me.animate({
'top' : mypos1,
'left': mypos2
});
});
});
});
You can do something like this, lets say you have 3 possible cases for how the divs might slide away:
var rand = Math.random();
if (rand < .33) {
// Some animation
} else if (rand < .66) {
// Some other possible animation
} else {
// Final animation possibility
}
Algorithm:
create an array of 'n' ints
shuffle the array
in the click function:
for each value 'v' in the shuffled array:
$('#div' + v).show('fast')
My guess is that you're going to have introduce a delay in the animation using the completion all back on 'effect' for this to look good, but that should be trivial to do
I have this simple animation that moves from side to side, Im trying to create a reset button so that the animation stops and gets back to default, but I cant seem to get i right.
The library I am using is Raphael, but I'm almost sure that with a simple javascript I can reset the values inside the function.
Body onload init function
function init() {
paper = Raphael("loadSVG");
var bg = paper.rect( 0, 0, "240px", "90px", 0 );
bg.attr( {fill: "#f3f3ff"} );
rect1 = paper.rect(150, 20, 50, 50);
rect1.attr( {fill: "#ffaaaa", "stroke-width": 3} );
}
The animation function
function moveRect1() {
if( xEnd == 150 )
xEnd = 50;
else
xEnd = 150;
rect1.animate( {x: xEnd}, 1000, "Sine", function (){
moveRect1();
});
}
and the stop button that don't work :)
function stopsvgRect1() {
rect1.stop();
}
You need to bind the stop button to the function you've created.
For example like this:
document.querySelector('#stop').onclick = function() {
stopsvgRect1();
};
Open this fiddle to see it in action.
edit:
As the position should also be resetted, you can choose Raphael.transform() for this action.
Open my updated fiddle to see how it works.