I'm working with CreateJS and wondered if anyone here has examples of controlling tweens using the Ticker object. I'm trying to get a sprite to follow a path defined by waypoints but i don't want to control each tween (in between waypoints) by time. I want to have smooth movement between each waypoint controlled by the Ticker object. I tried this code which doesn't seem to work at all.
var index = 0;
function move(){
index++;
if (index < path.length) {
createjs.Tween.get(person)
.to({x:gridSize * path[index][0] - pathOffset,y:gridSize * path[index][1] - pathOffset})
.call(move);
}
}
move();
createjs.Ticker.setFPS(30);
createjs.Ticker.addEventListener("tick", function(event){
createjs.Tween.tick(1);
stage.update();
});
This code seems to only jump between waypoints and not tween at all. Any ideas what i may be doing wrong or any code/tutorials which might help?
You need to add a duration(in milliseconds) to your tween, otherwise it would default to 0, this will cause the "jump", e.g.: 500 for half a second
instead of: .to({x:..., y:...})
use: .to({x:..., y:...},500)
And a second thing: You don't NEED to call createjs.Tween.tick(1); this is usually called automatically by the Tween-class.
Here is some help and some small examples: http://www.createjs.com/Docs/TweenJS/classes/Tween.html
Advanced Examples:
https://github.com/CreateJS/TweenJS/tree/master/examples
Related
I want to start a animation on an element while a previous animation is still active. However, calling animate() on the element queues the new animation at the end of the current animation.
For example, consider an animation where an element is being moved to a new position. Now, I also want to make it fade out when it reaches a certain position. The following queues the “once” animation at the end of the move, rather than at 80%.
rect.animate(1000).move(100, 100)
.once(0.8, function(pos, eased) {
rect.animate(200).opacity(0);
});
How do I make the element start fading out when it reaches 80% of the move? The API seems to be designed for chaining animations rather simultaneous overlapping animations.
What you are trying to do is a bit more complicated. Unforrtunately its not possible to "hack" into the current animation and add a new animation on the fly.
However what you can do is adding a new property which should be animated:
var fx = rect.animate(1000).move(100, 100)
.once(0.8, function(pos, eased) {
fx.opacity(0);
});
As you will notice that has its own problems because the oopacity immediately jumps to 80%. So this is not an approach which works for you.
Next try: Use the during method:
var morh = SVG.morph(
var fx = rect.animate(1000).move(100, 100)
.once(0.8, function(pos, eased) {
fx.during(function(pos, morphFn, easedPos) {
pos = (pos - 0.8) / 0.2
this.target().opacity(pos)
}
});
We just calculate the opacity ourselves
I have a circle with PIXI and I need that when the touch is fulfilled another object said circle returns to its original position, but it happens that I do not know any function or method for the movement to be appreciable, all I have achieved is that it disappear and appear in its initial position. How did the transition happen?
Just add the movement into rendering loop
I use PIXI.tickerTicker() for loop
let ticker = new PIXI.ticker.Ticker();
the rendering loop in your situation should be
function loop(){
renderer.render(stageContainer);
yourCircle.position.x += moveSpeed; //your question
if(resetCirclePosition)
yourCircle.position.x = defaultPos;
}
and then to start ticker use
ticker.add(loop);
ticker.start();
Look at ticker documentation http://pixijs.download/dev/docs/PIXI.ticker.Ticker.html
This question builds on the (correct) answer provided to this. I simply haven't been able to get any further..
With the help of an interpolator function, d3.js's tween allows smooth graphical transition between existing and new (ie to be set) DOM element values. At the simplest level, for a given animation we have a target element, an start state, an end state, a transition, a tween function and an interpolator.
Now, say I want every so often to programmatically update the contents of an input (text field) element. The value to be entered is non-interpolable (either the text is submitted, or it is not. There is no in-between state). In providing a closure (allowing for text retrieval at the scheduled transition time), tween would seem to be a good vehicle for the updates. Either I replace the interpolator with a fixed value, ensure the start and end values are identical, or find some other way of forcing it to fire at t=1. That's the theory..
To this end, in my case each property (not value) is modified in it's own update call, into which are passed transition, element index and parent element selection.
First cut:
an outer, 'governing' transition with delay values staggered using a multiple of the current element's index
playback_transition = d3.transition()
.delay(function(d, i, j) {
return (time_interval * i);
})
.duration(function() {
return 1; // the minimum
});
within a call to playback_transition.each() pass the transition as a parameter to a dependent animation by means of an update() interface
within this dependent animation, apply the transition and tween to the current element(s):
input // a UI dialog element
.transition()
.tween(i.toString(), setChordname( waveplot.chordname ));
Where:
function setChordname(newValue) {
return function() {
var i = newValue; // a string
return function(t) {
this.value = i;
inputChanged.call(this);
};
};
};
and
function inputChanged() {
if (!this.value) return;
try {
var chord = chordify.chordObjFromChordName(this.value);
purge(); // rid display of superceded elements
plotChord(chord, options); // calculate & draw chord using new input property
} catch (e) {
console.log(e.toString());
}
}
PROBLEM
While setChordname always fires (each chord is in turn correctly found and it's value stored), of the scheduled returned functions, only the first fires and results in display of the associated waveform. For all subsequent return function occurrences, it is as if they had never been scheduled.
From the display:
direct user update to the input field still works fine
only the first of setChordname's return functions fire, but, for this initial chord, carries right through, correctly displaying the cluster of associated chord and note waves.
From this, we can say that the problem has nothing to do with the integrity of the waveplotting functions.
From the console
transitions are accumulating correctly.
chord supply is all good
associated (ie initial) tween fires at t=1. (specifically, tween appears to accept omission of an interpolator function).
looking at the output of transition.toSource(), though the associated outer index increases by single figure leaps, tween itself is always paired with an empty pair of curly brackets.
transition = [[{__transition__:{8:{tween:{}, time:1407355314749, eas..
For the moment, apart from this and the initial execution, the tween factory return function behaviour is a mystery.
From Experiment
Neither of the following have any impact:
Extending the period before the initial transition takes effect
Extending (by a multiple) each staggered transition delay
Furthermore
the same transition configuration used in a different scenario works fine.
These seem to eliminate timing issues as a possible cause, leaving the focus more on the integrity of the tween setup, or conditions surrounding waveplot append/remove.
Afraid it might be interfering with input property text submission via the tween, I also tried disabling a parallel event listener (listening for 'change' events, triggering a call to inputChanged()). Apart from no longer being able to enter own chordnames by hand, no impact.
In addition to 'change', I tried out a variety of event.types ('submit', 'input', 'click' etc). No improvement.
The single most important clue is (to my mind) that only the first setChordname() return function is executed. This suggests that some fundamental rule of tween usage is being breached. The most likely candidate seems to be that the return value of tween **must* be an interpolator.
3 related questions, glad of answers to any:
Anything blatently wrong in this approach?
For a shared transition scenario such as this, do you see a better approach to transitioning a non-interpolable (and normally user-supplied) input property than using tween ?
Provided they are staggered in time, multiple transitions may be scheduled on the same element - but what about multiple tweens? Here, as the staggered transition/tween combos are operating on only one element, they seem likely to be passed identical data (d) and index(i) in every call. Impact?
I'm now able to answer my own question. Don't be put off by the initial couple of paragraphs: there are a couple of valuable lessons further down..
Ok, there were one or two trivial DOM-to-d3 reworking issues in my adoption of the original code. Moreover, an extra returned function construct managed to find it's way into this:
Was:
function setChordname(newValue) {
return function() { <--- Nasty..
var i = newValue;
return function(t) {
this.value = i;
inputChanged.call(this);
};
};
};
Should have been:
function setChordname(newValue) {
var i = newValue;
return function(t) {
this.value = i;
inputChanged.call(this);
};
};
The fundamental problem, however, was that the transition -passed in as a parameter to an update() function- seems in this case to have been blocked or ignored.
Originally (as documented in the question) defined as:
input // a UI dialog element
.transition()
.tween(i.toString(), setChordname( waveplot.chordname ));
..but should have been defined as:
transition
.select("#chordinput") // id attribute of the input element
.tween(i.toString(), setChordname( waveplot.chordname ));
My guess is that the first version tries to create a new transition (with no delay or duration defined), whereas the second uses the transition passed in through the update() interface.
Strange is that:
what worked for another dependent animation did not for this.
the staggered delays and their associated durations were nevertheless accepted by the original version, allowing me to be misled by console logs..
Just to round this topic off, I can point out the the following (event-based) approach seems to work just as well as the tween variant with non-interpolable values documented above. I can switch freely between the two with no apparent difference in the resulting animations:
transition
.select("#chordinput") // id attribute of the input element
.each("start", setChordname( waveplot.chordname ));
Thug
Is there an equivalent of an 'on interrupt' function when using dojo.fx animations?
On my site, I clear an area by sliding the div off the screen to the left and then clearing the innerHTML. So that the div is available for future use in the same place, I set its final position to be equal to its original position (though it's empty and invisible, so the user doesn't see). I do this by referencing the position when the function is fired to avoid hard coding the position in.
function clear (node) {
// get the current position
var position = domGeom.position (node, true);
// slide the calendar off the screen
var anim = dojo.fx.slideTo ({
node: node,
left: -2000,
unit: "px"
});
// attach on onEnd function
dojo.connect (anim, "onEnd", function (n1, n2) {
node.innerHTML = "";
// Reset the node's position
domStyle.set (node, "left", position.x + "px");
});
anim.play();
}
The problem is that if the user clicks 'clear' while the function is in progress, for example if they accidentally double click, then the 'position' variable takes the value of the node mid-animation. If I later put some content in the node, it's in the wrong place, or sometimes completely off screen.
What I was thinking of doing was adding a listener to the animation so that if it was ever interrupted, it would stop the animation and instead execute the 'onEnd' function immediately, so that the second clear function would have the correct position variable.
Unfortunately, I can't find such a listener; could anyone point me in the right direction, or suggest an alternative solution?
You might be interrupting the flow of events in your page, but you're not really 'interrupting' in Animation terms: there's no way an Animation could give you an event to tell you that Clear has been pressed, I'm afraid.
If you want the animation to be stopped when the user presses Clear, you'll have to stop the animation manually when the user presses Clear: Dojo can't automatically detect there's any link between the two things, and indeed there may well be other animations that you want to continue even if the user does press Clear.
So, you'll probably be looking to call .stop on the animation when appropriate.
I am trying to spin a 3D Gameobject in unity. It is actually a cylinder with just a texture of a poker chip on it. I want to spin it 360 degrees once it has collided with a raycast. It is working just fine in the Unity emulator, however, on the device itself the chip comes to a stop after its spin and then continues to spin in an endless loop. Here is a snippet of the code in question. Thank you for any help in advance.
// Spin the chip
if (Animate) {
if (Speed > 0 && Chip.tag.Contains("Chip")) {
Chip.transform.Rotate(0, Speed*Time.deltaTime, 0);
Speed -= 3;
Debug.Log(Speed);
}
else {
// Reset
Animate = false;
Speed = 360;
Chip.transform.localRotation = Quaternion.Euler(0.0,0.0,0.0);
}
}
To summorize this the best I can the gameobject Chip is assigned when it collides on raycast as such
// Set the chip
Chip = hit.transform;
Everything is done in the update function. Once the raycast hits it calls a betting function then after the betting is calculated it changes the Boolean Animate to true causing the spinning of the chip.
Something is setting Animate = true in some other code, hard to tell whats going on without seeing the rest of it.
Put some debug next to every spot where Animate is set to true, you should see something else setting it, only possible explanation as to why it continues to spin.
Another option is to use the Animation tool and instead of rotating, you just play the animation which performs the rotation for you.
Edit: Chances are its around the touch code, cause when you debug in the editor your using key strokes. A gotcha I've experienced a few times.
James Gramosli is correct in that some other code is triggering the animation again and it is most likely your touch code. It is a common problem when moving between editor and a touch-enabled device. You can determine if this is the case by using the UnityRemote to verify the control flow of your code.
That said, I would change your code to the following which removes the spin code from the Update loop that runs every frame. It is a small optimization, but primarily it cleans up the architecture and makes it more modular and a little neater.
It is not clear from your code snippet, but I will assume you are using UnityScript.
In your script that handles the touch code when you click on the chip, insert this line:
hit.transform.SendMessage("Spin", hit.transform, SendMessageOptions.DontRequireReceiver);
Put this code in a separate script called "SpinChip" and then add the script to your chip object.
var StartSpeed = 360.0;
var Deceleration = 3.0;
function Spin()
{
if (Animating)
{
print("Chip is already spinning, not starting another animation");
return;
}
/*
This code isn't necessary if this exists in a separate script and is only ever attached to the clickable chip
if (!gameObject.tag.Contains("Chip"))
{
print("That wasn't a chip you clicked");
return;
}
*/
print("Chip has been told to spin");
StartCoroutine(SpinningAnimation);
}
function SpinningAnimation()
{
print("Chip spin start");
transform.localRotation = Quaternion.identity;
Speed = StartSpeed;
Animating = true;
while (Speed > 0)
{
transform.Rotate(0, Speed*Time.deltaTime, 0);
Speed -= Deceleration;
yield; // wait one frame
}
print("Chip has completed the spin");
Animating = false;
}
What this code does is create a co-routine that runs once per update loop when activated that will spin the chip for you, and is independent of your actual button clicking code.
var rotSpeed: float = 60; // degrees per second
function Update(){
transform.Rotate(0, rotSpeed * Time.deltaTime, 0, Space.World);
}
Here is a code that rotates your game object, you can use it just with a vector 3 :transform.Rotate(x, y, z); or with Space transform.Rotate(x, y, z, Space.World);
rotSpeed is the rotation speed.
In your update function . The Bool variable Animate may becoming true . This may be reason your cylinder continues to rotate.
Other Solution is : You can create an animation of your cylinder and then take a stopwatch . So that after sometime you can stop you animation using the time of stopwatch