@editframe/elements 0.15.0-beta.17 → 0.15.0-beta.19
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 -1
- package/dist/elements/EFMedia.d.ts +7 -3
- package/dist/elements/EFMedia.js +45 -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 -3
- package/dist/elements/EFTimegroup.js +15 -103
- package/dist/elements/EFVideo.js +3 -1
- package/dist/elements/EFWaveform.d.ts +1 -0
- package/dist/elements/EFWaveform.js +6 -2
- 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/gui/EFFilmstrip.js +7 -16
- package/dist/gui/EFFitScale.d.ts +25 -0
- package/dist/gui/EFFitScale.js +123 -0
- package/dist/gui/EFWorkbench.d.ts +1 -5
- package/dist/gui/EFWorkbench.js +6 -55
- 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 +3 -3
- package/package.json +2 -2
- package/src/elements/EFMedia.browsertest.ts +10 -10
- package/src/elements/EFMedia.ts +56 -118
- package/src/elements/EFTemporal.browsertest.ts +64 -31
- package/src/elements/EFTemporal.ts +99 -119
- package/src/elements/EFTimegroup.ts +15 -133
- package/src/elements/EFVideo.ts +3 -1
- package/src/elements/EFWaveform.ts +5 -2
- package/src/elements/durationConverter.ts +9 -4
- package/src/elements/updateAnimations.ts +88 -0
- package/src/gui/EFFilmstrip.ts +7 -16
- package/src/gui/EFFitScale.ts +133 -0
- package/src/gui/EFWorkbench.ts +7 -64
- 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.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
|
@@ -625,12 +625,12 @@ video {
|
|
|
625
625
|
.flex-wrap {
|
|
626
626
|
flex-wrap: wrap;
|
|
627
627
|
}
|
|
628
|
+
.place-content-center {
|
|
629
|
+
place-content: center;
|
|
630
|
+
}
|
|
628
631
|
.items-center {
|
|
629
632
|
align-items: center;
|
|
630
633
|
}
|
|
631
|
-
.justify-center {
|
|
632
|
-
justify-content: center;
|
|
633
|
-
}
|
|
634
634
|
.overflow-auto {
|
|
635
635
|
overflow: auto;
|
|
636
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.19",
|
|
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.19",
|
|
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
|
|
|
@@ -347,75 +348,7 @@ export class EFMedia extends EFTargetable(
|
|
|
347
348
|
changedProperties.has("currentTime") ||
|
|
348
349
|
changedProperties.has("ownCurrentTimeMs")
|
|
349
350
|
) {
|
|
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
|
-
}
|
|
351
|
+
updateAnimations(this);
|
|
419
352
|
}
|
|
420
353
|
}
|
|
421
354
|
|
|
@@ -423,7 +356,7 @@ export class EFMedia extends EFTargetable(
|
|
|
423
356
|
return true;
|
|
424
357
|
}
|
|
425
358
|
|
|
426
|
-
get
|
|
359
|
+
get intrinsicDurationMs() {
|
|
427
360
|
if (!this.trackFragmentIndexLoader.value) {
|
|
428
361
|
return 0;
|
|
429
362
|
}
|
|
@@ -436,39 +369,7 @@ export class EFMedia extends EFTargetable(
|
|
|
436
369
|
if (durations.length === 0) {
|
|
437
370
|
return 0;
|
|
438
371
|
}
|
|
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;
|
|
372
|
+
return Math.max(...durations);
|
|
472
373
|
}
|
|
473
374
|
|
|
474
375
|
#audioContext = new OfflineAudioContext(2, 48000 / 30, 48000);
|
|
@@ -506,13 +407,15 @@ export class EFMedia extends EFTargetable(
|
|
|
506
407
|
async fetchAudioSpanningTime(fromMs: number, toMs: number) {
|
|
507
408
|
// Adjust range for track's own time
|
|
508
409
|
if (this.sourceInMs) {
|
|
509
|
-
fromMs -=
|
|
410
|
+
fromMs -=
|
|
411
|
+
this.startTimeMs - (this.trimStartMs ?? 0) - (this.sourceInMs ?? 0);
|
|
510
412
|
}
|
|
511
413
|
if (this.sourceOutMs) {
|
|
512
|
-
toMs -=
|
|
414
|
+
toMs -=
|
|
415
|
+
this.startTimeMs - (this.trimStartMs ?? 0) - (this.sourceOutMs ?? 0);
|
|
513
416
|
}
|
|
514
|
-
fromMs -= this.startTimeMs - this.trimStartMs;
|
|
515
|
-
toMs -= this.startTimeMs - this.trimStartMs;
|
|
417
|
+
fromMs -= this.startTimeMs - (this.trimStartMs ?? 0);
|
|
418
|
+
toMs -= this.startTimeMs - (this.trimStartMs ?? 0);
|
|
516
419
|
|
|
517
420
|
await this.trackFragmentIndexLoader.taskComplete;
|
|
518
421
|
const audioTrackId = this.defaultAudioTrackId;
|
|
@@ -582,11 +485,11 @@ export class EFMedia extends EFTargetable(
|
|
|
582
485
|
blob: audioBlob,
|
|
583
486
|
startMs:
|
|
584
487
|
(firstFragment.dts / audioTrackIndex.timescale) * 1000 -
|
|
585
|
-
this.trimStartMs,
|
|
488
|
+
(this.trimStartMs ?? 0),
|
|
586
489
|
endMs:
|
|
587
490
|
(lastFragment.dts / audioTrackIndex.timescale) * 1000 +
|
|
588
491
|
(lastFragment.duration / audioTrackIndex.timescale) * 1000 -
|
|
589
|
-
this.trimEndMs,
|
|
492
|
+
(this.trimEndMs ?? 0),
|
|
590
493
|
};
|
|
591
494
|
}
|
|
592
495
|
|
|
@@ -610,6 +513,16 @@ export class EFMedia extends EFTargetable(
|
|
|
610
513
|
return Number.parseInt(this.getAttribute("fft-decay") ?? "8", 10);
|
|
611
514
|
}
|
|
612
515
|
|
|
516
|
+
set interpolateFrequencies(value: boolean) {
|
|
517
|
+
const oldValue = this.interpolateFrequencies;
|
|
518
|
+
this.setAttribute("interpolate-frequencies", String(value));
|
|
519
|
+
this.requestUpdate("interpolate-frequencies", oldValue);
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
get interpolateFrequencies() {
|
|
523
|
+
return this.getAttribute("interpolate-frequencies") !== "false";
|
|
524
|
+
}
|
|
525
|
+
|
|
613
526
|
get shouldInterpolateFrequencies() {
|
|
614
527
|
if (this.hasAttribute("interpolate-frequencies")) {
|
|
615
528
|
return this.getAttribute("interpolate-frequencies") !== "false";
|
|
@@ -651,6 +564,8 @@ export class EFMedia extends EFTargetable(
|
|
|
651
564
|
this.currentSourceTimeMs,
|
|
652
565
|
this.fftSize,
|
|
653
566
|
this.fftDecay,
|
|
567
|
+
this.fftGain,
|
|
568
|
+
this.shouldInterpolateFrequencies,
|
|
654
569
|
] as const,
|
|
655
570
|
task: async () => {
|
|
656
571
|
await this.audioBufferTask.taskComplete;
|
|
@@ -661,7 +576,7 @@ export class EFMedia extends EFTargetable(
|
|
|
661
576
|
const startOffsetMs = this.audioBufferTask.value.startOffsetMs;
|
|
662
577
|
const audioBuffer = this.audioBufferTask.value.buffer;
|
|
663
578
|
|
|
664
|
-
const smoothedKey = `${this.fftSize}:${this.fftDecay}:${startOffsetMs}:${currentTimeMs}`;
|
|
579
|
+
const smoothedKey = `${this.shouldInterpolateFrequencies}:${this.fftSize}:${this.fftDecay}:${this.fftGain}:${startOffsetMs}:${currentTimeMs}`;
|
|
665
580
|
const cachedData = this.#byteTimeDomainCache.get(smoothedKey);
|
|
666
581
|
if (cachedData) return cachedData;
|
|
667
582
|
|
|
@@ -674,7 +589,7 @@ export class EFMedia extends EFTargetable(
|
|
|
674
589
|
(currentTimeMs - frameOffset - startOffsetMs) / 1000,
|
|
675
590
|
);
|
|
676
591
|
|
|
677
|
-
const cacheKey = `${this.fftSize}:${startOffsetMs}:${startTime}`;
|
|
592
|
+
const cacheKey = `${this.shouldInterpolateFrequencies}:${this.fftSize}:${this.fftGain}:${startOffsetMs}:${startTime}`;
|
|
678
593
|
const cachedFrame = this.#byteTimeDomainCache.get(cacheKey);
|
|
679
594
|
if (cachedFrame) return cachedFrame;
|
|
680
595
|
|
|
@@ -694,7 +609,7 @@ export class EFMedia extends EFTargetable(
|
|
|
694
609
|
analyser.maxDecibels = -20;
|
|
695
610
|
|
|
696
611
|
const gainNode = audioContext.createGain();
|
|
697
|
-
gainNode.gain.value =
|
|
612
|
+
gainNode.gain.value = this.fftGain; // Amplify the signal
|
|
698
613
|
|
|
699
614
|
source.connect(gainNode);
|
|
700
615
|
gainNode.connect(analyser);
|
|
@@ -773,8 +688,10 @@ export class EFMedia extends EFTargetable(
|
|
|
773
688
|
[
|
|
774
689
|
this.audioBufferTask.status,
|
|
775
690
|
this.currentSourceTimeMs,
|
|
776
|
-
this.fftSize,
|
|
777
|
-
this.fftDecay,
|
|
691
|
+
this.fftSize,
|
|
692
|
+
this.fftDecay,
|
|
693
|
+
this.fftGain,
|
|
694
|
+
this.shouldInterpolateFrequencies,
|
|
778
695
|
] as const,
|
|
779
696
|
task: async () => {
|
|
780
697
|
await this.audioBufferTask.taskComplete;
|
|
@@ -784,7 +701,7 @@ export class EFMedia extends EFTargetable(
|
|
|
784
701
|
const currentTimeMs = this.currentSourceTimeMs;
|
|
785
702
|
const startOffsetMs = this.audioBufferTask.value.startOffsetMs;
|
|
786
703
|
const audioBuffer = this.audioBufferTask.value.buffer;
|
|
787
|
-
const smoothedKey = `${this.fftSize}:${this.fftDecay}:${startOffsetMs}:${currentTimeMs}`;
|
|
704
|
+
const smoothedKey = `${this.shouldInterpolateFrequencies}:${this.fftSize}:${this.fftDecay}:${this.fftGain}:${startOffsetMs}:${currentTimeMs}`;
|
|
788
705
|
|
|
789
706
|
const cachedSmoothedData = this.#frequencyDataCache.get(smoothedKey);
|
|
790
707
|
if (cachedSmoothedData) {
|
|
@@ -800,7 +717,7 @@ export class EFMedia extends EFTargetable(
|
|
|
800
717
|
);
|
|
801
718
|
|
|
802
719
|
// Cache key for this specific frame
|
|
803
|
-
const cacheKey = `${this.fftSize}:${startOffsetMs}:${startTime}`;
|
|
720
|
+
const cacheKey = `${this.shouldInterpolateFrequencies}:${this.fftSize}:${this.fftGain}:${startOffsetMs}:${startTime}`;
|
|
804
721
|
|
|
805
722
|
// Check cache for this specific frame
|
|
806
723
|
const cachedFrame = this.#frequencyDataCache.get(cacheKey);
|
|
@@ -819,7 +736,7 @@ export class EFMedia extends EFTargetable(
|
|
|
819
736
|
analyser.maxDecibels = -10;
|
|
820
737
|
|
|
821
738
|
const gainNode = audioContext.createGain();
|
|
822
|
-
gainNode.gain.value =
|
|
739
|
+
gainNode.gain.value = this.fftGain;
|
|
823
740
|
|
|
824
741
|
const filter = audioContext.createBiquadFilter();
|
|
825
742
|
filter.type = "bandpass";
|
|
@@ -889,6 +806,16 @@ export class EFMedia extends EFTargetable(
|
|
|
889
806
|
return processedData;
|
|
890
807
|
},
|
|
891
808
|
});
|
|
809
|
+
|
|
810
|
+
set fftGain(value: number) {
|
|
811
|
+
const oldValue = this.fftGain;
|
|
812
|
+
this.setAttribute("fft-gain", String(value));
|
|
813
|
+
this.requestUpdate("fft-gain", oldValue);
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
get fftGain() {
|
|
817
|
+
return Number.parseFloat(this.getAttribute("fft-gain") ?? "3.0");
|
|
818
|
+
}
|
|
892
819
|
}
|
|
893
820
|
|
|
894
821
|
function processFFTData(fftData: Uint8Array, zeroThresholdPercent = 0.1) {
|
|
@@ -921,6 +848,17 @@ function processFFTData(fftData: Uint8Array, zeroThresholdPercent = 0.1) {
|
|
|
921
848
|
const goodData = fftData.slice(0, cutoffIndex);
|
|
922
849
|
const resampledData = interpolateData(goodData, fftData.length);
|
|
923
850
|
|
|
851
|
+
// Step 4: Attenuate the top 10% of interpolated samples
|
|
852
|
+
const attenuationStartIndex = Math.floor(totalBins * 0.9);
|
|
853
|
+
for (let i = attenuationStartIndex; i < totalBins; i++) {
|
|
854
|
+
// Calculate attenuation factor that goes from 1 to 0 over the top 10%
|
|
855
|
+
const attenuationProgress =
|
|
856
|
+
(i - attenuationStartIndex) / (totalBins - attenuationStartIndex) + 0.2;
|
|
857
|
+
const attenuationFactor = Math.max(0, 1 - attenuationProgress);
|
|
858
|
+
// biome-ignore lint/style/noNonNullAssertion: Manual bounds check
|
|
859
|
+
resampledData[i] = Math.floor(resampledData[i]! * attenuationFactor);
|
|
860
|
+
}
|
|
861
|
+
|
|
924
862
|
return resampledData;
|
|
925
863
|
}
|
|
926
864
|
|
|
@@ -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
|
});
|