I am trying to integrate it into an existing Paper.js application to replace the original .tweenTo function (http://paperjs.org/reference/tween/). The only issue I am facing so far is the "chaining" of the position or point property animations:
https://codepen.io/yevsim/pen/GRmPBZB
paper.install(window)
paper.setup(canvas);
const text = new PointText({
point: new Point(100, 100),
fontFamily: "sans-serif",
fontWeight: "bold",
fontSize: 48,
fillColor: 'black'
});
text.content = 'Move me';
const timeline = gsap.timeline();
timeline.to(text.point, { duration: 1, x: '+=100' });
timeline.to(text.point, { delay: 1, duration: 1, x: '+=100' });
For the reason unknown to me, it moves the text back to its original position before doing the second animation (i.e. instead of going from 100 -> 200 -> 300, it goes 100 -> 200 -> 100 -> 200). Chaining other properties animation e.g. width, height, color, opacity works as expected. I tried to play with replacing point with position, combining them together, but nothing worked for me.
I'm not really sure why but this will work if you store text.point into a variable and use this variable instead of a reference to the actual object when creating your timeline.
Based on your code, here a corrected version:
const text = new PointText({
point: new Point(100, 100),
fontFamily: 'sans-serif',
fontWeight: 'bold',
fontSize: 48,
fillColor: 'black',
content: 'Move me'
});
// Use a variable to reference the property to animate.
const point = text.point;
const timeline = gsap.timeline();
timeline.to(point, { duration: 1, x: '+=100' });
timeline.to(point, { delay: 1, duration: 1, x: '+=100' });
Related
I'm making a game with Phaser, and I need to have an animation for the health bar going down dynamically stop on a frame, and I couldn't find any clear documentation on the stopOnFrame() method, or the this.anims.getFrame(index) method, both of which woulden't work. I believe that stopOnFrame accepts a frame object, not a frame number but I coulden't figure out how to get that specific frame, as the getFrame() method returned undefined. If there's something I'm missing, my ideal solution looks something like this:
this.hpBar.play({key: 'damageAnimation', startFrame: this.hp})
this.hpBar.stopOnFrame(this.hpBar.getFrame(this.hp - amountOfDamage))
Thanks for any suggestions, cheers!
PS: I know there's some more nuance to how I would use the animations in forwards and reverse to properly create this effect, the example is purely for demonstration.
Two points, you would have to pass a Phaser.Textures.Frame to the stopOnFrame function, and as far as I know the function getFrame doesn't exist (atleast on the phaser sprite GameObject, as shown in your code).
You can use the function getFrameAt on the Animation object, the index has to be here only a valid integer, in the range from 0 - to max frame of the animation.
(btw.: here is the link to the documenation of the stopOnFrame function)
Info: the frame index-count, is based on the frames of the specific animation, not the frame in the spritesheet. (In this example the sprite frame index of the kick is 12, but in the kick animation the index for that specific frame is 2)
Here a Demo:
document.body.style = 'margin:0;';
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
scene: {
preload,
create
}
};
function preload(){
this.load.spritesheet('brawler',
'http://labs.phaser.io/assets/animations/brawler48x48.png',
{ frameWidth: 48, frameHeight: 48 }
);
this.load.image('brawler-sheet',
'http://labs.phaser.io/assets/animations/brawler48x48.png');
}
function create () {
this.add.text(10,10, 'Click, to Stop on kick (third frame)')
.setScale(1.5)
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
this.anims.create({
key: 'kick',
frames: this.anims.generateFrameNumbers('brawler',
{ frames: [ 10, 11, 12, 13, 10 ] }),
frameRate: 8,
repeat: -1,
repeatDelay: 0
});
this.add.image(140, 20, 'brawler-sheet')
.setOrigin(0)
const cody = this.add.sprite(100, 90);
cody.setScale(3);
cody.play('kick');
this.input.on('pointerdown', () => {
cody.stopOnFrame(cody.anims.currentAnim.getFrameAt(2))
});
}
new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>
But for a simple healt-bar, I would use a phaser tween, not an animation, like this you can set the value more precise, you can easily update the max-health and "animation" is easy.
Here a demo how I would do it (two visula alternatives):
(I would opt for the second version, if you have some nice heart images or so, I could find a better image for the demo)
document.body.style = 'margin:0;';
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
scene: {
create,
preload
},
banner: false
};
function preload ()
{
this.load.image('mushroom',
'https://labs.phaser.io/assets/sprites/mushroom16x16.png');
}
let healthMax = 32*5
function create () {
this.add.text(10,10, 'Click, to animate healthbar')
.setScale(1.5)
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
this.healthbarBG = this.add.rectangle(10, 50, 32*5, 10, 0xffffff)
.setOrigin(0);
this.healthbar = this.add.rectangle(12, 52, healthMax - 4, 10 - 4, 0xff0000)
.setOrigin(0);
this.add.text(10, 75, 'Or abit more flashy')
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
let tilespriteBG = this.add.tileSprite(10, 100, 16*5, 16, 'mushroom')
.setOrigin(0)
.setScale(2);
tilespriteBG.setTint(0x2a2a2a)
let tilesprite = this.add.tileSprite(10, 100, 16*5, 16, 'mushroom')
.setOrigin(0)
.setScale(2);
this.input.on('pointerdown', () => {
// remove 50% health
let newHealthWidth = healthMax * .5;
this.tweens.add({
targets: this.healthbar,
width: newHealthWidth,
duration: 750,
ease: 'Power2',
/* this two following properties must be remove, just for demo
yoyo: true,
repeat:-1*/
});
this.tweens.add({
targets: tilesprite,
width: { to: 16 * 5 * .5, from: 16 * 5},
duration: 750,
/* this two following properties must be remove, just for demo
yoyo:true,
repeat:-1*/
});
})
}
new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>
modifying the ease and/or the duration property (and others), you can make the animation suitable (and spicy) for the most usecases.
I'm trying to loop an animation with the Framer Motion library after a small delay. The animation itself will play when it's mounted, on the webpage refresh, however does not repeat.
Iv'e looked through the docs and this seems to be similar syntax.
const AnimateTrial = {
initial: {
opacity: 0,
x: -100,
y: -35,
scale: 0.9,
},
animate: (i) => {
const delay = 5 + i * 0.5;
return {
opacity: 1,
x: -10,
y: -35,
transition: {
opacity: { delay, duration: 1.5 },
x: { delay, duration: 1.5},
repeatType: "Infinity",
repeatDelay: 5,
},
};
}
Does anyone have an idea? Everything works minus bottom two lines!
The properties inside your transition object are not right. Use repeat in place of repeatType, Write it something like this
transition={{ repeat: Infinity, repeatDelay: 5 }}
If you check the docs repeateType property accepts only "loop" "reverse" "mirror" and not "Infinity".
I have a graph, whereby users can add plotlines themselves by clicking a button. Often, those plotlines are added outside the current view of the graph, which means the user has to manually zoom out to search for the plotline they added. Is it possible for HighStock to dynamically change its current view based on added Plotlines?
Check out this example here:
http://jsfiddle.net/Ltgzwpo2/2/
If you click on the button, a plotline is added OUTSIDE of the current view, i.e. you need to zoom out to find the plotline. Is it possible for the chart to dynamically zoom out itself upon the adding of a plotline?
This is the code I use to add a plotline:
$("#button").click(function() {
chart.xAxis[0].addPlotLine({
value: Date.UTC(2015, 10, 5),
color: "green",
width: 1,
dashStyle: 'ShortDash',
label: {
text: "this appeared outside of the current view!",
align: 'left',
y: 5,
x: 3,
style: {
fontSize: "12px"
}
},
zIndex: 10
});
});
You can use axis.setExtremes() to set the visible area.
var value = Date.UTC(2015, 10, 5);
chart.xAxis[0].addPlotLine({
value: value,
color: "green",
width: 1,
dashStyle: 'ShortDash',
label: {
text: "this appeared outside of the current view!",
align: 'left',
y: 5,
x: 3,
style: {
fontSize: "12px"
}
},
zIndex: 10
});
var range = 1000 * 3600 * 24 * 30;
chart.xAxis[0].setExtremes(value - range, value + range)
example: http://jsfiddle.net/cqwk84dz/
I'm using cirque.js plugin to show circle percentage values drawn with a canvas.
Here's a JSFIDDLE I made that should contain all the info with plugin code.
Initially, the circle gets drawn correctly, with the correct value.
Issue: When I try to update the value via a function on clicking a button, nothing happens, not working, I think the canvas needs to be drawn again with the new value?
Q: How can I update the circle percentage value asynchronously?
$('.cirque').cirque ({ //this works
radius: 40,
value: 65,
total: 100,
trackColor: '#ccc',
arcColor: '#5cb85c',
label: 'percent',
lineWidth: 12
});
$('#update').click(function (e) {
updateCircle(50); //this does not work
});
function updateCircle(val){
$('.cirque').cirque ({
radius: 40,
value: val,
total: 100,
trackColor: '#ccc',
arcColor: '#5cb85c',
label: 'percent',
lineWidth: 12
});
}
I've not find any function to update value in this plugin. But you can update value with a trick. Replace the div having class cirque with a same div and initialize it with new value like following. Hope this will help you.
function updateCircle(val){
var cirque=$('<div class="cirque"></div>');
$('.cirque').replaceWith(cirque);
cirque.cirque ({
radius: 40,
value: val,
total: 100,
trackColor: '#ccc',
arcColor: '#5cb85c',
label: 'percent',
lineWidth: 12
});
}
Updated Fiddle: https://jsfiddle.net/8d9sw1yg/2/
I have been developing an app using Kinetic which uses several layers to keep things organised and I have draggable elements in more than one layer. I am finding that when one layer is dragged, shapes on another layer are no longer draggable.
In the cut-down example supplied, the blue Rects in the upper layer are no longer draggable once the lower layer has been dragged, I can't see why this is.
I have tried looking through the documentation and various tutorials, asking on Stackoverflow is my last resort so I hope someone can help!
I have tried setting dragOnTop to false on the draggable layer by the way, this doesn't change the result.
Thanks,
Oscar
http://jsfiddle.net/EveryoneMustWin/QRaxJ/
var kItems = {};
kItems.stage = new Kinetic.Stage({
container: 'container',
width: $("#container").width(),
height: $("#container").height()
});
kItems.lowerLayer = new Kinetic.Layer({
scale: 1.0,
id: "lower",
draggable: true,
dragBoundFunc: function(pos) {
return {
x: pos.x,
y: pos.y
}
}
});
kItems.upperLayer = new Kinetic.Layer({
scale: 1.0,
id: "upper"
});
kItems.stage.add(kItems.lowerLayer);
kItems.stage.add(kItems.upperLayer);
kItems.backdrop = new Kinetic.Rect({
x: 50,
y: 50,
width: 200,
height: 200,
stroke: '#822',
strokeWidth: 2,
fill: '#b62',
opacity: 1,
id: 'backdrop'
});
kItems.lowerLayer.add(kItems.backdrop);
kItems.block1 = new Kinetic.Rect({
x: 100,
y: 100,
width: 20,
height: 20,
stroke: '#228',
strokeWidth: 2,
fill: '#65b',
opacity: 1,
id: 'block1',
draggable: true
});
kItems.upperLayer.add(kItems.block1);
kItems.block2 = new Kinetic.Rect({
x: 180,
y: 100,
width: 20,
height: 20,
stroke: '#228',
strokeWidth: 2,
fill: '#65b',
opacity: 1,
id: 'block2',
draggable: true
});
kItems.upperLayer.add(kItems.block2);
kItems.lowerLayer.draw();
kItems.upperLayer.draw();
kItems.lowerLayer.on("dragmove", function() {
kItems.upperLayer.setAttrs({x:this.getX(), y:this.getY()});
kItems.upperLayer.draw();
});
My workaround before this is fixed was to call layer.drawHit() on my dragEnd handler for the layer that became unresponsive (see my comment above). This has made it possible for me to continue using the newest version (there are many nice improvements that I didn't want to lose by using 4.3.3). Hope this helps.