I am trying to tween / cycle the color of the background of a page while it is clicked.
When the click is lifted, the cycling stops and the background color remains at the last cycled value. When it is clicked again, the process will continue.
Check the example here to see what I am referring to when I say cycle the color http://www.javascript-fx.com/development/colorcycle/spancycle.html
While browsing for solutions I have come across some libraries like JSTween or GSAP, but with my very fragile javascript experience I failed at implementing the examples to suit my need.
Any suggestions on how to do this will be helpful, preferably without any libraries since it will aid more in my understanding of javascript.
I am not looking for exact code, a pseudocode explanation of the process will also be great.
Best,
Andrei
So, Tweening colors is pretty easy with TweenJS or TweenMax (or TweenLite). I'll show this using TweenMax, mostly because the pseudocode is hard when there is no logic to pseudocode. Assume you have a text element:
<p id="text">This is some text to colorize</p>
You can tween the color of the text to red (#f00) over two seconds like this:
var textEl = document.getElementById('text');
TweenMax.to(textEl, 2, {color: '#f00'});
As far as cycling goes, you can send an onComplete handler to the tween, which will fire when the tween finishes. This will cause it to cycle between red and black:
var textEl = document.getElementById('text');
function toRed() {
TweenMax.to(textEl, 2, {color: '#f00', onComplete: toBlack});
}
function toBlack() {
TweenMax.to(textEl, 2, {color: '#000', onComplete: toRed});
}
toRed();
Here is a CodePen showing this in action.
If you want to make this a bit more compact, you can cycle by flipping the colorFrom and colorTo:
function cycle(colorFrom, colorTo) {
TweenMax.to(textEl, 2, {color: colorTo, onComplete: function() {
cycle(colorTo, colorFrom);
}});
}
cycle('#000', '#F00');
Doing the same thing in other tweening libraries becomes VERY similar.
Pseudocode for doing this cycle while tapped might be like this:
ON_CLICK:
ShowCycle = !ShowCycle;
IF ShowCycle
TweenHandle = cycle( RED, BLACK )
ELSE
IF EXISTS TweenHandle
cancelCycle( TweenHandle )
TweenHandle = null
END IF
END IF
Related
So i've made simple project in cocos2d added a heart sprite in the middle and tried to add an Animation do the heart sprite node (Just as it says on Cocos2d manual).
Problem is that animation works in the Preview, but nothing seems to be moving while playing game.
What should i do?
I tried adding the clip as default, checked PlayOnLoad box, I also created script for the heart Node so that it starts the animation and logs the state of animation for me:
cc.Class(
{extends: cc.Component,
properties: {
},
// LIFE-CYCLE CALLBACKS:
// onLoad () {},
start () {
var anim = this.getComponent(cc.Animation);
cc.log(anim == null);
var animState = anim.play();
animState.wrapMode = cc.WrapMode.Loop;
animState.repeatCount = Infinity;
animState.speed = 1;
cc.log(animState);
},});
it returns JSON that is saying that the animation is playing and all... but its not, what should i do?
I just want the animation to be played :(
EDIT: I found out that the animation is actually running, it's just property "eulerangles" which i was trying to use to animate heart's rotation wasn't really animating. I tried adding some position changes and they happen to work.
OK, so as it always is it was all my mistake for being an imbecil
I was trying to use "EulerAngle" instead of "Angle" property, which was working in editor but nowhere else.
Everything works fine, I'm sorry guys, i'll close this thread here.
I am tasked with creating an interactive SVG infographic with few slides for a browser game, it has 5 steps total. When you click prev / next buttons or a specific step, the whole svg should animate itself to the correct step.
In terms of code, this is what I have:
function Slide() {
// Cache all top-level svg elements for later use
this.el = $('svg#betfair-slider');
this.hands = this.el.find('#hands_8_');
this.cardsDesk = this.el.find('g#center-cards');
this.textContainer = $('.step-text');
// Use a shared timeline across all slides, so there are no overlapping tweens
this.tween = new TimelineLite();
}
function Slide2 () {
// Inherit from the main slide
Slide.call(this);
// each slide has its own supporting explanatory text
this.html = [
'<h3>Preflop</h3>',
'<p>Amet sit lorem ipsum dolar</p>'
].join('');
// the main openslide method
this.openSlide = function() {
// find the cards that need to be animated for this specific slide
var cards = this.hands.find('.card');
// fade out each card
this.tween.staggerTo(cards, 0.2, { opacity: 0 }, 0.2);
// Render supporting text
this.textContainer.html(this.html);
};
}
Here are the cards I am trying to get:
I am able to fetch them using the this.hands.find('.card'); jquery method (I can see them in the console), but I just can't animate them. I have tried animating different attributes (opacity, x, y, left, etc), but nothing happens - nothing moves on the screen.
I am able to do this.hands.find('.card').hide() and change the css using jQuery, but why TimelineLite doesn't work here? I also tried this approach:
var cards = this.hands.find('.card');
for (var i = cards.length - 1; i >= 0; i -= 1) {
var card = cards[i];
this.tween.to(card, 0.2, { opacity: 0 });
}
But still no success... The interesting thing is that when I attach an onComplete callback on the tweens, THEY ARE fired, but absolutely nothing moves on the screen. You can check out everything here.
Thanks for the help in advance, any suggestions are more then welcome.
I think you might be misunderstanding how timelines work (or perhaps I'm misunderstanding your intent). Like all tweens, timelines start playing immediately by default. So if you're using one timeline and shoving all your tweens in there based on user interaction (meaning time elapses between when you create it and when you populate it...and populate it more...), its playhead will already have advanced. I bet that's causing your tweens to jump to their end state almost immediately. That's not a bug - it's how things are supposed to work, although there's some logic in GSAP to adjust behavior in certain circumstances to make it more intuitive.
I see several options:
Just use TweenMax instead of a TimelineLite. Like TweenMax.staggerTo(...) and TweenMax.to(...).
Or just create a TimelineLite for each user interaction (instead of one for ALL of your tweens globally). That way you'll populate it right away and it'll play as you expected.
You could use one global timeline if you really want to, but you might just need to manage its playhead if you're going to be inserting tweens on each user interaction rather than all at once.
If you're still having trouble, don't hesitate to post in the GSAP-dedicated forums at http://greensock.com/forums/ and it's be super helpful if you included a codepen or jsfiddle reduced test case so that we can tinker and very quickly see what's going on and how the changes affect the result.
Happy tweening!
Is there a way to toggle between a sprite's animations? For example, I have a sprite touching the ground, but when it leaves the ground, I want it to play a different animation than the one that it plays while on the ground. However, I also want it to play the the first animation when it touches the ground again. I basically want something like this:
if (sprite.body.touching.down === false) {
sprite.animations.toggleAnimation("different_animation");
} else {
sprite.animations.play("original_animation");
}
Does Phaser have an easy way of doing this?
You can add as many animations to a Sprite as you need and then play them using the key. For example:
sprite.animations.add('jump', [0,1,2,3]);
sprite.animations.add('crouch', [4,5]);
sprite.animations.add('walk', [6,7,9,10,11]);
Then you can just play the animations by their key: sprite.play('walk')
It looks like I've found a solution to this; what I've been needing to do is load a different texture onto the sprite, not necessarily play a different animation. I guess I didn't communicate that very well. Basically, what I'm saying is this example:
http://phaser.io/examples/v2/animation/change-texture-on-click
to make things easy my approch is:
animation_arr = ['idle', 'walk', 'jump', 'idle_towel', 'walk_towel', 'jump_towel' ];
for(var i=0; i < animation_arr.length; i++){
player.animations.add(animation_arr[i], [0+(i*10), 1+(i*10), 2+(i*10), 3+(i*10), 4+(i*10), 5+(i*10), 6+(i*10), 7+(i*10), 8+(i*10), 9+(i*10)], 10, true);
}
For example when I copy the link from an answer and access it, a nice block of color appears to highlight the answer and then is fading out. How this is done?
It looks at the hash, selects that answer, and then animates the background color. Either use jQuery UI or add the Colors plugin to be able to animate colors.
This is what the code may look like...
var hash = window.location.hash;
if (hash) {
var answer = $('#answer-' + hash.substr(1)),
originalBackgroundColor = answer.css('backgroundColor');
// This class changes the background colur.
// Best to keep style stuff in the CSS layer.
answer
.addClass('linked')
.animate({
backgroundColor: originalBackgroundColor
}, 1000);
// You may optionally remove the added class
// in the callback of the above animation.
}
I use the following snippet to make an element's background lightblue, then slowly fade to whiite over 30 seconds:
$("#" + post.Id).css("background-color", "lightblue")
.animate({ backgroundColor: "white" }, 30000);
Two questions.
First, instead of fading to white, is there a way to fade opacity to 100%? That way I don't have to change "white" if I choose to change the page's background color?
Second, about once out of every 10 or 15 times, the background stays lightblue and fails to fade to white. I'm using the latest versions of jQuery and the UI core. What could be going wrong?
EDIT: Bounty is for a solution to problem regarding second question.
EDIT2:
Apparently I got downvoted into oblivion because I said I rolled my own solution but didn't show it. My bad. I didn't want to be self-promoting. My code works 100% of the time and doesn't require jQuery. A demonstration and the code can be found at:
http://prettycode.org/2009/07/30/fade-background-color-in-javascript/
For your second question: in my experience this is usually because a Javascript error has occurred somewhere else on the page. Once there is one Javascript exception, the rest of the page stops running Javascript. Try installing Firebug (if you haven't already), then open up the "Console" tab and enable it. Then any javascript errors or exceptions will be printed to the console.
Another thing to try (which kinda contradicts my last statement...) is to disable all your browser plug-ins to see if you can recreate. Sometimes they interfere with scripts on the page (particularly GreaseMonkey.)
If you could provide a sample HTML snippet which reproduces this animation problem it would be a lot easier for us to help you. In the script I have pasted below, I can click it all day, as fast or slow as I like, and it never fails to animate for me.
For the first question: I know you said you'd found a workaround, but the following works for me (even on IE6) so I thought I'd post it, since it may be different from what you were thinking. (Note that setting CSS "opacity" property through jQuery.css() works on IE, whereas IE does not support the "opacity" property directly in CSS.)
<html>
<head>
<style>
body { background-color: #08f; }
#test { background-color: white; width: 100px; }
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script>
var myOpacity = 0.125;
$(function(){
$('#test').css('opacity', myOpacity);
$('a').click(function(){
myOpacity = 1.0 - myOpacity;
$('#test').animate({ opacity: myOpacity });
return false;
});
});
</script>
</head>
<body>
<p>Click me</p>
<div id="test">Test</div>
</body></html>
Dont forget the color plugin.
See here
When the color fails to animate to blue you could try to use the callback function to log a message to the console. You can then check that the event actually fired and completed. If it does then you could potentially use two animates. The first one to animate to a halfway house color then the use the callback to animate to white (so you get two bites of the cherry, if the outer fails but completes the callback has a second go)
It would be good if you could try to recreate the issue or give a url of the issue itself.
e.g
$("#" + post.Id).css("background-color", "lightblue")
.animate({ backgroundColor: "#C0D9D9" }, 15000, function(){
$(this).animate({ backgroundColor: "#ffffff" }, 15000)
});
You could always use something like this, avoiding the JQuery animate method entirely.
setTimeout(function() { UpdateBackgroundColor(); }, 10);
UpdateBackgroundColor() {
// Get the element.
// Check it's current background color.
// Move it one step closer to desired goal.
if (!done) {
setTimeout(UpdateBackgroundColor, 10);
}
}
Also, you may be able to remove the "white" coding by reading the background color from the appropriate item (which may involve walking up the tree).
It is possible to have jQuery change the Opacity CSS property of an item (as mentioned in another answer), but there's two reasons why that wouldn't work for your scenario. Firstly, making something "100% opaque" is fully visible. If the item didn't have any other modifications to its opacity, the default opacity is 100%, and there would be no change, so I'm guessing you meant fading to 0% opacity, which would be disappearing. This would get rid of the light blue background, but also the text on top of it, which I don't think was your intent.
A potentially easy fix for your situation is to change the color word "white" to "transparent" in your original code listing. The color plugin may not recognize that color word (haven't checked documentation on that yet), but setting the background color to "transparent" will let whatever color behind it (page background, if nothing else) shine through, and will self-update if you change your page background.
I'll answer your first question.
You can animate opacity like this:
.animate({opacity: 1.0}, 3000)
I think you can try using fadeOut/fadeIn too..
What about:
$("#" + post.Id).fadeIn( "slow" );
You could possibly have two divs that occupy the same space (using position: absolute; and position: relative; setting the z-index on one higher to make sure one is above and the other is below. the top one would have a transparent background and the one below would have a background color. then just fadeout the one below.
As for the second question:
If you think the default animation classes from JQuery are not properly working you could try Bernie's Better Animation Class. I have some good experiences with that library.
Animate only works for numbers. See the jquery docs. You can do opacity but you can't do background color. You can use the color plug in. Background-color uses strings like 'red', 'blue', '#493054' etc... which are not numbers.