ntk 8.12.11 → 8.12.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/renderingcontext_2d.js +11 -1
- package/lib/window.js +10 -3
- package/package.json +1 -1
|
@@ -3640,7 +3640,17 @@ class RenderingContext2d {
|
|
|
3640
3640
|
const y = Math.min(...ys);
|
|
3641
3641
|
const w = Math.max(...xs) - x;
|
|
3642
3642
|
const h = Math.max(...ys) - y;
|
|
3643
|
-
|
|
3643
|
+
// A rectangle of no area is still one, and clips everything: what a box
|
|
3644
|
+
// of no height clips its content to, a menu at `max-height: 0`. Taken
|
|
3645
|
+
// for a path, it built the mask the size of the surface, and every
|
|
3646
|
+
// rectangle clipped inside it was intersected into that mask; the
|
|
3647
|
+
// intersection of an empty one is empty, and every consumer draws
|
|
3648
|
+
// nothing through that, as where two rectangles do not meet.
|
|
3649
|
+
if (!(w > 0 && h > 0)) {
|
|
3650
|
+
return Number.isFinite(w) && Number.isFinite(h)
|
|
3651
|
+
? { x: 0, y: 0, w: 0, h: 0 }
|
|
3652
|
+
: null;
|
|
3653
|
+
}
|
|
3644
3654
|
// Server clip rectangles are integers, so a fractional edge could only
|
|
3645
3655
|
// be honoured by rounding — which would differ from the mask path's
|
|
3646
3656
|
// antialiased edge by up to a pixel. Rare, so leave those to the mask
|
package/lib/window.js
CHANGED
|
@@ -1560,6 +1560,7 @@ export default class Window extends Drawable {
|
|
|
1560
1560
|
|
|
1561
1561
|
_runFrame() {
|
|
1562
1562
|
const f = this._frame;
|
|
1563
|
+
const startedAt = performance.now();
|
|
1563
1564
|
if (
|
|
1564
1565
|
!f.pending.size &&
|
|
1565
1566
|
!f.rafCbs.length &&
|
|
@@ -1601,7 +1602,7 @@ export default class Window extends Drawable {
|
|
|
1601
1602
|
// that drew nothing has to fall back to the timer, or nothing would ever
|
|
1602
1603
|
// run the next frame.
|
|
1603
1604
|
if (!this._clockOnPresent()) this._armFence();
|
|
1604
|
-
this._armTimer();
|
|
1605
|
+
this._armTimer(startedAt);
|
|
1605
1606
|
}
|
|
1606
1607
|
|
|
1607
1608
|
/**
|
|
@@ -2156,8 +2157,14 @@ export default class Window extends Drawable {
|
|
|
2156
2157
|
* and arming one would only cap the rate the display just set. An explicit
|
|
2157
2158
|
* `frameInterval` is honoured in both, since a cap the caller asked for
|
|
2158
2159
|
* applies whatever ends the frame.
|
|
2160
|
+
*
|
|
2161
|
+
* The period runs from the start of the frame (`startedAt`), not from its
|
|
2162
|
+
* end: a frame's own work is part of its period, not a pause owed after it.
|
|
2163
|
+
* Counted from the end, a window whose frames took 3 ms drew one every 19
|
|
2164
|
+
* under a 16.7 ms interval — a GL map panned by an animation, whose window
|
|
2165
|
+
* is on the fence, ran at 51 frames a second on a 60 Hz panel.
|
|
2159
2166
|
*/
|
|
2160
|
-
_armTimer() {
|
|
2167
|
+
_armTimer(startedAt = performance.now()) {
|
|
2161
2168
|
const f = this._frame;
|
|
2162
2169
|
if (f.timer) return;
|
|
2163
2170
|
let period = this.frameInterval;
|
|
@@ -2169,7 +2176,7 @@ export default class Window extends Drawable {
|
|
|
2169
2176
|
f.timer = setTimeout(() => {
|
|
2170
2177
|
f.timer = null;
|
|
2171
2178
|
if (f.pending.size || f.rafCbs.length || f.needsRedraw) this._scheduleFrame();
|
|
2172
|
-
}, period);
|
|
2179
|
+
}, Math.max(0, period - (performance.now() - startedAt)));
|
|
2173
2180
|
if (typeof f.timer.unref === 'function') f.timer.unref();
|
|
2174
2181
|
}
|
|
2175
2182
|
|