I am trying to setup a counter from a specific date using RxJS on an Angular 14 project, but the counter seems wrong.
Milliseconds only change on the red spot, seconds are changing on the orange spot, but seconds should change at the blue spot, and milliseconds should countup on the orange and red spot combined. Am I correct?
What is my mistake in this code?
TS:
startTime = new Date("April 10, 2013 00:00:00").getTime();
elapsedTime = Date.now() - this.startTime;
count: Observable<number> | undefined;
this.count = interval()
.pipe(map(count => count + this.elapsedTime)
);
}
This is the placeholder:
{{ count | async }}
Thank you
The problem is that you are scheduling with interval a new notification every ms, but the app cant process and render each notification in 1m. That means that as time goes by, the difference between the notification count being process (your intended measure of elapsedTime) and the real elapsed time in ms gets bigger and bigger and thus the time seems to run slower.
The easiest way to prevent this is increase the interval time between emissions to avoid a backlog of notifications, and to calculate the elapsedTime against the startTime in each iteration.
this.count = interval(30).pipe(
map(count => Date.now() - this.startTime)
);
cheers
Related
I'm having a little trouble working with the linearRampToValueAtTime on a BiQuadFilter applied to a WebAudio.
The audio works ok, and the initial lowpass filter is applied.
Problem is, as soon as I use the linearRamp method to bring up the frequency, it seems to ignore the endTime parameter (or better, it's not time correctly).
Some code to explain it better.
Here's the instancing:
this.audioLoader.load( 'public/media/soundtrack-es_cobwebs_in_the_sky.mp3', buffer => {
this.sounds.soundtrack = new THREE.Audio(this.listener);
const audioContext = this.sounds.soundtrack.context;
this.biquadFilter = audioContext.createBiquadFilter();
this.biquadFilter.type = "lowpass"; // Low pass filter
this.biquadFilter.frequency.setValueAtTime(200, audioContext.currentTime);
this.sounds.soundtrack.setBuffer(buffer);
this.sounds.soundtrack.setFilter(this.biquadFilter);
this.sounds.soundtrack.setVolume(0.5);
this.sounds.soundtrack.play();
})
Until here, everything looks ok. The sound plays muffled as needed.
Then, after a certain event, there's a camera transition, where I want the sound to gradually open up.
As a endTime parameter, I'm passing 2 seconds + the internal context delta.
this.sounds.soundtrack.filters[0].frequency.linearRampToValueAtTime(2400, 2 + this.sounds.soundtrack.context.currentTime);
Expecting to hear the ramp in two seconds, but the sound opens up immediately.
What am I missing?
The linear ramp will be applied using the previous event as the startTime. In your case that will be audioContext.currentTime at the point in time when you created the filter. If that is sufficiently long ago it will sound as if the ramp jumps right to the end value. You can fix that by inserting a new event right before the ramp.
const currentTime = this.sounds.soundtrack.context.currentTime;
const filter = this.sounds.soundtrack.filters[0];
filter.frequency.setValueAtTime(200, currentTime);
filter.frequency.linearRampToValueAtTime(2400, currentTime + 2);
Hey so I'm working on a simple app and I want this image on a map to move closer hour by hour towards the user location. I can't figure out where to start, can anyone help?
Thanks!
Swift has a Timer class. There are several overloads for Timer.init. The newer block based one works like this:
let hour = TimeInterval(60 * 60) //60 seconds per min * 60 min per hour = 360 seconds per hour
let timer = Timer.init(timeInterval: hour, repeats: true) { timer in
//Do hourly update stuff here
}
I'm working on an AS3 project and for one of the effects I use timers to switch the colors then stop. The function is below.
//global variable
private var valueAnimationTimer:Timer = new Timer(50);
//constructor
valueAnimationTimer.addEventListener(TimerEvent.TIMER, scrollUp );
//function
private function scrollUp(e:TimerEvent):void
{
var i:int = e.currentTarget.currentCount as int;
if (i < 10)
{
if (colored){
if (i % 2 == 0){
ChangeColor(ico, flickerColor);
}
else{
ico.transform.colorTransform = new ColorTransform();
}
}
tfValue.y -= 7.5;
}
else
{
RemoveFilters(ico);
tfValue.y = ico.height / 2;
e.currentTarget.reset();
RemoveSprite(tfValue);
colored = false;
}
}
Each character (object) has it's own version of this function and it happens at different times (like when it is injured or poisoned). The listener is added once in the constructor, it is only removed when the character dies and is removed from the stage. The issue here is after the timer is used on at least 3 characters, the frame rate begins to drop. Every time the function is called, the frame rate drops lower and lower.
What I don't understand is, if the timer is stopped, and the listeners are only added once so it doesn't overload the stack, then why does the frame rate begin to decline after the listener is actually used? It doesn't run forever only for a small amount of time, but it happens again and again. When the frame rate drops the entire program begins to lag badly and eventually freezes. I have no idea what is causing this
Also be aware that inside of the Timer function, the first number is your count in MILLISECONDS and the second is repeat count
var fl_TimerInstance:Timer = new Timer(240000, 1);
So this example above is a 4 minute timer that repeats 1 time
I bring this up because yours is set for 50 milliseconds which is very quick lol
I'm making a timer. When the minutes value reaches 60, it has to decrease by 60 and increment the hour. It's tracking a time lapse; the minutes is currently the time of the computation divided by 6 : each frame is 10 seconds in real life.
This is the code I have so far:
effect("Mins")(1)+Math.floor(((time*10)/6))+effect("MinAdd")("Slider");
if(effect("Mins")("Slider").value > 60) {effect("Mins")("Slider") -60;}
Unfortunately, it doesn't work, and I don't know why.
I'm not quite sure what your setup is there, but usually property values are read by reading the .value property and set through setValue(), so in your case e.g.
effect("Mins")("Slider").setValue(effect("Mins")("Slider").value - 60);
Personally I'd probably use something more along the lines of:
var currentsec = (time*10)/6);
var minute = Math.floor(currentsec / 60);
var sec = currentsec % 60;
effect("Mins")("Slider").setValue(minute);
effect("Seconds")("Slider").setValue(sec);
though in your case of course for minutes and hours.
Previously, with Objective-C I could use performSelector: in order to repeat an action after a random period of time which could vary between 1-3 seconds. But since I'm not able to use performSelector: in Swift, I've tried using "NSTimer.scheduledTimerWithTimeInterval". And it works in order to repeat the action. But there is a problem. On set the time variable to call a function that will generate a random number. But it seems that NSTimer uses the same number every time it repeats the action.
What that means is that the action is not performed randomly, but instead, after a set period of time that is generated randomly at the beginning of the game and it is used during all the game.
The question is: Is there any way to set the NSTimer to create a random number every time it executes the action? Or should I use a different method? Thanks!
#LearnCocos2D is right... use SKActions or the update method in your scene. Here is a basic example of using update to repeat an action after a random period of time.
class YourScene:SKScene {
// Time of last update(currentTime:) call
var lastUpdateTime = NSTimeInterval(0)
// Seconds elapsed since last action
var timeSinceLastAction = NSTimeInterval(0)
// Seconds before performing next action. Choose a default value
var timeUntilNextAction = NSTimeInterval(4)
override func update(currentTime: NSTimeInterval) {
let delta = currentTime - lastUpdateTime
lastUpdateTime = currentTime
timeSinceLastAction += delta
if timeSinceLastAction >= timeUntilNextAction {
// perform your action
// reset
timeSinceLastAction = NSTimeInterval(0)
// Randomize seconds until next action
timeUntilNextAction = CDouble(arc4random_uniform(6))
}
}
}
use let wait = SKAction.waitForDuration(sec, withRange: dur) in your code. SKAction.waitForDuration with withRange parameter will compute random time interval with average time = sec and possible range = dur
Generate a random time yourself and use dispatch_after to do the action.
For more information on dispatch_after, see here. Basically you can use this instead of performSelector