@vosjs/studio-core 0.45.0 → 0.45.2
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/dist/index.d.ts +6 -0
- package/dist/index.js +65 -3
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1868,6 +1868,12 @@ interface HtmlOverlayClip extends OverlayClipBase {
|
|
|
1868
1868
|
* timeline's clock in the preview and in every export chunk alike. One
|
|
1869
1869
|
* rasterize per frame while on screen. Absent = a still, byte-identical
|
|
1870
1870
|
* to before the field existed.
|
|
1871
|
+
*
|
|
1872
|
+
* Move the LAYER with `motion` poses, never its text with CSS: the
|
|
1873
|
+
* browser places text on whole device pixels each time it rasterizes, so
|
|
1874
|
+
* text a keyframe drifts or scales slowly steps a pixel at a time beside
|
|
1875
|
+
* shapes that glide. A layer with a motion track is drawn from one raster
|
|
1876
|
+
* of each picture and moves by resampling it, which glides.
|
|
1871
1877
|
*/
|
|
1872
1878
|
live?: boolean;
|
|
1873
1879
|
/** Values for a live layer's `{{data.<name>}}` placeholders. */
|
package/dist/index.js
CHANGED
|
@@ -1515,6 +1515,8 @@ var DESIGN_FRAME_WIDTH = 1920;
|
|
|
1515
1515
|
var HTML_LAYER_WARN_BYTES = 32e3;
|
|
1516
1516
|
var HTML_LAYER_MAX_BYTES = 128e3;
|
|
1517
1517
|
var HTML_LAYER_LIVE_HZ = 60;
|
|
1518
|
+
var HTML_LAYER_RASTER_SCALE = 2;
|
|
1519
|
+
var HTML_LAYER_RASTER_MAX_AREA = 4096 * 4096;
|
|
1518
1520
|
var HTML_LAYER_ASSET_HOST = "https://assets.vos.so/";
|
|
1519
1521
|
function splitTopLevel(value) {
|
|
1520
1522
|
const out = [];
|
|
@@ -5834,6 +5836,35 @@ var STUDIO_FRAME = `(ctx, content, dt) => {
|
|
|
5834
5836
|
else { cc.beginPath(); cc.rect(x, y, w, h) }
|
|
5835
5837
|
}
|
|
5836
5838
|
|
|
5839
|
+
// A moving html layer's raster: its picture drawn ONCE at the largest size
|
|
5840
|
+
// its track reaches (so a pose only ever scales it down), into one canvas
|
|
5841
|
+
// per clip, redrawn only when a new picture lands or the frame's size
|
|
5842
|
+
// changes. A still layer in motion rasterizes once; a live one once per
|
|
5843
|
+
// picture, as before.
|
|
5844
|
+
function hlRaster(ol, el, nw, nh) {
|
|
5845
|
+
if (typeof document === 'undefined') return el
|
|
5846
|
+
var hlPk = ol.scale
|
|
5847
|
+
var hlKs = ol.track.keyframes
|
|
5848
|
+
for (var hlKi = 0; hlKi < hlKs.length; hlKi++) if (hlKs[hlKi].value[2] > hlPk) hlPk = hlKs[hlKi].value[2]
|
|
5849
|
+
var hlBW = ol.w * W * hlPk
|
|
5850
|
+
var hlBH = hlBW * nh / nw
|
|
5851
|
+
var hlSS = Math.min(${HTML_LAYER_RASTER_SCALE}, Math.sqrt(${HTML_LAYER_RASTER_MAX_AREA} / Math.max(1, hlBW * hlBH)))
|
|
5852
|
+
var hlRW = Math.max(1, Math.floor(hlBW * hlSS))
|
|
5853
|
+
var hlRH = Math.max(1, Math.floor(hlBH * hlSS))
|
|
5854
|
+
var hlRs = ns.htmlRaster || (ns.htmlRaster = {})
|
|
5855
|
+
var hlR = hlRs[ol.id]
|
|
5856
|
+
if (!hlR) hlR = hlRs[ol.id] = { c: document.createElement('canvas'), el: null }
|
|
5857
|
+
if (hlR.el !== el || hlR.c.width !== hlRW || hlR.c.height !== hlRH) {
|
|
5858
|
+
if (hlR.c.width !== hlRW) hlR.c.width = hlRW
|
|
5859
|
+
if (hlR.c.height !== hlRH) hlR.c.height = hlRH
|
|
5860
|
+
var hlX = hlR.c.getContext('2d')
|
|
5861
|
+
hlX.clearRect(0, 0, hlRW, hlRH)
|
|
5862
|
+
try { hlX.drawImage(el, 0, 0, hlRW, hlRH) } catch (e) { return el }
|
|
5863
|
+
hlR.el = el
|
|
5864
|
+
}
|
|
5865
|
+
return hlR.c
|
|
5866
|
+
}
|
|
5867
|
+
|
|
5837
5868
|
// Text overlays: visibility signature + "a transition is animating".
|
|
5838
5869
|
// During a hold the drawn pixels are static, so the signature alone drives
|
|
5839
5870
|
// redraws (position/text/style edits change it \u2014 live SET_DATA); during
|
|
@@ -5894,6 +5925,7 @@ var STUDIO_FRAME = `(ctx, content, dt) => {
|
|
|
5894
5925
|
if (ns.htmlKeys) delete ns.htmlKeys[hlK]
|
|
5895
5926
|
if (ns.htmlWant) delete ns.htmlWant[hlK]
|
|
5896
5927
|
if (ns.htmlErrors) delete ns.htmlErrors[hlK]
|
|
5928
|
+
if (ns.htmlRaster) delete ns.htmlRaster[hlK]
|
|
5897
5929
|
}
|
|
5898
5930
|
}
|
|
5899
5931
|
// A styled layer's cached layout leaves with its clip.
|
|
@@ -6110,7 +6142,15 @@ var STUDIO_FRAME = `(ctx, content, dt) => {
|
|
|
6110
6142
|
}
|
|
6111
6143
|
ovC.save()
|
|
6112
6144
|
rr(-olDW / 2, -olDH / 2, olDW, olDH, olRad, ovC); ovC.clip()
|
|
6113
|
-
|
|
6145
|
+
// A MOVING html layer is drawn from a raster of its picture, never from
|
|
6146
|
+
// the picture itself: the browser rasterizes an SVG image afresh at
|
|
6147
|
+
// every draw transform and places text on whole device pixels as it
|
|
6148
|
+
// does, so text under a slow move or scale held still and then jumped
|
|
6149
|
+
// a pixel while the shapes beside it glided. A fixed raster moves by
|
|
6150
|
+
// resampling, every frame.
|
|
6151
|
+
var olSrc = ol.html && ol.track ? hlRaster(ol, olEl, olNW, olNH) : olEl
|
|
6152
|
+
if (olSrc !== olEl) ovC.imageSmoothingQuality = 'high'
|
|
6153
|
+
try { ovC.drawImage(olSrc, -olDW / 2, -olDH / 2, olDW, olDH) } catch (e) {}
|
|
6114
6154
|
ovC.restore()
|
|
6115
6155
|
if (ol.border && ol.border.width > 0) {
|
|
6116
6156
|
ovC.strokeStyle = ol.border.color || '#ffffff'
|
|
@@ -6231,8 +6271,20 @@ var STUDIO_FRAME = `(ctx, content, dt) => {
|
|
|
6231
6271
|
var rbPY = ol.box.py * olMS * s
|
|
6232
6272
|
var rbW = rtL.width + rbPX * 2
|
|
6233
6273
|
var rbH = rtN * rtLH + rbPY * 2
|
|
6274
|
+
// A per-unit entrance leaves the clip at full strength while its
|
|
6275
|
+
// units arrive one by one, so the box follows the EARLIEST unit (the
|
|
6276
|
+
// units' own delay, seconds and ease) or it stands empty until the
|
|
6277
|
+
// first word shows. A typewriter's field is there from its first frame.
|
|
6278
|
+
var rbA = 1
|
|
6279
|
+
if (rtFx && rtFx.k !== 'typewriter') {
|
|
6280
|
+
var rbN = 0
|
|
6281
|
+
for (var rbi = 0; rbi < rtN; rbi++) rbN += rtL.lines[rbi].units.length
|
|
6282
|
+
var rbO = rtFx.d === 2 && rbN % 2 === 0 ? 0.5 : 0
|
|
6283
|
+
var rbU = Math.max(0, Math.min(1, (olT - rbO * rtFx.st) / rtFx.dur))
|
|
6284
|
+
rbA = rtFx.k === 'pop' ? Math.min(1, rbU * 2) : 1 - Math.pow(1 - rbU, 3)
|
|
6285
|
+
}
|
|
6234
6286
|
ovC.save()
|
|
6235
|
-
ovC.globalAlpha = olA * ol.box.o
|
|
6287
|
+
ovC.globalAlpha = olA * ol.box.o * rbA
|
|
6236
6288
|
ovC.fillStyle = ol.box.c
|
|
6237
6289
|
rr(-rbW / 2, -rbH / 2, rbW, rbH, Math.min(ol.box.r * olMS * s, rbH / 2), ovC)
|
|
6238
6290
|
ovC.fill()
|
|
@@ -9047,8 +9099,18 @@ var ON_FRAME = `(ctx, content, dt) => {
|
|
|
9047
9099
|
var tqAx = (tqA[0] - W / 2) * trGsc + W / 2 + trGox * W, tqAy = (tqA[1] - H / 2) * trGsc + H / 2 - trGoy * H
|
|
9048
9100
|
var tqBx = (tqB[0] - W / 2) * trSc + W / 2 + trOx * W, tqBy = (tqB[1] - H / 2) * trSc + H / 2 - trOy * H
|
|
9049
9101
|
var tqX2 = tqAx + (tqBx - tqAx) * tqP, tqY2 = tqAy + (tqBy - tqAy) * tqP
|
|
9102
|
+
// A slide pulls the two cards a frame apart, so the lerp would cross
|
|
9103
|
+
// the bare ground between them: the dot rides the card that holds
|
|
9104
|
+
// more of the frame instead, moved with it, and only a card's own
|
|
9105
|
+
// point is ever drawn on that card.
|
|
9106
|
+
var tqOn = true
|
|
9107
|
+
if (trOut.kind === 'slide' || (trIn && trIn.kind === 'slide')) {
|
|
9108
|
+
var tqOut = Math.abs(trGox) + Math.abs(trGoy) <= Math.abs(trOx) + Math.abs(trOy)
|
|
9109
|
+
tqOn = tqOut ? !!trQa : !!trQb
|
|
9110
|
+
tqX2 = tqOut ? tqAx : tqBx; tqY2 = tqOut ? tqAy : tqBy
|
|
9111
|
+
}
|
|
9050
9112
|
var tqR = trQs || (((d.cursorStyle && d.cursorStyle.size) || 24) * s * 0.5)
|
|
9051
|
-
drawCur(ovC, tqX2, tqY2, tqR, 1, 2 * (trQw || s))
|
|
9113
|
+
if (tqOn) drawCur(ovC, tqX2, tqY2, tqR, 1, 2 * (trQw || s))
|
|
9052
9114
|
}
|
|
9053
9115
|
ov.sig = ovSig
|
|
9054
9116
|
ov.active = camActiveNow || !!trOut || pqLive
|