I am using Ext.js 5.0, and trying to revert opacity animation as follows:
var errorLabel = Ext.ComponentQuery.query( '#errorLabel' )[0];
errorLabel.show();
new Ext.util.DelayedTask( function() {
errorLabel.animate( {
duration: 500,
to:
{
opacity: 0
},
listeners:
{
afteranimate: function()
{
// HERE I TRIED LOT'S OF METHODS TO SET BACK THE OPACITY PARAMETER:
errorLabel.setStyle( 'opacity: 1.0' );
//errorLabel.setOpacity( 100 );
// ...
},
scope: this
}
} );
} ).delay( 3000 );
But no success ...
Any clue how can I revert the animation parameters? Is there a general method for doing so?
To set style, try using this syntax:
errorLabel.setStyle('opacity', '1');
Related
No collisions between map layer and player sprite. But collisions between world bounds work. What is wrong?
I tried different workarounds that could find online and none of them worked.
Game config
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
backgroundColor: "#f",
physics: {
default: 'arcade',
arcade: {
gravity: { y: gameState.gravity },
debug: true
}
},
scene: {
preload,
create,
update
}
};
Code in create() regarding the tilemap and its layers and the character
gameState.map = this.add.tilemap('map');
gameState.dungeonTileset = gameState.map.addTilesetImage('dungeon', 'dungeonTiles');
gameState.backgroundLayer = gameState.map.createStaticLayer('Background', gameState.dungeonTileset);
gameState.mapLayer = gameState.map.createStaticLayer('Map', gameState.dungeonTileset);
gameState.miscLayer = gameState.map.createStaticLayer('Misc', gameState.dungeonTileset);
gameState.mapLayer.setCollisionByExclusion([-1]);
this.physics.world.bounds.width = gameState.mapLayer.width;
this.physics.world.bounds.height = gameState.mapLayer.height;
gameState.player = this.physics.add.sprite(73, 398, 'player', 0);
gameState.player.setCollideWorldBounds(true);
this.physics.add.collider(gameState.player, gameState.mapLayer);
No warning and no errors are coming up in the console. I don't know what to do anymore.
Thanks in advance!
I have addited a little bit the original example so you can see how it looks, I think the problem in your code is the line concerning gameState.mapLayer.setCollisionByExclusion([-1]); but am not sure because I can't see how the tilemap is created
var config = {
type: Phaser.WEBGL,
width: 800,
height: 576,
backgroundColor: '#2d2d2d',
parent: 'phaser-example',
loader: {
baseURL: 'https://labs.phaser.io',
crossOrigin: 'anonymous'
},
pixelArt: true,
physics: {
default: 'arcade',
arcade: { gravity: { y: 300 } }
},
scene: {
preload: preload,
create: create,
update: update
}
};
var game = new Phaser.Game(config);
var map;
var cursors;
var player;
var groundLayer;
function preload ()
{
this.load.image('ground_1x1', 'assets/tilemaps/tiles/ground_1x1.png');
this.load.tilemapTiledJSON('map', 'assets/tilemaps/maps/tile-collision-test.json');
this.load.image('player', 'assets/sprites/phaser-dude.png');
}
function create ()
{
map = this.make.tilemap({ key: 'map' });
var groundTiles = map.addTilesetImage('ground_1x1');
map.createDynamicLayer('Background Layer', groundTiles, 0, 0);
groundLayer = map.createDynamicLayer('Ground Layer', groundTiles, 0, 0);
groundLayer.setCollisionBetween(1, 25);//here
player = this.physics.add.sprite(80, 70, 'player')
.setBounce(0.1);
this.physics.add.collider(player, groundLayer);
cursors = this.input.keyboard.createCursorKeys();
this.cameras.main.setBounds(0, 0, map.widthInPixels, map.heightInPixels);
this.cameras.main.startFollow(player);
}
function update ()
{
player.body.setVelocityX(0);
if (cursors.left.isDown)
{
player.body.setVelocityX(-200);
}
else if (cursors.right.isDown)
{
player.body.setVelocityX(200);
}
if (cursors.up.isDown && player.body.onFloor())
{
player.body.setVelocityY(-300);
}
}
<script src="//cdn.jsdelivr.net/npm/phaser#3.17.0/dist/phaser.min.js"></script>
This is my first attempt at building an a-frame experience, and I'm doing so by cobbling together multiple community components.
I'm currently attempting to implement a spritesheet animation using aframe-spritesheet-component ( https://github.com/EkoLabs/aframe-spritesheet-component ) and having an issue getting it to play well with others.
My build here: https://afantasy.github.io/spritetest/
So far, I've managed to get the spritesheet animation to loop through once, after which it causes a total freeze of the entire environment.
I am not sure whether it's a bad interaction with the other components I've installed, or with the aframe framework itself.
From what I gather from the console, something is up with the update / tick functions.
I've managed to isolate the direct cause to this bit of code I grabbed directly from the aframe-spritesheet-component example on github ( https://ekolabs.github.io/aframe-spritesheet-component/examples/rowscols/ )
<!-- SPRITE ANIMATION LOOP -->
<script type="text/javascript">
var animation = { progress: 0 };
var tween = new TWEEN.Tween(animation)
.to({ progress: 1 }, 1000)
.onUpdate(function(){
document.querySelector('a-image').setAttribute('sprite-sheet', 'progress', animation.progress);
});
tween.onComplete(function() { animation.progress = 0; });
tween.chain(tween);
tween.start();
</script>
Super stumped and sure how to proceed from here, any hints would be appreciated.
Here is the code for an alternative spritesheet animation component that might work for you, without requiring the external TWEEN.js dependency:
AFRAME.registerComponent('spritesheet-animation', {
schema:
{
rows: {type: 'number', default: 1},
columns: {type: 'number', default: 1},
// set these values to play a (consecutive) subset of frames from spritesheet
firstFrameIndex: {type: 'number', default: 0},
lastFrameIndex: {type: 'number', default: -1}, // index is inclusive
// goes from top-left to bottom-right.
frameDuration: {type: 'number', default: 1}, // seconds to display each frame
loop: {type: 'boolean', default: true},
},
init: function()
{
this.repeatX = 1 / this.data.columns;
this.repeatY = 1 / this.data.rows;
if (this.data.lastFrameIndex == -1) // indicates value not set; default to full sheet
this.data.lastFrameIndex = this.data.columns * this.data.rows - 1;
this.mesh = this.el.getObject3D("mesh");
this.frameTimer = 0;
this.currentFrameIndex = this.data.firstFrameIndex;
this.animationFinished = false;
},
tick: function (time, timeDelta)
{
// return if animation finished.
if (this.animationFinished)
return;
this.frameTimer += timeDelta / 1000;
while (this.frameTimer > this.data.frameDuration)
{
this.currentFrameIndex += 1;
this.frameTimer -= this.data.frameDuration;
if (this.currentFrameIndex > this.data.lastFrameIndex)
{
if (this.data.loop)
{
this.currentFrameIndex = this.data.firstFrameIndex;
}
else
{
this.animationFinished = true;
return;
}
}
}
let rowNumber = Math.floor(this.currentFrameIndex / this.data.columns);
let columnNumber = this.currentFrameIndex % this.data.columns;
let offsetY = (this.data.rows - rowNumber - 1) / this.data.rows;
let offsetX = columnNumber / this.data.columns;
if ( this.mesh.material.map )
{
this.mesh.material.map.repeat.set(this.repeatX, this.repeatY);
this.mesh.material.map.offset.set(offsetX, offsetY);
}
}
});
A complete example of the component in code:
https://github.com/stemkoski/A-Frame-Examples/blob/master/spritesheet.html
Live preview of example:
https://stemkoski.github.io/A-Frame-Examples/spritesheet.html
Your app.js is minified, so it's hard to trace the issue. However, I replaced the Tween library in your version with the exact Tween library used on their version and it seemed to work:
https://stackoverflow-51620935.glitch.me
My guess is that either you may be forgetting to configure Tween (I have never used this library before) or are using an unsupported version (the console also shows several warnings about deprecated methods).
I copy/pasted your code into that glitch above, and changed line 96 to include the overwrite:
<!-- SPRITE ANIMATION LOOP -->
<script src="tween-rewrite.js"></script>
<script type="text/javascript">
var animation = { progress: 0 };
var tween = new TWEEN.Tween(animation)
.to({ progress: 1 }, 1000)
.onUpdate(function(){
document.querySelector('a-image').setAttribute('sprite-sheet', 'progress', animation.progress);
});
tween.onComplete(function() { animation.progress = 0; });
tween.chain(tween);
tween.start();
</script>
Ran into the same problem. Looping the animation like this works for me:
<script>
function smokeLoop(){
var animation = { progress: 0 };
var tween = new TWEEN.Tween(animation)
.to({ progress: 1 }, 4000)
.onUpdate(function(){
document.querySelector('a-image').setAttribute('sprite-sheet', 'progress', animation.progress);
});
tween.onComplete(function() { animation.progress = 0; smokeLoop();});
tween.start();
}
smokeLoop();
</script>
What is the best pattern, in react native, to animate components on state change?
For example I have a list of elements and tapping on one I want it to disappear and the ones below him to 'get up' filling the missing space
How can I make the transition smooth?
React-natives own animated API works really well.
Basically you have a value in state, which you connect with a style props, and change that value over time. (for examples follow link)
For smooth animations use usenativedriver (not always possible) and also, make sure you don't have debugger runnning in emulated/real device
EDIT: 2018-05-31
This is an example of how I've used it. Probably exist other ways of doing it
import { Animated, Text} from 'react-native';
class ShowCaseAnimation extends Component {
state = {
animations: {
height: new Animated.Value(0),
fade: new Animated.Value(0),
}
}
componentDidMount() {
const { height, fade } = this.state.animations;
if (this.props.animate) {
doneAnimation({ height, fade }).start(() => {
// Do stuff after animations
});
}
}
render() {
const { animations } = this.state;
return (
<Animated.View
style={{
height: animate? animations.height : 300,
opacity: animate? animations.fade: 1,
// other styling
}}
>
<Text> All your base are belong to us </Text>
</Animated.View>
);
}
}
*doneAnimation: *
import { Animated, Easing } from 'react-native';
export const doneAnimation = ({ height, fade }) => Animated.parallel([
Animated.timing(height, {
toValue: 300,
easing: Easing.elastic(),
duration: 500,
delay: 1500,
}),
Animated.timing(fade, {
toValue: 1,
easing: Easing.ease,
duration: 1000,
delay: 1500,
}),
]);
export default doneAnimation;
doneAnimation will change the state and perform the described animations.
This is how you can trigger an animation on state change in a functional component.
Say you have a Button that changes state with onPress:
<Button title="toggle" onPress={() => setValue(!Value)} />
then you can trigger the animation inside a useEffect with the Value
that changes in the dependency array:
const [Value, setValue] = useState(true);
useEffect(() => {
// Input your animation here
// ...
}, [Value]);
I am using react-navigation Transitioner to create a custom StackNavigator. When using useNativeDriver: true in my transition configuration, the animation for the transition only runs the first time. When set to false, it works as expected.
Note: Whilst setting it to false does fix my problem, I get choppy performance on Android without it, even in production mode.
Below snippet is my navigation view
render() {
return (
<Transitioner
configureTransition={this._configureTransition}
navigation={this.props.navigation}
render={this._render}
/>
);
}
_configureTransition = () => {
return { useNativeDriver: true };
}
_render = (transitionProps) => {
return transitionProps.scenes.map(scene => this._renderScene(transitionProps, scene));
}
_renderScene = (transitionProps, scene) => {
const { layout, position } = transitionProps;
const { index } = scene;
const translateX = position.interpolate({
inputRange: [index - 1, index, index + 1],
outputRange: [layout.initWidth, 0, 0],
});
const animationStyle = {
position: 'absolute',
width: '100%',
height: '100%',
backgroundColor: '#FFF',
transform: [{ translateX }],
};
const Scene = this.props.router.getComponentForRouteName(scene.route.routeName);
return (
<Animated.View key={scene.key} style={animationStyle}>
<Scene />
</Animated.View>
);
}
Below is a screen cap of the problem. Note how the first transition is animated, whilst future ones are not (the 'back' navigation should be animated too)
How can I rotate ImageSurface around it's origin if I have applied translate to it ?
It does not rotate around origin. Can someone explain me is it using "align point" as center of rotation ?
EDIT
My ImageSurface is rotating like it has distante point of rotation and it scales up.
function _createFb() {
this.fbLogo = new ImageSurface({
size : [true, true],
content : 'images/fb.png',
properties: {
zIndex: 10
}
});
var fbModifier = new StateModifier({
origin: [0.5,0.5],
align:[0.5,0.5],
transform: Transform.scale(0.4,0.4,1)
});
var fbPosModifier = new StateModifier({
transform: Transform.translate(-250,520,0)
});
this.fbLogo.on("mouseleave", function(){
fbModifier.setTransform(Transform.rotateZ(Math.PI/4), { duration: 1000});
});
this.layout.content.add(fbModifier).add(fbPosModifier).add(this.fbLogo);
}
MY SOLUTION
function _createFb() {
this.fbLogo = new ImageSurface({
size : [true, true],
content : 'images/fb.png',
properties: {
zIndex: 10
}
});
var fbModifier = new StateModifier({
origin: [0.5,0.5],
align:[0.5,0.5],
transform: Transform.scale(0.4,0.4,1)
});
var fbPosModifier = new StateModifier({
transform: Transform.translate(-250,520,0)
});
var fbRotateModifier = new Modifier();
var transitionable = new Transitionable(0);
this.fbLogo.on("mouseleave", function(){
transitionable.reset(0);
fbRotateModifier.transformFrom(function(){
return Transform.rotateZ(transitionable.get());
}
);
transitionable.set(2 * Math.PI, {curve: "inOutQuad", duration: 500});
});
this.layout.content.add(fbModifier).add(fbPosModifier).add(fbRotateModifier).add(this.fbLogo);
}
This can be done using straight Famo.us, no need to modify CSS. Here's an example. Some of these modifiers can be combined, but I'm breaking them up for clarity. Centering the origin is first applied to a Surface. Rotations now pivot about the newly defined origin. Then the rotated Surface is translated.
var surface = new Surface({
size : [100,100],
properties : {background : 'red'}
});
var translateModifier = new Modifier({
transform : Transform.translate(100,0,0)
});
//rotates around and around based on your current system time
var rotateModifier = new Modifier({
transform : function(){ return Transform.rotateZ(Date.now() * .001) }
});
var centerModifier = new Modifier({
origin : [.5,.5]
});
context
.add(translateModifier)
.add(rotateModifier)
.add(centerModifier)
.add(surface)
I had similar problems to spin an element. The transform origin needs to be set center (50% 50%). I used css class for this.
.myClass {
-webkit-transform-origin: 50% 50% !important;
}
var myElem = new Surface({
size: [40, 40],
classes: ['myClass']
});
this.myElemModifier = new StateModifier();
// called from user action
this.myElemModifier.setTransform(
Transform.rotateZ(Math.PI), { duration: 5000 }
);