I want to know if, once you create a timing Animation in React-Native and start it, can you can update its duration dynamically, without having to stop/recreate the animation? This is the use case that motivated this question:
I am developing a music player in React-Native. I have a simple Player component with a progress bar (slider) like this:
Basically, an Animated.Value is used as the slider's value. When pressing play, a timing animation starts, its duration being the duration of the song. Simultaneously, I control the timers with setInterval(). Every 1000 milliseconds, I add +1 to the timer displayed.
This works fine. Here I have a simple Expo snackbar showing how this works.
The problem is, I want to add a slider that controls the playback speed:
let's ignore the real audio playback and focus only on the slider and timers behavior. If the playback is paused, then when sliding the "Speed factor" slider, it's a very easy change because I only need to update the timers. The progress bar stays the same. But when we're currently playing the song, how do I handle the updates of the timers and the progress bar?
The speed factor slider will adjust the real duration of the song with this formula:
real_duration = normal_duration / speed_factor where speed_factor can be a number between 0.5 and 1.5, for example.
And due to this change duration, I ask whether it is possible to update on the fly an animation's duration, once it has started.
Related
Sometimes my app is quite busy with other stuff so for a noticeable amount of time,
it becomes unresponsive to touch events bound to my TouchableOpacity components.
activeOpacity property makes the button changing its opacity with some delay (1-2 seconds) if that kind of heavy load being present so users do not feel that they actually press that button and keep pressing until they see a reaction. Of course it creates some frustration for them.
My understanding is that I think these opacity changing animation also requires some communication between JS and native side over the bridge. That's why it is affected by other bridge communication and becomes unresponsive for a while.
Is there any way to overcome this situation in React Native side and make the button immediately change its opacity?
Or can it be handled only by creating a new native button component for that purpose ?
Check out requestAnimationFrame https://reactnative.dev/docs/timers.
"requestAnimationFrame(fn) is not the same as setTimeout(fn, 0) - the former will fire after all the frame has flushed, whereas the latter will fire as quickly as possible (over 1000x per second on a iPhone 5S)."
Wrap your onPress logic in requestAnimationFrame so that the animation happens before the logic.
It seems to me that the system takes a different screen capture that the one my app takes on applicationWillResignActive.
To my surprise there is a delay of about 0.6 secs between the image taken by the system (b) and the image taken by the game (d). It kind of makes sence if the system needs to take the screen capture before applicationWillResignActive, but for a game with fast moving objects this can be easily noticed by the player.
How can I workaround this?
The following are the steps the player makes and how it causes such discrepancy:
(a) The player pulses the home button when she is playing. (b) The system screen capture is taken. (c) The player taps the game icon. (d) The game is launched with the screen capture taken on applicationWillResignActive. (e) The game is paused showing the discrepancy in a fast moving object.
I believe this is because your game rendering is not on main thread(certainly it shouldn't be on main thread), so when applicationDidEnterBackground/applicationWillResignActive is returned, the system takes a screen shot from video card's buffer immediately.
At this time, your game loop thread is still running, so it may update some frames before it is paused.
I don't know how you implement your game loop, but you can try this:
In applicationDidEnterBackground/applicationWillResignActive, put a global semaphore(dispatch_semaphore_t) and block the main thread, in your game loop, observe the semaphore and if it exist, pause your game loop, then signal the semaphore.
This will assure that the screen shot is taken after your game is paused.
Also notice that after applicationWillResignActive, the system will take the snapshot for task switcher, and after applicationDidEnterBackground, the system will take snapshot for next time you app enter foreground.
Hope this will help you.
I have an app which record videos, now I can load the camera, record no problem, issue is i am using the function
[imagePickerController setVideoMaximumDuration:5];
property which limits the length of the video, what I'm wondering is if there a way this can be a countdown timer on the video screen.
Thanks
The two are unrelated.
Implement an onscreen countdown via whatever means you want and start it when you start the 5 second duration video recording. Then tear it down when the video stops recording.
I want to want to create a countdown timer with a progress bar (a backwards progress bar).
I want it to tell me when it reached the end of the time and I want to be able to stop and restart it whenever I want.
Is there an easy way to do it?
Yes. Matt Legend Gemmel has a great video on how to approach Custom UI Controls.
I am using cocos2d. I would like to be able to detect whether the screen is touched at a particular instant - that is, rather than intercepting an event when it occurs, I want to detect the presence of touch at a particular moment.
The reason is that I am animating sprites and want to determine if the sprite should keep moving - if the screen is still touched. I cannot use ccTouchesEnded because each time an animation starts I set isTouchEnabled to false because I also want the user to be able to tap rapidly on the screen to move the sprite but if they tapped too rapidly, it would mess with the position of the sprite during the animation process - which I have found screws up the positions of my objects in weird ways.
Is this possible?
There does not appear to be any public API to detect touches other than enabling and receiving these events in the main UI run loop.
You can keep handling events, and set the state left by the last touch event in a model object or global variables. Then you can poll your app's own internal state at any time.
Instead of disabling touches, you can just have your touch handler not do inappropriate things if the event time stamp is too close to some animation start time.