@editframe/elements 0.15.0-beta.18 → 0.15.0-beta.20
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/EF_FRAMEGEN.js +1 -0
- package/dist/elements/EFMedia.d.ts +7 -3
- package/dist/elements/EFMedia.js +42 -90
- package/dist/elements/EFTemporal.browsertest.d.ts +4 -3
- package/dist/elements/EFTemporal.d.ts +14 -11
- package/dist/elements/EFTemporal.js +63 -87
- package/dist/elements/EFTimegroup.d.ts +1 -1
- package/dist/elements/EFTimegroup.js +12 -107
- package/dist/elements/EFVideo.js +3 -1
- package/dist/elements/durationConverter.d.ts +8 -8
- package/dist/elements/durationConverter.js +2 -2
- package/dist/elements/updateAnimations.d.ts +9 -0
- package/dist/elements/updateAnimations.js +62 -0
- package/dist/getRenderInfo.d.ts +2 -2
- package/dist/gui/EFFilmstrip.js +7 -16
- package/dist/gui/EFFitScale.d.ts +27 -0
- package/dist/gui/EFFitScale.js +137 -0
- package/dist/gui/EFWorkbench.d.ts +1 -5
- package/dist/gui/EFWorkbench.js +7 -54
- package/dist/gui/TWMixin.css.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/style.css +0 -6
- package/package.json +2 -2
- package/src/elements/EFMedia.browsertest.ts +10 -10
- package/src/elements/EFMedia.ts +48 -118
- package/src/elements/EFTemporal.browsertest.ts +64 -31
- package/src/elements/EFTemporal.ts +99 -119
- package/src/elements/EFTimegroup.ts +12 -131
- package/src/elements/EFVideo.ts +3 -1
- package/src/elements/durationConverter.ts +9 -4
- package/src/elements/updateAnimations.ts +88 -0
- package/src/gui/ContextMixin.ts +0 -3
- package/src/gui/EFFilmstrip.ts +7 -16
- package/src/gui/EFFitScale.ts +151 -0
- package/src/gui/EFWorkbench.ts +13 -63
- package/types.json +1 -1
package/dist/gui/TWMixin.css.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const twStyle = "/*\n! tailwindcss v3.4.4 | MIT License | https://tailwindcss.com\n*//*\n1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)\n2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)\n*/\n\n*,\n::before,\n::after {\n box-sizing: border-box; /* 1 */\n border-width: 0; /* 2 */\n border-style: solid; /* 2 */\n border-color: #e5e7eb; /* 2 */\n}\n\n::before,\n::after {\n --tw-content: '';\n}\n\n/*\n1. Use a consistent sensible line-height in all browsers.\n2. Prevent adjustments of font size after orientation changes in iOS.\n3. Use a more readable tab size.\n4. Use the user's configured `sans` font-family by default.\n5. Use the user's configured `sans` font-feature-settings by default.\n6. Use the user's configured `sans` font-variation-settings by default.\n7. Disable tap highlights on iOS\n*/\n\nhtml,\n:host {\n line-height: 1.5; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n -moz-tab-size: 4; /* 3 */\n -o-tab-size: 4;\n tab-size: 4; /* 3 */\n font-family: ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; /* 4 */\n font-feature-settings: normal; /* 5 */\n font-variation-settings: normal; /* 6 */\n -webkit-tap-highlight-color: transparent; /* 7 */\n}\n\n/*\n1. Remove the margin in all browsers.\n2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.\n*/\n\nbody {\n margin: 0; /* 1 */\n line-height: inherit; /* 2 */\n}\n\n/*\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n3. Ensure horizontal rules are visible by default.\n*/\n\nhr {\n height: 0; /* 1 */\n color: inherit; /* 2 */\n border-top-width: 1px; /* 3 */\n}\n\n/*\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\n\nabbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\n\n/*\nRemove the default font size and weight for headings.\n*/\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: inherit;\n font-weight: inherit;\n}\n\n/*\nReset links to optimize for opt-in styling instead of opt-out.\n*/\n\na {\n color: inherit;\n text-decoration: inherit;\n}\n\n/*\nAdd the correct font weight in Edge and Safari.\n*/\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/*\n1. Use the user's configured `mono` font-family by default.\n2. Use the user's configured `mono` font-feature-settings by default.\n3. Use the user's configured `mono` font-variation-settings by default.\n4. Correct the odd `em` font sizing in all browsers.\n*/\n\ncode,\nkbd,\nsamp,\npre {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; /* 1 */\n font-feature-settings: normal; /* 2 */\n font-variation-settings: normal; /* 3 */\n font-size: 1em; /* 4 */\n}\n\n/*\nAdd the correct font size in all browsers.\n*/\n\nsmall {\n font-size: 80%;\n}\n\n/*\nPrevent `sub` and `sup` elements from affecting the line height in all browsers.\n*/\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/*\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n3. Remove gaps between table borders by default.\n*/\n\ntable {\n text-indent: 0; /* 1 */\n border-color: inherit; /* 2 */\n border-collapse: collapse; /* 3 */\n}\n\n/*\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n3. Remove default padding in all browsers.\n*/\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-feature-settings: inherit; /* 1 */\n font-variation-settings: inherit; /* 1 */\n font-size: 100%; /* 1 */\n font-weight: inherit; /* 1 */\n line-height: inherit; /* 1 */\n letter-spacing: inherit; /* 1 */\n color: inherit; /* 1 */\n margin: 0; /* 2 */\n padding: 0; /* 3 */\n}\n\n/*\nRemove the inheritance of text transform in Edge and Firefox.\n*/\n\nbutton,\nselect {\n text-transform: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Remove default button styles.\n*/\n\nbutton,\ninput:where([type='button']),\ninput:where([type='reset']),\ninput:where([type='submit']) {\n -webkit-appearance: button; /* 1 */\n background-color: transparent; /* 2 */\n background-image: none; /* 2 */\n}\n\n/*\nUse the modern Firefox focus style for all focusable elements.\n*/\n\n:-moz-focusring {\n outline: auto;\n}\n\n/*\nRemove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)\n*/\n\n:-moz-ui-invalid {\n box-shadow: none;\n}\n\n/*\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\n\nprogress {\n vertical-align: baseline;\n}\n\n/*\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n\n::-webkit-inner-spin-button,\n::-webkit-outer-spin-button {\n height: auto;\n}\n\n/*\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n\n[type='search'] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/*\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to `inherit` in Safari.\n*/\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/*\nAdd the correct display in Chrome and Safari.\n*/\n\nsummary {\n display: list-item;\n}\n\n/*\nRemoves the default spacing and border for appropriate elements.\n*/\n\nblockquote,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\nfigure,\np,\npre {\n margin: 0;\n}\n\nfieldset {\n margin: 0;\n padding: 0;\n}\n\nlegend {\n padding: 0;\n}\n\nol,\nul,\nmenu {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n/*\nReset default styling for dialogs.\n*/\ndialog {\n padding: 0;\n}\n\n/*\nPrevent resizing textareas horizontally by default.\n*/\n\ntextarea {\n resize: vertical;\n}\n\n/*\n1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)\n2. Set the default placeholder color to the user's configured gray 400 color.\n*/\n\ninput::-moz-placeholder, textarea::-moz-placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\ninput::placeholder,\ntextarea::placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\n/*\nSet the default cursor for buttons.\n*/\n\nbutton,\n[role=\"button\"] {\n cursor: pointer;\n}\n\n/*\nMake sure disabled buttons don't get the pointer cursor.\n*/\n:disabled {\n cursor: default;\n}\n\n/*\n1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)\n2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)\n This can trigger a poorly considered lint error in some tools but is included by design.\n*/\n\nimg,\nsvg,\nvideo,\ncanvas,\naudio,\niframe,\nembed,\nobject {\n display: block; /* 1 */\n vertical-align: middle; /* 2 */\n}\n\n/*\nConstrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)\n*/\n\nimg,\nvideo {\n max-width: 100%;\n height: auto;\n}\n\n/* Make elements with the HTML hidden attribute stay hidden by default */\n[hidden] {\n display: none;\n}\n\n*, ::before, ::after {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n --tw-contain-size: ;\n --tw-contain-layout: ;\n --tw-contain-paint: ;\n --tw-contain-style: ;\n}\n\n::backdrop {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n --tw-contain-size: ;\n --tw-contain-layout: ;\n --tw-contain-paint: ;\n --tw-contain-style: ;\n}\n.container {\n width: 100%;\n}\n@media (min-width: 640px) {\n\n .container {\n max-width: 640px;\n }\n}\n@media (min-width: 768px) {\n\n .container {\n max-width: 768px;\n }\n}\n@media (min-width: 1024px) {\n\n .container {\n max-width: 1024px;\n }\n}\n@media (min-width: 1280px) {\n\n .container {\n max-width: 1280px;\n }\n}\n@media (min-width: 1536px) {\n\n .container {\n max-width: 1536px;\n }\n}\n.pointer-events-none {\n pointer-events: none;\n}\n.visible {\n visibility: visible;\n}\n.static {\n position: static;\n}\n.fixed {\n position: fixed;\n}\n.absolute {\n position: absolute;\n}\n.relative {\n position: relative;\n}\n.inset-0 {\n inset: 0px;\n}\n.top-0 {\n top: 0px;\n}\n.z-10 {\n z-index: 10;\n}\n.z-20 {\n z-index: 20;\n}\n.col-span-2 {\n grid-column: span 2 / span 2;\n}\n.mx-2 {\n margin-left: 0.5rem;\n margin-right: 0.5rem;\n}\n.mb-\\[1px\\] {\n margin-bottom: 1px;\n}\n.block {\n display: block;\n}\n.inline-block {\n display: inline-block;\n}\n.inline {\n display: inline;\n}\n.flex {\n display: flex;\n}\n.grid {\n display: grid;\n}\n.contents {\n display: contents;\n}\n.hidden {\n display: none;\n}\n.h-\\[1\\.1rem\\] {\n height: 1.1rem;\n}\n.h-\\[5px\\] {\n height: 5px;\n}\n.h-full {\n height: 100%;\n}\n.w-1 {\n width: 0.25rem;\n}\n.w-\\[2px\\] {\n width: 2px;\n}\n.w-full {\n width: 100%;\n}\n.transform {\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.cursor-crosshair {\n cursor: crosshair;\n}\n.resize {\n resize: both;\n}\n.flex-wrap {\n flex-wrap: wrap;\n}\n.place-content-center {\n place-content: center;\n}\n.place-items-center {\n place-items: center;\n}\n.items-center {\n align-items: center;\n}\n.justify-center {\n justify-content: center;\n}\n.overflow-auto {\n overflow: auto;\n}\n.overflow-hidden {\n overflow: hidden;\n}\n.text-nowrap {\n text-wrap: nowrap;\n}\n.rounded {\n border-radius: 0.25rem;\n}\n.border {\n border-width: 1px;\n}\n.border-r-2 {\n border-right-width: 2px;\n}\n.border-blue-500 {\n --tw-border-opacity: 1;\n border-color: rgb(59 130 246 / var(--tw-border-opacity));\n}\n.border-red-700 {\n --tw-border-opacity: 1;\n border-color: rgb(185 28 28 / var(--tw-border-opacity));\n}\n.border-slate-500 {\n --tw-border-opacity: 1;\n border-color: rgb(100 116 139 / var(--tw-border-opacity));\n}\n.border-b-slate-600 {\n --tw-border-opacity: 1;\n border-bottom-color: rgb(71 85 105 / var(--tw-border-opacity));\n}\n.bg-blue-200 {\n --tw-bg-opacity: 1;\n background-color: rgb(191 219 254 / var(--tw-bg-opacity));\n}\n.bg-blue-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(59 130 246 / var(--tw-bg-opacity));\n}\n.bg-red-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(239 68 68 / var(--tw-bg-opacity));\n}\n.bg-slate-100 {\n --tw-bg-opacity: 1;\n background-color: rgb(241 245 249 / var(--tw-bg-opacity));\n}\n.bg-slate-200 {\n --tw-bg-opacity: 1;\n background-color: rgb(226 232 240 / var(--tw-bg-opacity));\n}\n.bg-slate-300 {\n --tw-bg-opacity: 1;\n background-color: rgb(203 213 225 / var(--tw-bg-opacity));\n}\n.bg-slate-800 {\n --tw-bg-opacity: 1;\n background-color: rgb(30 41 59 / var(--tw-bg-opacity));\n}\n.bg-opacity-20 {\n --tw-bg-opacity: 0.2;\n}\n.p-\\[1px\\] {\n padding: 1px;\n}\n.pb-0 {\n padding-bottom: 0px;\n}\n.pl-1 {\n padding-left: 0.25rem;\n}\n.pl-2 {\n padding-left: 0.5rem;\n}\n.pr-0 {\n padding-right: 0px;\n}\n.pr-1 {\n padding-right: 0.25rem;\n}\n.pt-\\[8px\\] {\n padding-top: 8px;\n}\n.font-mono {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n.text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.line-through {\n text-decoration-line: line-through;\n}\n.opacity-50 {\n opacity: 0.5;\n}\n.shadow {\n --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.shadow-slate-300 {\n --tw-shadow-color: #cbd5e1;\n --tw-shadow: var(--tw-shadow-colored);\n}\n.shadow-slate-600 {\n --tw-shadow-color: #475569;\n --tw-shadow: var(--tw-shadow-colored);\n}\n.outline {\n outline-style: solid;\n}\n.filter {\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.hover\\:bg-slate-400:hover {\n --tw-bg-opacity: 1;\n background-color: rgb(148 163 184 / var(--tw-bg-opacity));\n}\n.peer:hover ~ .peer-hover\\:border-slate-400 {\n --tw-border-opacity: 1;\n border-color: rgb(148 163 184 / var(--tw-border-opacity));\n}\n.peer:hover ~ .peer-hover\\:bg-slate-300 {\n --tw-bg-opacity: 1;\n background-color: rgb(203 213 225 / var(--tw-bg-opacity));\n}\n.data-\\[focused\\]\\:bg-slate-400[data-focused] {\n --tw-bg-opacity: 1;\n background-color: rgb(148 163 184 / var(--tw-bg-opacity));\n}\n.peer[data-focused] ~ .peer-data-\\[focused\\]\\:border-slate-400 {\n --tw-border-opacity: 1;\n border-color: rgb(148 163 184 / var(--tw-border-opacity));\n}\n.peer[data-focused] ~ .peer-data-\\[focused\\]\\:bg-slate-300 {\n --tw-bg-opacity: 1;\n background-color: rgb(203 213 225 / var(--tw-bg-opacity));\n}\n";
|
|
1
|
+
const twStyle = "/*\n! tailwindcss v3.4.4 | MIT License | https://tailwindcss.com\n*//*\n1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)\n2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)\n*/\n\n*,\n::before,\n::after {\n box-sizing: border-box; /* 1 */\n border-width: 0; /* 2 */\n border-style: solid; /* 2 */\n border-color: #e5e7eb; /* 2 */\n}\n\n::before,\n::after {\n --tw-content: '';\n}\n\n/*\n1. Use a consistent sensible line-height in all browsers.\n2. Prevent adjustments of font size after orientation changes in iOS.\n3. Use a more readable tab size.\n4. Use the user's configured `sans` font-family by default.\n5. Use the user's configured `sans` font-feature-settings by default.\n6. Use the user's configured `sans` font-variation-settings by default.\n7. Disable tap highlights on iOS\n*/\n\nhtml,\n:host {\n line-height: 1.5; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n -moz-tab-size: 4; /* 3 */\n -o-tab-size: 4;\n tab-size: 4; /* 3 */\n font-family: ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; /* 4 */\n font-feature-settings: normal; /* 5 */\n font-variation-settings: normal; /* 6 */\n -webkit-tap-highlight-color: transparent; /* 7 */\n}\n\n/*\n1. Remove the margin in all browsers.\n2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.\n*/\n\nbody {\n margin: 0; /* 1 */\n line-height: inherit; /* 2 */\n}\n\n/*\n1. Add the correct height in Firefox.\n2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)\n3. Ensure horizontal rules are visible by default.\n*/\n\nhr {\n height: 0; /* 1 */\n color: inherit; /* 2 */\n border-top-width: 1px; /* 3 */\n}\n\n/*\nAdd the correct text decoration in Chrome, Edge, and Safari.\n*/\n\nabbr:where([title]) {\n -webkit-text-decoration: underline dotted;\n text-decoration: underline dotted;\n}\n\n/*\nRemove the default font size and weight for headings.\n*/\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-size: inherit;\n font-weight: inherit;\n}\n\n/*\nReset links to optimize for opt-in styling instead of opt-out.\n*/\n\na {\n color: inherit;\n text-decoration: inherit;\n}\n\n/*\nAdd the correct font weight in Edge and Safari.\n*/\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/*\n1. Use the user's configured `mono` font-family by default.\n2. Use the user's configured `mono` font-feature-settings by default.\n3. Use the user's configured `mono` font-variation-settings by default.\n4. Correct the odd `em` font sizing in all browsers.\n*/\n\ncode,\nkbd,\nsamp,\npre {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; /* 1 */\n font-feature-settings: normal; /* 2 */\n font-variation-settings: normal; /* 3 */\n font-size: 1em; /* 4 */\n}\n\n/*\nAdd the correct font size in all browsers.\n*/\n\nsmall {\n font-size: 80%;\n}\n\n/*\nPrevent `sub` and `sup` elements from affecting the line height in all browsers.\n*/\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/*\n1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)\n2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)\n3. Remove gaps between table borders by default.\n*/\n\ntable {\n text-indent: 0; /* 1 */\n border-color: inherit; /* 2 */\n border-collapse: collapse; /* 3 */\n}\n\n/*\n1. Change the font styles in all browsers.\n2. Remove the margin in Firefox and Safari.\n3. Remove default padding in all browsers.\n*/\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-feature-settings: inherit; /* 1 */\n font-variation-settings: inherit; /* 1 */\n font-size: 100%; /* 1 */\n font-weight: inherit; /* 1 */\n line-height: inherit; /* 1 */\n letter-spacing: inherit; /* 1 */\n color: inherit; /* 1 */\n margin: 0; /* 2 */\n padding: 0; /* 3 */\n}\n\n/*\nRemove the inheritance of text transform in Edge and Firefox.\n*/\n\nbutton,\nselect {\n text-transform: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Remove default button styles.\n*/\n\nbutton,\ninput:where([type='button']),\ninput:where([type='reset']),\ninput:where([type='submit']) {\n -webkit-appearance: button; /* 1 */\n background-color: transparent; /* 2 */\n background-image: none; /* 2 */\n}\n\n/*\nUse the modern Firefox focus style for all focusable elements.\n*/\n\n:-moz-focusring {\n outline: auto;\n}\n\n/*\nRemove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)\n*/\n\n:-moz-ui-invalid {\n box-shadow: none;\n}\n\n/*\nAdd the correct vertical alignment in Chrome and Firefox.\n*/\n\nprogress {\n vertical-align: baseline;\n}\n\n/*\nCorrect the cursor style of increment and decrement buttons in Safari.\n*/\n\n::-webkit-inner-spin-button,\n::-webkit-outer-spin-button {\n height: auto;\n}\n\n/*\n1. Correct the odd appearance in Chrome and Safari.\n2. Correct the outline style in Safari.\n*/\n\n[type='search'] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/*\nRemove the inner padding in Chrome and Safari on macOS.\n*/\n\n::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/*\n1. Correct the inability to style clickable types in iOS and Safari.\n2. Change font properties to `inherit` in Safari.\n*/\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/*\nAdd the correct display in Chrome and Safari.\n*/\n\nsummary {\n display: list-item;\n}\n\n/*\nRemoves the default spacing and border for appropriate elements.\n*/\n\nblockquote,\ndl,\ndd,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\nhr,\nfigure,\np,\npre {\n margin: 0;\n}\n\nfieldset {\n margin: 0;\n padding: 0;\n}\n\nlegend {\n padding: 0;\n}\n\nol,\nul,\nmenu {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n/*\nReset default styling for dialogs.\n*/\ndialog {\n padding: 0;\n}\n\n/*\nPrevent resizing textareas horizontally by default.\n*/\n\ntextarea {\n resize: vertical;\n}\n\n/*\n1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)\n2. Set the default placeholder color to the user's configured gray 400 color.\n*/\n\ninput::-moz-placeholder, textarea::-moz-placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\ninput::placeholder,\ntextarea::placeholder {\n opacity: 1; /* 1 */\n color: #9ca3af; /* 2 */\n}\n\n/*\nSet the default cursor for buttons.\n*/\n\nbutton,\n[role=\"button\"] {\n cursor: pointer;\n}\n\n/*\nMake sure disabled buttons don't get the pointer cursor.\n*/\n:disabled {\n cursor: default;\n}\n\n/*\n1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)\n2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)\n This can trigger a poorly considered lint error in some tools but is included by design.\n*/\n\nimg,\nsvg,\nvideo,\ncanvas,\naudio,\niframe,\nembed,\nobject {\n display: block; /* 1 */\n vertical-align: middle; /* 2 */\n}\n\n/*\nConstrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)\n*/\n\nimg,\nvideo {\n max-width: 100%;\n height: auto;\n}\n\n/* Make elements with the HTML hidden attribute stay hidden by default */\n[hidden] {\n display: none;\n}\n\n*, ::before, ::after {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n --tw-contain-size: ;\n --tw-contain-layout: ;\n --tw-contain-paint: ;\n --tw-contain-style: ;\n}\n\n::backdrop {\n --tw-border-spacing-x: 0;\n --tw-border-spacing-y: 0;\n --tw-translate-x: 0;\n --tw-translate-y: 0;\n --tw-rotate: 0;\n --tw-skew-x: 0;\n --tw-skew-y: 0;\n --tw-scale-x: 1;\n --tw-scale-y: 1;\n --tw-pan-x: ;\n --tw-pan-y: ;\n --tw-pinch-zoom: ;\n --tw-scroll-snap-strictness: proximity;\n --tw-gradient-from-position: ;\n --tw-gradient-via-position: ;\n --tw-gradient-to-position: ;\n --tw-ordinal: ;\n --tw-slashed-zero: ;\n --tw-numeric-figure: ;\n --tw-numeric-spacing: ;\n --tw-numeric-fraction: ;\n --tw-ring-inset: ;\n --tw-ring-offset-width: 0px;\n --tw-ring-offset-color: #fff;\n --tw-ring-color: rgb(59 130 246 / 0.5);\n --tw-ring-offset-shadow: 0 0 #0000;\n --tw-ring-shadow: 0 0 #0000;\n --tw-shadow: 0 0 #0000;\n --tw-shadow-colored: 0 0 #0000;\n --tw-blur: ;\n --tw-brightness: ;\n --tw-contrast: ;\n --tw-grayscale: ;\n --tw-hue-rotate: ;\n --tw-invert: ;\n --tw-saturate: ;\n --tw-sepia: ;\n --tw-drop-shadow: ;\n --tw-backdrop-blur: ;\n --tw-backdrop-brightness: ;\n --tw-backdrop-contrast: ;\n --tw-backdrop-grayscale: ;\n --tw-backdrop-hue-rotate: ;\n --tw-backdrop-invert: ;\n --tw-backdrop-opacity: ;\n --tw-backdrop-saturate: ;\n --tw-backdrop-sepia: ;\n --tw-contain-size: ;\n --tw-contain-layout: ;\n --tw-contain-paint: ;\n --tw-contain-style: ;\n}\n.container {\n width: 100%;\n}\n@media (min-width: 640px) {\n\n .container {\n max-width: 640px;\n }\n}\n@media (min-width: 768px) {\n\n .container {\n max-width: 768px;\n }\n}\n@media (min-width: 1024px) {\n\n .container {\n max-width: 1024px;\n }\n}\n@media (min-width: 1280px) {\n\n .container {\n max-width: 1280px;\n }\n}\n@media (min-width: 1536px) {\n\n .container {\n max-width: 1536px;\n }\n}\n.pointer-events-none {\n pointer-events: none;\n}\n.visible {\n visibility: visible;\n}\n.static {\n position: static;\n}\n.fixed {\n position: fixed;\n}\n.absolute {\n position: absolute;\n}\n.relative {\n position: relative;\n}\n.inset-0 {\n inset: 0px;\n}\n.top-0 {\n top: 0px;\n}\n.z-10 {\n z-index: 10;\n}\n.z-20 {\n z-index: 20;\n}\n.col-span-2 {\n grid-column: span 2 / span 2;\n}\n.mx-2 {\n margin-left: 0.5rem;\n margin-right: 0.5rem;\n}\n.mb-\\[1px\\] {\n margin-bottom: 1px;\n}\n.block {\n display: block;\n}\n.inline-block {\n display: inline-block;\n}\n.inline {\n display: inline;\n}\n.flex {\n display: flex;\n}\n.grid {\n display: grid;\n}\n.contents {\n display: contents;\n}\n.hidden {\n display: none;\n}\n.h-\\[1\\.1rem\\] {\n height: 1.1rem;\n}\n.h-\\[5px\\] {\n height: 5px;\n}\n.h-full {\n height: 100%;\n}\n.w-1 {\n width: 0.25rem;\n}\n.w-\\[2px\\] {\n width: 2px;\n}\n.w-full {\n width: 100%;\n}\n.transform {\n transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));\n}\n.cursor-crosshair {\n cursor: crosshair;\n}\n.resize {\n resize: both;\n}\n.flex-wrap {\n flex-wrap: wrap;\n}\n.place-content-center {\n place-content: center;\n}\n.items-center {\n align-items: center;\n}\n.overflow-auto {\n overflow: auto;\n}\n.overflow-hidden {\n overflow: hidden;\n}\n.text-nowrap {\n text-wrap: nowrap;\n}\n.rounded {\n border-radius: 0.25rem;\n}\n.border {\n border-width: 1px;\n}\n.border-r-2 {\n border-right-width: 2px;\n}\n.border-blue-500 {\n --tw-border-opacity: 1;\n border-color: rgb(59 130 246 / var(--tw-border-opacity));\n}\n.border-red-700 {\n --tw-border-opacity: 1;\n border-color: rgb(185 28 28 / var(--tw-border-opacity));\n}\n.border-slate-500 {\n --tw-border-opacity: 1;\n border-color: rgb(100 116 139 / var(--tw-border-opacity));\n}\n.border-b-slate-600 {\n --tw-border-opacity: 1;\n border-bottom-color: rgb(71 85 105 / var(--tw-border-opacity));\n}\n.bg-blue-200 {\n --tw-bg-opacity: 1;\n background-color: rgb(191 219 254 / var(--tw-bg-opacity));\n}\n.bg-blue-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(59 130 246 / var(--tw-bg-opacity));\n}\n.bg-red-500 {\n --tw-bg-opacity: 1;\n background-color: rgb(239 68 68 / var(--tw-bg-opacity));\n}\n.bg-slate-100 {\n --tw-bg-opacity: 1;\n background-color: rgb(241 245 249 / var(--tw-bg-opacity));\n}\n.bg-slate-200 {\n --tw-bg-opacity: 1;\n background-color: rgb(226 232 240 / var(--tw-bg-opacity));\n}\n.bg-slate-300 {\n --tw-bg-opacity: 1;\n background-color: rgb(203 213 225 / var(--tw-bg-opacity));\n}\n.bg-slate-800 {\n --tw-bg-opacity: 1;\n background-color: rgb(30 41 59 / var(--tw-bg-opacity));\n}\n.bg-opacity-20 {\n --tw-bg-opacity: 0.2;\n}\n.p-\\[1px\\] {\n padding: 1px;\n}\n.pb-0 {\n padding-bottom: 0px;\n}\n.pl-1 {\n padding-left: 0.25rem;\n}\n.pl-2 {\n padding-left: 0.5rem;\n}\n.pr-0 {\n padding-right: 0px;\n}\n.pr-1 {\n padding-right: 0.25rem;\n}\n.pt-\\[8px\\] {\n padding-top: 8px;\n}\n.font-mono {\n font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;\n}\n.text-sm {\n font-size: 0.875rem;\n line-height: 1.25rem;\n}\n.text-xs {\n font-size: 0.75rem;\n line-height: 1rem;\n}\n.line-through {\n text-decoration-line: line-through;\n}\n.opacity-50 {\n opacity: 0.5;\n}\n.shadow {\n --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);\n --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);\n box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);\n}\n.shadow-slate-300 {\n --tw-shadow-color: #cbd5e1;\n --tw-shadow: var(--tw-shadow-colored);\n}\n.shadow-slate-600 {\n --tw-shadow-color: #475569;\n --tw-shadow: var(--tw-shadow-colored);\n}\n.outline {\n outline-style: solid;\n}\n.filter {\n filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);\n}\n.hover\\:bg-slate-400:hover {\n --tw-bg-opacity: 1;\n background-color: rgb(148 163 184 / var(--tw-bg-opacity));\n}\n.peer:hover ~ .peer-hover\\:border-slate-400 {\n --tw-border-opacity: 1;\n border-color: rgb(148 163 184 / var(--tw-border-opacity));\n}\n.peer:hover ~ .peer-hover\\:bg-slate-300 {\n --tw-bg-opacity: 1;\n background-color: rgb(203 213 225 / var(--tw-bg-opacity));\n}\n.data-\\[focused\\]\\:bg-slate-400[data-focused] {\n --tw-bg-opacity: 1;\n background-color: rgb(148 163 184 / var(--tw-bg-opacity));\n}\n.peer[data-focused] ~ .peer-data-\\[focused\\]\\:border-slate-400 {\n --tw-border-opacity: 1;\n border-color: rgb(148 163 184 / var(--tw-border-opacity));\n}\n.peer[data-focused] ~ .peer-data-\\[focused\\]\\:bg-slate-300 {\n --tw-bg-opacity: 1;\n background-color: rgb(203 213 225 / var(--tw-bg-opacity));\n}\n";
|
|
2
2
|
export {
|
|
3
3
|
twStyle as default
|
|
4
4
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -14,4 +14,5 @@ export { EFToggleLoop } from './gui/EFToggleLoop.js';
|
|
|
14
14
|
export { EFScrubber } from './gui/EFScrubber.js';
|
|
15
15
|
export { EFTimeDisplay } from './gui/EFTimeDisplay.js';
|
|
16
16
|
export { EFFocusOverlay } from './gui/EFFocusOverlay.js';
|
|
17
|
+
export { EFFitScale } from './gui/EFFitScale.js';
|
|
17
18
|
export { getRenderInfo, RenderInfo } from './getRenderInfo.js';
|
package/dist/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import { EFToggleLoop } from "./gui/EFToggleLoop.js";
|
|
|
15
15
|
import { EFScrubber } from "./gui/EFScrubber.js";
|
|
16
16
|
import { EFTimeDisplay } from "./gui/EFTimeDisplay.js";
|
|
17
17
|
import { EFFocusOverlay } from "./gui/EFFocusOverlay.js";
|
|
18
|
+
import { EFFitScale } from "./gui/EFFitScale.js";
|
|
18
19
|
import "./EF_FRAMEGEN.js";
|
|
19
20
|
import { RenderInfo, getRenderInfo } from "./getRenderInfo.js";
|
|
20
21
|
if (typeof window !== "undefined") {
|
|
@@ -29,6 +30,7 @@ export {
|
|
|
29
30
|
EFCaptionsSegment,
|
|
30
31
|
EFConfiguration,
|
|
31
32
|
EFFilmstrip,
|
|
33
|
+
EFFitScale,
|
|
32
34
|
EFFocusOverlay,
|
|
33
35
|
EFImage,
|
|
34
36
|
EFPreview,
|
package/dist/style.css
CHANGED
|
@@ -628,15 +628,9 @@ video {
|
|
|
628
628
|
.place-content-center {
|
|
629
629
|
place-content: center;
|
|
630
630
|
}
|
|
631
|
-
.place-items-center {
|
|
632
|
-
place-items: center;
|
|
633
|
-
}
|
|
634
631
|
.items-center {
|
|
635
632
|
align-items: center;
|
|
636
633
|
}
|
|
637
|
-
.justify-center {
|
|
638
|
-
justify-content: center;
|
|
639
|
-
}
|
|
640
634
|
.overflow-auto {
|
|
641
635
|
overflow: auto;
|
|
642
636
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@editframe/elements",
|
|
3
|
-
"version": "0.15.0-beta.
|
|
3
|
+
"version": "0.15.0-beta.20",
|
|
4
4
|
"description": "",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"license": "UNLICENSED",
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@bramus/style-observer": "^1.3.0",
|
|
30
|
-
"@editframe/assets": "0.15.0-beta.
|
|
30
|
+
"@editframe/assets": "0.15.0-beta.20",
|
|
31
31
|
"@lit/context": "^1.1.2",
|
|
32
32
|
"@lit/task": "^1.0.1",
|
|
33
33
|
"d3": "^7.9.0",
|
|
@@ -148,7 +148,7 @@ describe("EFMedia", () => {
|
|
|
148
148
|
timegroup.mode = "sequence";
|
|
149
149
|
const element = document.createElement("test-media");
|
|
150
150
|
element.src = "/assets/10s-bars.mp4";
|
|
151
|
-
element.
|
|
151
|
+
element.sourceInMs = 1_000;
|
|
152
152
|
|
|
153
153
|
const preview = document.createElement("ef-preview");
|
|
154
154
|
timegroup.appendChild(element);
|
|
@@ -180,7 +180,7 @@ describe("EFMedia", () => {
|
|
|
180
180
|
timegroup.mode = "sequence";
|
|
181
181
|
const element = document.createElement("test-media");
|
|
182
182
|
element.src = "/assets/10s-bars.mp4";
|
|
183
|
-
element.
|
|
183
|
+
element.sourceInMs = 6_000;
|
|
184
184
|
|
|
185
185
|
const preview = document.createElement("ef-preview");
|
|
186
186
|
timegroup.appendChild(element);
|
|
@@ -212,7 +212,7 @@ describe("EFMedia", () => {
|
|
|
212
212
|
timegroup.mode = "sequence";
|
|
213
213
|
const element = document.createElement("test-media");
|
|
214
214
|
element.src = "/assets/10s-bars.mp4";
|
|
215
|
-
element.
|
|
215
|
+
element.sourceOutMs = 6_000;
|
|
216
216
|
|
|
217
217
|
const preview = document.createElement("ef-preview");
|
|
218
218
|
timegroup.appendChild(element);
|
|
@@ -224,8 +224,8 @@ describe("EFMedia", () => {
|
|
|
224
224
|
|
|
225
225
|
await element.trackFragmentIndexLoader.taskComplete;
|
|
226
226
|
|
|
227
|
-
expect(element.durationMs).toBe(
|
|
228
|
-
expect(timegroup.durationMs).toBe(
|
|
227
|
+
expect(element.durationMs).toBe(6_000);
|
|
228
|
+
expect(timegroup.durationMs).toBe(6_000);
|
|
229
229
|
});
|
|
230
230
|
test("Computes duration from track fragment index sourceout", async () => {
|
|
231
231
|
// Mock the request for the track fragment index, responds with a 10 second duration
|
|
@@ -244,7 +244,7 @@ describe("EFMedia", () => {
|
|
|
244
244
|
timegroup.mode = "sequence";
|
|
245
245
|
const element = document.createElement("test-media");
|
|
246
246
|
element.src = "/assets/10s-bars.mp4";
|
|
247
|
-
element.
|
|
247
|
+
element.sourceOutMs = 5_000;
|
|
248
248
|
|
|
249
249
|
const preview = document.createElement("ef-preview");
|
|
250
250
|
timegroup.appendChild(element);
|
|
@@ -276,8 +276,8 @@ describe("EFMedia", () => {
|
|
|
276
276
|
timegroup.mode = "sequence";
|
|
277
277
|
const element = document.createElement("test-media");
|
|
278
278
|
element.src = "/assets/10s-bars.mp4";
|
|
279
|
-
element.
|
|
280
|
-
element.
|
|
279
|
+
element.sourceInMs = 1_000;
|
|
280
|
+
element.sourceOutMs = 5_000;
|
|
281
281
|
|
|
282
282
|
const preview = document.createElement("ef-preview");
|
|
283
283
|
timegroup.appendChild(element);
|
|
@@ -310,8 +310,8 @@ describe("EFMedia", () => {
|
|
|
310
310
|
timegroup.mode = "sequence";
|
|
311
311
|
const element = document.createElement("test-media");
|
|
312
312
|
element.src = "/assets/10s-bars.mp4";
|
|
313
|
-
element.
|
|
314
|
-
element.
|
|
313
|
+
element.sourceInMs = 9_000;
|
|
314
|
+
element.sourceOutMs = 10_000;
|
|
315
315
|
|
|
316
316
|
const preview = document.createElement("ef-preview");
|
|
317
317
|
timegroup.appendChild(element);
|
package/src/elements/EFMedia.ts
CHANGED
|
@@ -12,9 +12,10 @@ import { MP4File } from "@editframe/assets/MP4File.js";
|
|
|
12
12
|
import { EF_INTERACTIVE } from "../EF_INTERACTIVE.js";
|
|
13
13
|
import { EF_RENDERING } from "../EF_RENDERING.js";
|
|
14
14
|
import { EFSourceMixin } from "./EFSourceMixin.js";
|
|
15
|
-
import { EFTemporal
|
|
15
|
+
import { EFTemporal } from "./EFTemporal.js";
|
|
16
16
|
import { FetchMixin } from "./FetchMixin.js";
|
|
17
17
|
import { EFTargetable } from "./TargetController.ts";
|
|
18
|
+
import { updateAnimations } from "./updateAnimations.ts";
|
|
18
19
|
|
|
19
20
|
const log = debug("ef:elements:EFMedia");
|
|
20
21
|
|
|
@@ -136,8 +137,11 @@ export class EFMedia extends EFTargetable(
|
|
|
136
137
|
}
|
|
137
138
|
},
|
|
138
139
|
onComplete: () => {
|
|
140
|
+
this.requestUpdate("intrinsicDurationMs");
|
|
139
141
|
this.requestUpdate("ownCurrentTimeMs");
|
|
142
|
+
console.log("Requesting update for durationMs", this, this.rootTimegroup);
|
|
140
143
|
this.rootTimegroup?.requestUpdate("ownCurrentTimeMs");
|
|
144
|
+
this.rootTimegroup?.requestUpdate("durationMs");
|
|
141
145
|
},
|
|
142
146
|
});
|
|
143
147
|
|
|
@@ -347,75 +351,7 @@ export class EFMedia extends EFTargetable(
|
|
|
347
351
|
changedProperties.has("currentTime") ||
|
|
348
352
|
changedProperties.has("ownCurrentTimeMs")
|
|
349
353
|
) {
|
|
350
|
-
|
|
351
|
-
if (
|
|
352
|
-
this.startTimeMs > timelineTimeMs ||
|
|
353
|
-
this.endTimeMs < timelineTimeMs
|
|
354
|
-
) {
|
|
355
|
-
this.style.display = "none";
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
this.style.display = "";
|
|
359
|
-
const animations = this.getAnimations({ subtree: true });
|
|
360
|
-
|
|
361
|
-
this.style.setProperty("--ef-duration", `${this.durationMs}ms`);
|
|
362
|
-
this.style.setProperty(
|
|
363
|
-
"--ef-transition-duration",
|
|
364
|
-
`${this.parentTimegroup?.overlapMs ?? 0}ms`,
|
|
365
|
-
);
|
|
366
|
-
this.style.setProperty(
|
|
367
|
-
"--ef-transition-out-start",
|
|
368
|
-
`${this.durationMs - (this.parentTimegroup?.overlapMs ?? 0)}ms`,
|
|
369
|
-
);
|
|
370
|
-
|
|
371
|
-
for (const animation of animations) {
|
|
372
|
-
if (animation.playState === "running") {
|
|
373
|
-
animation.pause();
|
|
374
|
-
}
|
|
375
|
-
const effect = animation.effect;
|
|
376
|
-
if (!(effect && effect instanceof KeyframeEffect)) {
|
|
377
|
-
return;
|
|
378
|
-
}
|
|
379
|
-
const target = effect.target;
|
|
380
|
-
// TODO: better generalize work avoidance for temporal elements
|
|
381
|
-
if (!target) {
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
if (target.closest("ef-video, ef-audio") !== this) {
|
|
385
|
-
return;
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
// Important to avoid going to the end of the animation
|
|
389
|
-
// or it will reset awkwardly.
|
|
390
|
-
if (isEFTemporal(target)) {
|
|
391
|
-
const timing = effect.getTiming();
|
|
392
|
-
const duration = Number(timing.duration) ?? 0;
|
|
393
|
-
const delay = Number(timing.delay);
|
|
394
|
-
const newTime = Math.floor(
|
|
395
|
-
Math.min(target.ownCurrentTimeMs, duration - 1 + delay),
|
|
396
|
-
);
|
|
397
|
-
if (Number.isNaN(newTime)) {
|
|
398
|
-
return;
|
|
399
|
-
}
|
|
400
|
-
animation.currentTime = newTime;
|
|
401
|
-
} else if (target) {
|
|
402
|
-
const nearestTimegroup = target.closest("ef-timegroup");
|
|
403
|
-
if (!nearestTimegroup) {
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
|
-
const timing = effect.getTiming();
|
|
407
|
-
const duration = Number(timing.duration) ?? 0;
|
|
408
|
-
const delay = Number(timing.delay);
|
|
409
|
-
const newTime = Math.floor(
|
|
410
|
-
Math.min(nearestTimegroup.ownCurrentTimeMs, duration - 1 + delay),
|
|
411
|
-
);
|
|
412
|
-
|
|
413
|
-
if (Number.isNaN(newTime)) {
|
|
414
|
-
return;
|
|
415
|
-
}
|
|
416
|
-
animation.currentTime = newTime;
|
|
417
|
-
}
|
|
418
|
-
}
|
|
354
|
+
updateAnimations(this);
|
|
419
355
|
}
|
|
420
356
|
}
|
|
421
357
|
|
|
@@ -423,7 +359,7 @@ export class EFMedia extends EFTargetable(
|
|
|
423
359
|
return true;
|
|
424
360
|
}
|
|
425
361
|
|
|
426
|
-
get
|
|
362
|
+
get intrinsicDurationMs() {
|
|
427
363
|
if (!this.trackFragmentIndexLoader.value) {
|
|
428
364
|
return 0;
|
|
429
365
|
}
|
|
@@ -436,39 +372,7 @@ export class EFMedia extends EFTargetable(
|
|
|
436
372
|
if (durations.length === 0) {
|
|
437
373
|
return 0;
|
|
438
374
|
}
|
|
439
|
-
|
|
440
|
-
this.sourceInMs &&
|
|
441
|
-
this.sourceOutMs &&
|
|
442
|
-
this.sourceOutMs > this.sourceInMs
|
|
443
|
-
) {
|
|
444
|
-
return Math.max(this.sourceOutMs - this.sourceInMs);
|
|
445
|
-
}
|
|
446
|
-
if (this.sourceInMs) {
|
|
447
|
-
return (
|
|
448
|
-
Math.max(...durations) -
|
|
449
|
-
this.trimStartMs -
|
|
450
|
-
this.trimEndMs -
|
|
451
|
-
this.sourceInMs
|
|
452
|
-
);
|
|
453
|
-
}
|
|
454
|
-
if (this.sourceOutMs) {
|
|
455
|
-
return (
|
|
456
|
-
Math.max(...durations) -
|
|
457
|
-
this.trimStartMs -
|
|
458
|
-
this.trimEndMs -
|
|
459
|
-
this.sourceOutMs
|
|
460
|
-
);
|
|
461
|
-
}
|
|
462
|
-
if (this.sourceInMs && this.sourceOutMs) {
|
|
463
|
-
return (
|
|
464
|
-
Math.max(...durations) -
|
|
465
|
-
this.trimStartMs -
|
|
466
|
-
this.trimEndMs -
|
|
467
|
-
this.sourceOutMs -
|
|
468
|
-
this.sourceInMs
|
|
469
|
-
);
|
|
470
|
-
}
|
|
471
|
-
return Math.max(...durations) - this.trimStartMs - this.trimEndMs;
|
|
375
|
+
return Math.max(...durations);
|
|
472
376
|
}
|
|
473
377
|
|
|
474
378
|
#audioContext = new OfflineAudioContext(2, 48000 / 30, 48000);
|
|
@@ -506,13 +410,15 @@ export class EFMedia extends EFTargetable(
|
|
|
506
410
|
async fetchAudioSpanningTime(fromMs: number, toMs: number) {
|
|
507
411
|
// Adjust range for track's own time
|
|
508
412
|
if (this.sourceInMs) {
|
|
509
|
-
fromMs -=
|
|
413
|
+
fromMs -=
|
|
414
|
+
this.startTimeMs - (this.trimStartMs ?? 0) - (this.sourceInMs ?? 0);
|
|
510
415
|
}
|
|
511
416
|
if (this.sourceOutMs) {
|
|
512
|
-
toMs -=
|
|
417
|
+
toMs -=
|
|
418
|
+
this.startTimeMs - (this.trimStartMs ?? 0) - (this.sourceOutMs ?? 0);
|
|
513
419
|
}
|
|
514
|
-
fromMs -= this.startTimeMs - this.trimStartMs;
|
|
515
|
-
toMs -= this.startTimeMs - this.trimStartMs;
|
|
420
|
+
fromMs -= this.startTimeMs - (this.trimStartMs ?? 0);
|
|
421
|
+
toMs -= this.startTimeMs - (this.trimStartMs ?? 0);
|
|
516
422
|
|
|
517
423
|
await this.trackFragmentIndexLoader.taskComplete;
|
|
518
424
|
const audioTrackId = this.defaultAudioTrackId;
|
|
@@ -582,11 +488,11 @@ export class EFMedia extends EFTargetable(
|
|
|
582
488
|
blob: audioBlob,
|
|
583
489
|
startMs:
|
|
584
490
|
(firstFragment.dts / audioTrackIndex.timescale) * 1000 -
|
|
585
|
-
this.trimStartMs,
|
|
491
|
+
(this.trimStartMs ?? 0),
|
|
586
492
|
endMs:
|
|
587
493
|
(lastFragment.dts / audioTrackIndex.timescale) * 1000 +
|
|
588
494
|
(lastFragment.duration / audioTrackIndex.timescale) * 1000 -
|
|
589
|
-
this.trimEndMs,
|
|
495
|
+
(this.trimEndMs ?? 0),
|
|
590
496
|
};
|
|
591
497
|
}
|
|
592
498
|
|
|
@@ -610,6 +516,16 @@ export class EFMedia extends EFTargetable(
|
|
|
610
516
|
return Number.parseInt(this.getAttribute("fft-decay") ?? "8", 10);
|
|
611
517
|
}
|
|
612
518
|
|
|
519
|
+
set interpolateFrequencies(value: boolean) {
|
|
520
|
+
const oldValue = this.interpolateFrequencies;
|
|
521
|
+
this.setAttribute("interpolate-frequencies", String(value));
|
|
522
|
+
this.requestUpdate("interpolate-frequencies", oldValue);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
get interpolateFrequencies() {
|
|
526
|
+
return this.getAttribute("interpolate-frequencies") !== "false";
|
|
527
|
+
}
|
|
528
|
+
|
|
613
529
|
get shouldInterpolateFrequencies() {
|
|
614
530
|
if (this.hasAttribute("interpolate-frequencies")) {
|
|
615
531
|
return this.getAttribute("interpolate-frequencies") !== "false";
|
|
@@ -651,6 +567,8 @@ export class EFMedia extends EFTargetable(
|
|
|
651
567
|
this.currentSourceTimeMs,
|
|
652
568
|
this.fftSize,
|
|
653
569
|
this.fftDecay,
|
|
570
|
+
this.fftGain,
|
|
571
|
+
this.shouldInterpolateFrequencies,
|
|
654
572
|
] as const,
|
|
655
573
|
task: async () => {
|
|
656
574
|
await this.audioBufferTask.taskComplete;
|
|
@@ -661,7 +579,7 @@ export class EFMedia extends EFTargetable(
|
|
|
661
579
|
const startOffsetMs = this.audioBufferTask.value.startOffsetMs;
|
|
662
580
|
const audioBuffer = this.audioBufferTask.value.buffer;
|
|
663
581
|
|
|
664
|
-
const smoothedKey = `${this.fftSize}:${this.fftDecay}:${startOffsetMs}:${currentTimeMs}`;
|
|
582
|
+
const smoothedKey = `${this.shouldInterpolateFrequencies}:${this.fftSize}:${this.fftDecay}:${this.fftGain}:${startOffsetMs}:${currentTimeMs}`;
|
|
665
583
|
const cachedData = this.#byteTimeDomainCache.get(smoothedKey);
|
|
666
584
|
if (cachedData) return cachedData;
|
|
667
585
|
|
|
@@ -674,7 +592,7 @@ export class EFMedia extends EFTargetable(
|
|
|
674
592
|
(currentTimeMs - frameOffset - startOffsetMs) / 1000,
|
|
675
593
|
);
|
|
676
594
|
|
|
677
|
-
const cacheKey = `${this.fftSize}:${startOffsetMs}:${startTime}`;
|
|
595
|
+
const cacheKey = `${this.shouldInterpolateFrequencies}:${this.fftSize}:${this.fftGain}:${startOffsetMs}:${startTime}`;
|
|
678
596
|
const cachedFrame = this.#byteTimeDomainCache.get(cacheKey);
|
|
679
597
|
if (cachedFrame) return cachedFrame;
|
|
680
598
|
|
|
@@ -694,7 +612,7 @@ export class EFMedia extends EFTargetable(
|
|
|
694
612
|
analyser.maxDecibels = -20;
|
|
695
613
|
|
|
696
614
|
const gainNode = audioContext.createGain();
|
|
697
|
-
gainNode.gain.value =
|
|
615
|
+
gainNode.gain.value = this.fftGain; // Amplify the signal
|
|
698
616
|
|
|
699
617
|
source.connect(gainNode);
|
|
700
618
|
gainNode.connect(analyser);
|
|
@@ -773,8 +691,10 @@ export class EFMedia extends EFTargetable(
|
|
|
773
691
|
[
|
|
774
692
|
this.audioBufferTask.status,
|
|
775
693
|
this.currentSourceTimeMs,
|
|
776
|
-
this.fftSize,
|
|
777
|
-
this.fftDecay,
|
|
694
|
+
this.fftSize,
|
|
695
|
+
this.fftDecay,
|
|
696
|
+
this.fftGain,
|
|
697
|
+
this.shouldInterpolateFrequencies,
|
|
778
698
|
] as const,
|
|
779
699
|
task: async () => {
|
|
780
700
|
await this.audioBufferTask.taskComplete;
|
|
@@ -784,7 +704,7 @@ export class EFMedia extends EFTargetable(
|
|
|
784
704
|
const currentTimeMs = this.currentSourceTimeMs;
|
|
785
705
|
const startOffsetMs = this.audioBufferTask.value.startOffsetMs;
|
|
786
706
|
const audioBuffer = this.audioBufferTask.value.buffer;
|
|
787
|
-
const smoothedKey = `${this.fftSize}:${this.fftDecay}:${startOffsetMs}:${currentTimeMs}`;
|
|
707
|
+
const smoothedKey = `${this.shouldInterpolateFrequencies}:${this.fftSize}:${this.fftDecay}:${this.fftGain}:${startOffsetMs}:${currentTimeMs}`;
|
|
788
708
|
|
|
789
709
|
const cachedSmoothedData = this.#frequencyDataCache.get(smoothedKey);
|
|
790
710
|
if (cachedSmoothedData) {
|
|
@@ -800,7 +720,7 @@ export class EFMedia extends EFTargetable(
|
|
|
800
720
|
);
|
|
801
721
|
|
|
802
722
|
// Cache key for this specific frame
|
|
803
|
-
const cacheKey = `${this.fftSize}:${startOffsetMs}:${startTime}`;
|
|
723
|
+
const cacheKey = `${this.shouldInterpolateFrequencies}:${this.fftSize}:${this.fftGain}:${startOffsetMs}:${startTime}`;
|
|
804
724
|
|
|
805
725
|
// Check cache for this specific frame
|
|
806
726
|
const cachedFrame = this.#frequencyDataCache.get(cacheKey);
|
|
@@ -819,7 +739,7 @@ export class EFMedia extends EFTargetable(
|
|
|
819
739
|
analyser.maxDecibels = -10;
|
|
820
740
|
|
|
821
741
|
const gainNode = audioContext.createGain();
|
|
822
|
-
gainNode.gain.value =
|
|
742
|
+
gainNode.gain.value = this.fftGain;
|
|
823
743
|
|
|
824
744
|
const filter = audioContext.createBiquadFilter();
|
|
825
745
|
filter.type = "bandpass";
|
|
@@ -889,6 +809,16 @@ export class EFMedia extends EFTargetable(
|
|
|
889
809
|
return processedData;
|
|
890
810
|
},
|
|
891
811
|
});
|
|
812
|
+
|
|
813
|
+
set fftGain(value: number) {
|
|
814
|
+
const oldValue = this.fftGain;
|
|
815
|
+
this.setAttribute("fft-gain", String(value));
|
|
816
|
+
this.requestUpdate("fft-gain", oldValue);
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
get fftGain() {
|
|
820
|
+
return Number.parseFloat(this.getAttribute("fft-gain") ?? "3.0");
|
|
821
|
+
}
|
|
892
822
|
}
|
|
893
823
|
|
|
894
824
|
function processFFTData(fftData: Uint8Array, zeroThresholdPercent = 0.1) {
|
|
@@ -3,76 +3,109 @@ import { customElement } from "lit/decorators/custom-element.js";
|
|
|
3
3
|
import { describe, expect, test } from "vitest";
|
|
4
4
|
import { EFTemporal } from "./EFTemporal.js";
|
|
5
5
|
|
|
6
|
-
@customElement("
|
|
7
|
-
class
|
|
6
|
+
@customElement("ten-seconds")
|
|
7
|
+
class TenSeconds extends EFTemporal(LitElement) {
|
|
8
|
+
get intrinsicDurationMs() {
|
|
9
|
+
return 10_000;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
8
12
|
|
|
9
13
|
declare global {
|
|
10
14
|
interface HTMLElementTagNameMap {
|
|
11
|
-
"
|
|
15
|
+
"ten-seconds": TenSeconds;
|
|
12
16
|
}
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
describe("sourcein and sourceout", () => {
|
|
16
20
|
test("sourcein and sourceout are parsed correctly", () => {
|
|
17
|
-
const element = document.createElement("
|
|
21
|
+
const element = document.createElement("ten-seconds");
|
|
18
22
|
element.setAttribute("sourcein", "1s");
|
|
19
23
|
element.setAttribute("sourceout", "5s");
|
|
20
24
|
expect(element.sourceInMs).toBe(1_000);
|
|
21
25
|
expect(element.sourceOutMs).toBe(5_000);
|
|
26
|
+
expect(element.durationMs).toBe(4_000);
|
|
22
27
|
});
|
|
23
28
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
describe("only srcin is set", () => {
|
|
30
|
+
test("duration is calculated", () => {
|
|
31
|
+
const element = document.createElement("ten-seconds");
|
|
32
|
+
element.sourceInMs = 1_000;
|
|
33
|
+
expect(element.durationMs).toBe(9_000);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe("only srcout is set", () => {
|
|
38
|
+
test("duration is calculated", () => {
|
|
39
|
+
const element = document.createElement("ten-seconds");
|
|
40
|
+
element.sourceOutMs = 5_000;
|
|
41
|
+
expect(element.durationMs).toBe(5_000);
|
|
42
|
+
});
|
|
30
43
|
});
|
|
31
44
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
45
|
+
describe("srcout is before srcin", () => {
|
|
46
|
+
test("duration is zero", () => {
|
|
47
|
+
const element = document.createElement("ten-seconds");
|
|
48
|
+
element.sourceInMs = 5_000;
|
|
49
|
+
element.sourceOutMs = 1_000;
|
|
50
|
+
console.log(element.sourceInMs, element.sourceOutMs, element.durationMs);
|
|
51
|
+
expect(element.durationMs).toBe(0);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe("srcin is negative", () => {
|
|
56
|
+
test("srcin is normalized to 0 ", () => {
|
|
57
|
+
const element = document.createElement("ten-seconds");
|
|
58
|
+
element.sourceInMs = -1_000;
|
|
59
|
+
expect(element.sourceInMs).toBe(0);
|
|
60
|
+
expect(element.durationMs).toBe(10_000);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe("srcout is beyond the intrinsic duration", () => {
|
|
65
|
+
test("srcout is normalized to the intrinsic duration", () => {
|
|
66
|
+
const element = document.createElement("ten-seconds");
|
|
67
|
+
element.sourceOutMs = 15_000;
|
|
68
|
+
expect(element.sourceOutMs).toBe(10_000);
|
|
69
|
+
});
|
|
38
70
|
});
|
|
39
71
|
});
|
|
40
72
|
|
|
41
73
|
describe("trimstart and trimend", () => {
|
|
42
74
|
test("trimstart and trimend attributes are parsed correctly", () => {
|
|
43
|
-
const element = document.createElement("
|
|
75
|
+
const element = document.createElement("ten-seconds");
|
|
44
76
|
element.setAttribute("trimstart", "1s");
|
|
45
77
|
element.setAttribute("trimend", "5s");
|
|
46
78
|
expect(element.trimStartMs).toBe(1_000);
|
|
47
79
|
expect(element.trimEndMs).toBe(5_000);
|
|
80
|
+
expect(element.durationMs).toBe(4_000);
|
|
48
81
|
});
|
|
49
82
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
83
|
+
describe("trimstart is beyond the intrinsic duration", () => {
|
|
84
|
+
test("trimstart is normalized to the intrinsic duration", () => {
|
|
85
|
+
const element = document.createElement("ten-seconds");
|
|
86
|
+
element.trimStartMs = 15_000;
|
|
87
|
+
expect(element.trimStartMs).toBe(10_000);
|
|
88
|
+
});
|
|
56
89
|
});
|
|
57
90
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
91
|
+
describe("trimend is beyond the intrinsic duration", () => {
|
|
92
|
+
test("trimend is normalized to the intrinsic duration", () => {
|
|
93
|
+
const element = document.createElement("ten-seconds");
|
|
94
|
+
element.trimEndMs = 15_000;
|
|
95
|
+
expect(element.trimEndMs).toBe(10_000);
|
|
96
|
+
});
|
|
64
97
|
});
|
|
65
98
|
});
|
|
66
99
|
|
|
67
100
|
describe("duration", () => {
|
|
68
101
|
test("duration is parsed correctly", () => {
|
|
69
|
-
const element = document.createElement("
|
|
102
|
+
const element = document.createElement("ten-seconds");
|
|
70
103
|
element.setAttribute("duration", "10s");
|
|
71
104
|
expect(element.durationMs).toBe(10_000);
|
|
72
105
|
});
|
|
73
106
|
|
|
74
107
|
test("duration can be set directly on the element", () => {
|
|
75
|
-
const element = document.createElement("
|
|
108
|
+
const element = document.createElement("ten-seconds");
|
|
76
109
|
element.duration = "10s";
|
|
77
110
|
expect(element.durationMs).toBe(10_000);
|
|
78
111
|
});
|