From 5ff583dbd4d316e0011c48b79cb15f4c5c113a25 Mon Sep 17 00:00:00 2001 From: weizhenye Date: Mon, 24 Jun 2024 23:47:15 +0800 Subject: [PATCH] fix: avoid .ASS-fix-font-size overflow and some refactors --- src/global.css | 6 ++++++ src/index.js | 5 +++++ src/internal.js | 7 +------ src/renderer/animation.js | 4 ++-- src/renderer/clip.js | 4 ++-- src/renderer/dom.js | 3 +-- src/renderer/font-size.js | 6 ++++-- src/renderer/renderer.js | 4 ++-- src/utils.js | 13 ------------- 9 files changed, 23 insertions(+), 29 deletions(-) diff --git a/src/global.css b/src/global.css index 5e8fe05..2f47c2b 100644 --- a/src/global.css +++ b/src/global.css @@ -36,8 +36,14 @@ .ASS-fix-font-size { font-size: 2048px; line-height: normal; + width: 0; + height: 0; position: absolute; visibility: hidden; + overflow: hidden; +} +.ASS-fix-font-size span { + position: absolute; } .ASS-fix-objectBoundingBox { width: 100%; diff --git a/src/index.js b/src/index.js index d457e85..cc1d700 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,6 @@ /* eslint-disable max-len */ import { compile } from 'ass-compiler'; +import { setKeyframes } from './renderer/animation.js'; import { $fixFontSize } from './renderer/font-size.js'; import { clear, createResize, createPlay, createPause, createSeek } from './internal.js'; import { createSVGEl, addGlobalStyle } from './utils.js'; @@ -144,6 +145,10 @@ export default class ASS { this.#resize(); this.resampling = resampling; + dialogues.forEach((dialogue) => { + setKeyframes(dialogue, styles); + }); + const observer = new ResizeObserver(this.#resize); observer.observe(video); this.#store.observer = observer; diff --git a/src/internal.js b/src/internal.js index f963b27..21c5be2 100644 --- a/src/internal.js +++ b/src/internal.js @@ -1,6 +1,5 @@ /* eslint-disable no-param-reassign */ import { renderer } from './renderer/renderer.js'; -import { setKeyframes } from './renderer/animation.js'; import { batchAnimate } from './utils.js'; export function clear(store) { @@ -93,7 +92,7 @@ export function createPause(store) { } export function createResize(that, store) { - const { video, box, svg, dialogues } = store; + const { video, box, svg } = store; return function resize() { const cw = video.clientWidth; const ch = video.clientHeight; @@ -134,10 +133,6 @@ export function createResize(that, store) { svg.style.cssText = cssText; svg.setAttributeNS(null, 'viewBox', `0 0 ${sw} ${sh}`); - dialogues.forEach((dialogue) => { - setKeyframes(dialogue, store); - }); - createSeek(store)(); }; } diff --git a/src/renderer/animation.js b/src/renderer/animation.js index 0db3d8a..cfa0f5e 100644 --- a/src/renderer/animation.js +++ b/src/renderer/animation.js @@ -99,7 +99,7 @@ function createTransformKeyframes({ fromTag, tag, fragment }) { } // TODO: accel is not implemented yet, maybe it can be simulated by cubic-bezier? -export function setKeyframes(dialogue, store) { +export function setKeyframes(dialogue, styles) { const { start, end, effect, move, fade, slices } = dialogue; const duration = (end - start) * 1000; const keyframes = [ @@ -111,7 +111,7 @@ export function setKeyframes(dialogue, store) { Object.assign(dialogue, { keyframes }); } slices.forEach((slice) => { - const sliceTag = store.styles[slice.style].tag; + const sliceTag = styles[slice.style].tag; slice.fragments.forEach((fragment) => { if (!fragment.tag.t || fragment.tag.t.length === 0) { return; diff --git a/src/renderer/clip.js b/src/renderer/clip.js index a0dfef1..02da996 100644 --- a/src/renderer/clip.js +++ b/src/renderer/clip.js @@ -1,4 +1,4 @@ -import { createSVGEl, uuid, vendor } from '../utils.js'; +import { createSVGEl, uuid } from '../utils.js'; export function createClipPath(clip, store) { const sw = store.scriptRes.width; @@ -34,7 +34,7 @@ export function createClipPath(clip, store) { store.defs.append($clipPath); return { $clipPath, - cssText: `${vendor.clipPath}clip-path:url(#${id});`, + cssText: `clip-path:url(#${id});`, }; } diff --git a/src/renderer/dom.js b/src/renderer/dom.js index 433ebcf..30313cb 100644 --- a/src/renderer/dom.js +++ b/src/renderer/dom.js @@ -125,7 +125,6 @@ export function createDialogue(dialogue, store) { if (dialogue.keyframes) { animations.push(initAnimation($div, dialogue.keyframes, animationOptions)); } - dialogue.animations = animations; $div.append(df); - return $div; + return { $div, animations }; } diff --git a/src/renderer/font-size.js b/src/renderer/font-size.js index 4346e9c..81cdcb7 100644 --- a/src/renderer/font-size.js +++ b/src/renderer/font-size.js @@ -2,14 +2,16 @@ export const $fixFontSize = document.createElement('div'); $fixFontSize.className = 'ASS-fix-font-size'; -$fixFontSize.textContent = '0'; +const $span = document.createElement('span'); +$span.textContent = '0'; +$fixFontSize.append($span); const cache = Object.create(null); export function getRealFontSize(fn, fs) { if (!cache[fn]) { $fixFontSize.style.fontFamily = `font-family:"${fn}",Arial;`; - cache[fn] = fs * 2048 / $fixFontSize.clientHeight; + cache[fn] = fs * 2048 / $span.clientHeight; } return cache[fn]; } diff --git a/src/renderer/renderer.js b/src/renderer/renderer.js index af407ae..636dc94 100644 --- a/src/renderer/renderer.js +++ b/src/renderer/renderer.js @@ -6,8 +6,8 @@ import { setTransformOrigin } from './transform.js'; import { getScrollEffect } from './scroll.js'; export function renderer(dialogue, store) { - const $div = createDialogue(dialogue, store); - Object.assign(dialogue, { $div }); + const { $div, animations } = createDialogue(dialogue, store); + Object.assign(dialogue, { $div, animations }); store.box.append($div); const { width } = $div.getBoundingClientRect(); Object.assign(dialogue, { width }); diff --git a/src/utils.js b/src/utils.js index 62af08f..872ed76 100644 --- a/src/utils.js +++ b/src/utils.js @@ -37,19 +37,6 @@ export function createSVGEl(name, attrs = []) { return $el; } -function getVendor(prop) { - const { style } = document.body; - const Prop = prop.replace(/^\w/, (x) => x.toUpperCase()); - if (prop in style) return ''; - if (`webkit${Prop}` in style) return '-webkit-'; - if (`moz${Prop}` in style) return '-moz-'; - return ''; -} - -export const vendor = { - clipPath: getVendor('clipPath'), -}; - const GLOBAL_CSS = '__GLOBAL_CSS__'; /** * @param {HTMLElement} container