| 283 | // current frame finish awaiting. The same goes for lifecycle hooks 'predraw' |
| 284 | // and 'postdraw'. |
| 285 | async _draw(requestAnimationFrameTimestamp) { |
| 286 | if (this.hitCriticalError) return; |
| 287 | const now = requestAnimationFrameTimestamp || globalThis.performance.now(); |
| 288 | const timeSinceLastFrame = now - this._lastTargetFrameTime; |
| 289 | const targetTimeBetweenFrames = 1000 / this._targetFrameRate; |
| 290 | |
| 291 | // only draw if we really need to; don't overextend the browser. |
| 292 | // draw if we're within 5ms of when our next frame should paint |
| 293 | // (this will prevent us from giving up opportunities to draw |
| 294 | // again when it's really about time for us to do so). fixes an |
| 295 | // issue where the frameRate is too low if our refresh loop isn't |
| 296 | // in sync with the browser. note that we have to draw once even |
| 297 | // if looping is off, so we bypass the time delay if that |
| 298 | // is the case. |
| 299 | const epsilon = 5; |
| 300 | if ( |
| 301 | !this._loop || |
| 302 | timeSinceLastFrame >= targetTimeBetweenFrames - epsilon |
| 303 | ) { |
| 304 | //mandatory update values(matrixes and stack) |
| 305 | this.deltaTime = now - this._lastRealFrameTime; |
| 306 | this._frameRate = 1000.0 / this.deltaTime; |
| 307 | await this.redraw(); |
| 308 | this._lastTargetFrameTime = Math.max(this._lastTargetFrameTime |
| 309 | + targetTimeBetweenFrames, now); |
| 310 | this._lastRealFrameTime = now; |
| 311 | |
| 312 | // If the user is actually using mouse module, then update |
| 313 | // coordinates, otherwise skip. We can test this by simply |
| 314 | // checking if any of the mouse functions are available or not. |
| 315 | // NOTE : This reflects only in complete build or modular build. |
| 316 | if (typeof this._updateMouseCoords !== 'undefined') { |
| 317 | this._updateMouseCoords(); |
| 318 | |
| 319 | //reset delta values so they reset even if there is no mouse event to set them |
| 320 | // for example if the mouse is outside the screen |
| 321 | this.movedX = 0; |
| 322 | this.movedY = 0; |
| 323 | } |
| 324 | } |
| 325 | |
| 326 | // get notified the next time the browser gives us |
| 327 | // an opportunity to draw. |
| 328 | if (this._loop) { |
| 329 | const boundDraw = this._draw.bind(this); |
| 330 | this._requestAnimId = typeof window !== 'undefined' ? |
| 331 | window.requestAnimationFrame(boundDraw) : |
| 332 | setImmediate(boundDraw); |
| 333 | } |
| 334 | } |
| 335 | |
| 336 | /** |
| 337 | * Removes the sketch from the web page. |