I am trying to create a web app using React VR and run it using Samsung Gear VR.
I could not see the default white dot (VR pointer) while in VR mode in my scene. Consequently methods such as "onInput" and "onClick" are not working. The same methods work quite fine if I view the same scene outside VR mode - even using the browser provided in Gear VR.
Am I missing something? How do I access those methods while in VR mode in Gear VR?
Example code that works fine in normal web browser (including the one in Gear VR), but not when I am in VR.
<Text
style={{
// backgroundColor: '#777879',
fontSize: 0.2,
transform: [{translate: [0, 0, -5]}],
color: this.state.textColor
}}
onEnter={() => this.setState({textColor: 'gold'})}
onExit={() => this.setState({textColor: 'white'})}>
This text will turn gold when you look at it.
</Text>
You need to add a raycaster:
To do so, you need to do the following:
In your project, go to <project root>/vr/client.js.
Just before the init method, add a SimpleRaycaster constant.
const SimpleRaycaster = {
getType: () => "simple",
getRayOrigin: () => [0, 0, 0],
getRayDirection: () => [0, 0, -1],
drawsCursor: () => true
};
function init(bundle, parent, options) {
//...
Then, in the init method, set cursorVisibility: visible and add the raycaster to the array of raycasters:
function init(bundle, parent, options) {
const vr = new VRInstance(bundle, 'Example', parent, {
raycasters: [
SimpleRaycaster // Add SimpleRaycaster to the options
],
cursorVisibility: "visible", // Add cursorVisibility
enableHotReload: true,
...options,
});
vr.render = function() {
// Any custom behavior you want to perform on each frame goes here
};
// Begin the animation loop
vr.start();
return vr;
}
window.ReactVR = {init};
That's it. Now you should have a white dot in the middle of your view.
Related
Hello everyone I'm trying to make a complex animation And I'm new to the framer motion so I need help if it's possible.
I'm trying to do this animation
all the animation will be revealed when scrolling but I don't Know How?
I tried this example but I think it will not take me any where example
So, Any clue please?
Thanks in advance.
i think useAnimationControls will help, but i think there is another better solution or another way, but any way i wish this help you here is the documentation, it says that it returns a promise (and also can be used in async function with await).
like the following code:
import { useAnimationControls, motion } from "framer-motion"
export default function App() {
let controls = useAnimationControls()
controls
.start({
opacity: 1,
backgroundColor: "red",
color: "white",
})
.then(() =>
controls.start({
color: "black",
backgroundColor: "lightgreen",
x: -100,
})
)
.then(() => {
controls.start({
opacity: 0,
x: 100,
})
})
return (
<>
<motion.div initial={{ opacity: 0 }} animate={controls}>
hi there
</motion.div>
</>
)
}
the above code will do these things below respectively:
will increase the opacity to 1 and change the color & bg color
then it will change color & bg color again and change the x position
then will decrease the opacity to 0 and x position too
here is another animation library that is simple and also may be useful to use named animejs, and also they have a friend and non-boaring documentation you can check it here
In my React Native project I'm using the Switch component. It can be switched directly by pressing it, but I also want to let the user change it by pressing nearby related items.
It of course animates the switching when pressed, but when I changed its state using setState() it just jumps directly to the other position without animation.
Is there a way I can programmatically trigger the animation when changing its state from code?
(There is a question with a similar wording but it seems to be to an unrelated problem I can't quite work out.)
Depends a little on the approach you're taking, but I'd say your best bet is with Animated (which is part of React Native).
You can do something like this:
render(){
var animVal = new Animated.Value(0);
Animated.timing(animVal, {toValue: 1, duration: 300}).start();
var animatedViewStyles =
{
marginLeft: animVal.interpolate({
inputRange: [0, 1],
outputRange: this.state.switchOn ? [100, 0] : [0, 100],
}),
// add some other styles here
color: 'green'
};
}
return (
<Animated.View style={animatedViewStyles}>
<TouchableHighlight onPress(() => this.setState({switchOn: !this.state.switchOn}))><Text>This is my switch</Text></TouchableHighlight>
</Animated.View>
);
See the docs https://facebook.github.io/react-native/docs/animated.html for more info.
Angular 1 handles enter, leave and move animations. The Angular 2 documentation describes how to do enter and leave animations (void => * and * => void), but how can one implement move animations in Angular 2?
Read Angular's official guide for animations if you haven't already.
You define animation states and the transitions between them. For instance:
animations: [
trigger('heroState', [
state('inactive', style({
backgroundColor: '#eee',
transform: 'scale(1)'
})),
state('active', style({
backgroundColor: '#cfd8dc',
transform: 'scale(1.1)'
})),
transition('inactive => active', animate('100ms ease-in')),
transition('active => inactive', animate('100ms ease-out'))
])
]
inactive and active can be replaced with any arbitrary strings and you can have as many unique states as you wish, but there must be a valid transition to each one or else the animation won't happen. void is a special case for when elements aren't yet attached to the view and * is a wildcard, applying to any of the defined states.
EDIT:
Hmm... well, for one thing, you might be able to use this Sortable library. It claims to support Angular 2 and is pure Javascript (no jQuery) so theoretically, it should work well but I have not used it myself.
Otherwise, I am certain it would be possible purely inside Angular 2, but it would probably require some fairly clever code. Relative motion (irrespective of a component or element's particular position) is easy with transform: translateY() property. The problem is that Angular 2 animation states only apply if the component is in that state so if you give it a translateY(-20px) to move an element up a position, it's not going to keep that position if you want to want to move it up again.
See this plunker for the solution I have come up with.
template: `
<div #thisElement>
<div class="div-box" #moveState="state">Click buttons to move <div>
</div>
<button (click)="moveUp()">Up</button>
<button (click)="moveDown()">Down</button>
`,
I defined animation states for 'moveUp' and 'moveDown' that ONLY apply during the actual animation and a 'static' state that is applied when the component isn't moving.
animations: [
trigger('moveState', [
state('moveUp', style({
transform: 'translateY(-30px)';
})),
state('moveDown', style({
transform: 'translateY(30px)';
})),
state('static', style({
transform: 'translateY(0)';
})),
transition('* => moveUp', animate('100ms ease-in')),
transition('* => moveDown', animate('100ms ease-out')),
transition('* => static', animate('0ms linear'))
])
]
For the function that actually initiates the animation, it applies the 'moveUp' or 'moveDown' state and then starts a timeout that triggers a callback after an amount of time equal to the length of the transition. In the callback, it sets the animation state to 'static' (the transition to the 'static' state is set to 0 ms so we don't actually animate it moving back to a static position). Then we use Renderer to apply a translation for where we want it to ultimately end up (calculated using a position property that would define it's position relative to where it was initially, not it's position in the array). The Renderer applies its styles separately from the animation so we can apply both without them conflicting with each other.
export class MyComponent {
state = 'static';
#ViewChild('thisElement') thisBox: ElementRef;
position: number = 0;
//...
moveUp() {
this.state = 'moveUp';
this.position--;
setTimeout(() => {
this.state = 'static';
this.renderer.setElementStyle(this.thisBox.nativeElement, 'transform', 'translateY(' + String(this.position * 30) + 'px)');
}, 100)
}
moveDown() {
this.state = 'moveDown';
this.position++;
setTimeout(() => {
this.state = 'static';
this.renderer.setElementStyle(this.thisBox.nativeElement, 'transform', 'translateY(' + String(this.position * 30) + 'px)');
}, 100)
}
//...
}
This is only an example of how you can animate moves without having to define states for each possible position it could be in. As far as triggering the animations on array manipulation, you'll have to figure that out for yourself. I would use some kind of implementation with EventEmitters or Subjects to send events to the components that would then decide on whether or not they need to animate or not.
I'm looking to animate a text field into view and a button out of view at the same time, so that it looks like the text field is replacing the button. (They are both equal size and take up the same area of the screen).
What's the best way to do this using React Native animation?
At this point, I am rendering the button if one of my state values is false, and the text field if it is true.
You can animate any style property in react-native using the Animated API.
If you are able to represent the changes in a sequence of style changes, the Animated API can do it. For instance animating the opacity from 1 to 0 and back to 1 will give a nice fade in fade out effect. The docs explain the Animations much more clearly
Also you can you selective rendering to mount or hide the component
<View style={{/*style props that need to be animated*/}}
{ boolShowText? <Text/> : <View/> }
</View>
The fading example as found in react-native docs
class FadeInView extends React.Component {
constructor(props) {
super(props);
this.state = {
fadeAnim: new Animated.Value(0), // init opacity 0
};
}
componentDidMount() {
Animated.timing( // Uses easing functions
this.state.fadeAnim, // The value to drive
{toValue: 1}, // Configuration
).start(); // Don't forget start!
}
render() {
return (
<Animated.View // Special animatable View
style={{opacity: this.state.fadeAnim}}> // Binds
{this.props.children}
</Animated.View>
);
}
}
I have an element controlling the rendering of a child element. (A TouchableHighlight that sets some state in its onPress.) In the child element's componentDidMount method I construct an Animated.spring and start it. This works for entry, but I need to do the same animation in reverse to exit (it's like a drawer). componentWillUnmount executes too quickly for Animated.spring to even start working.
How would I handle animating the child's exit?
I have implemented a FadeInOut component that will animate a component in or out when its isVisible property changes. I made it because I wanted to avoid explicitly handling the visibility state in the components that should enter/exit with an animation.
<FadeInOut isVisible={this.state.someBooleanProperty} style={styles.someStyle}>
<Text>Something...</Text>
</FadeInOut>
This implementation uses a delayed fade, because I use it for showing progress indicator, but you can change it to use any animation you want, or generalise it to accept the animation parameters as props:
'use strict';
import React from 'react-native';
const {
View,
Animated,
PropTypes
} = React;
export default React.createClass({
displayName: 'FadeInOut',
propTypes: {
isVisible: PropTypes.bool.isRequired,
children: PropTypes.node.isRequired,
style: View.propTypes.style
},
getInitialState() {
return {
view: this.props.children,
opacity: new Animated.Value(this.props.isVisible ? 1 : 0)
};
},
componentWillReceiveProps(nextProps) {
const isVisible = this.props.isVisible;
const shouldBeVisible = nextProps.isVisible;
if (isVisible && !shouldBeVisible) {
Animated.timing(this.state.opacity, {
toValue: 0,
delay: 500,
duration: 200
}).start(this.removeView);
}
if (!isVisible && shouldBeVisible) {
this.insertView();
Animated.timing(this.state.opacity, {
toValue: 1,
delay: 500,
duration: 200
}).start();
}
},
insertView() {
this.setState({
view: this.props.children
});
},
removeView() {
this.setState({
view: null
});
},
render() {
return (
<Animated.View
pointerEvents={this.props.isVisible ? 'auto' : 'none'}
style={[this.props.style, {opacity: this.state.opacity}]}>
{this.state.view}
</Animated.View>
);
}
});
I think you have the animation ownership inverted. If you move your animation logic to the parent that is opening and closing the child, the problem becomes much simpler. Rather than beginning the animation on componentDidMount, do it on the click of your TouchableHighlight in addition to, but independent of, whatever prop manipulations on the child you need to do.
Then when the user clicks to close, you can simply reverse the animation as per normal and you don't really even need to unload it. Also this would allow you to have a reusable drawer (the thing that slides up and down) and it's abstracted away from the content within it. So you can have a single drawer mechanism supporting multiple different types of content.