fix: prevent 404s due to relative image paths of VideoScrolls

develop
Tomáš Mládek 2022-08-17 22:42:00 +02:00
parent a3311a67fb
commit 1a93571eb4
1 changed files with 76 additions and 67 deletions

View File

@ -74,6 +74,17 @@
) as Document; ) as Document;
console.debug("[SVG] Loaded."); console.debug("[SVG] Loaded.");
loadedPercent = 100; loadedPercent = 100;
// Prevent 404s due to relative image paths
const imageElements = Array.from(
svgParsed.getElementsByTagName("image")
).filter((el) =>
Array.from(el.children).some((el) => el.tagName == "desc")
);
imageElements.forEach((el) => {
el.remove();
});
const svg = root.appendChild(svgParsed.firstElementChild as Element) as any; const svg = root.appendChild(svgParsed.firstElementChild as Element) as any;
// Set document background // Set document background
@ -238,7 +249,7 @@
// Videoscrolls // Videoscrolls
console.debug("[SVG] Processing video scrolls."); console.debug("[SVG] Processing video scrolls.");
scrolls = await processScrolls(svg); scrolls = await processScrolls(svg, imageElements);
console.info(`[SVG] Found ${scrolls.length} video scrolls.`); console.info(`[SVG] Found ${scrolls.length} video scrolls.`);
// Debug Stats // Debug Stats
@ -363,7 +374,7 @@
requestAnimationFrame(animate); requestAnimationFrame(animate);
}); });
function processAnchors(document: XMLDocument): SVGRectElement[] { function processAnchors(document: SVGElement): SVGRectElement[] {
const result: SVGRectElement[] = []; const result: SVGRectElement[] = [];
Array.from(document.getElementsByTagName("rect")) Array.from(document.getElementsByTagName("rect"))
.filter((el) => el.id.startsWith("anchor")) .filter((el) => el.id.startsWith("anchor"))
@ -375,81 +386,79 @@
return result; return result;
} }
async function processScrolls(svg: XMLDocument): Promise<VideoScrollDef[]> { async function processScrolls(
const ratio = (svg as any).clientWidth / (svg as any).viewBox.baseVal.width; svg: SVGElement,
images: SVGImageElement[]
): Promise<VideoScrollDef[]> {
const ratio = svg.clientWidth / (svg as any).viewBox.baseVal.width;
return Promise.all( return Promise.all(
Array.from(svg.getElementsByTagName("image")) images.map(async (el) => {
.filter((el) => const descNode = Array.from(el.children).find(
Array.from(el.children).some((el) => el.tagName == "desc") (el) => el.tagName == "desc"
) );
.map(async (el) => { console.debug(
const descNode = Array.from(el.children).find( `[SVG/VIDEOSCROLLS] Found video scroll #${el.id}: ${descNode?.textContent}`
(el) => el.tagName == "desc" );
); const [directionString, filesURL] = descNode!.textContent!.split("\n");
console.debug(
`[SVG/VIDEOSCROLLS] Found video scroll #${el.id}: ${descNode?.textContent}`
);
const [directionString, filesURL] =
descNode!.textContent!.split("\n");
const directions: VideoScrollDirection[] = directionString const directions: VideoScrollDirection[] = directionString
.split(" ") .split(" ")
.map((direction) => { .map((direction) => {
if ( if (
!Object.values(VideoScrollDirection).includes( !Object.values(VideoScrollDirection).includes(
direction as VideoScrollDirection direction as VideoScrollDirection
) )
) { ) {
console.error( console.error(
`Unknown direction definition: "${direction}" (in #${el.id})` `Unknown direction definition: "${direction}" (in #${el.id})`
); );
return false; return false;
} }
return direction as VideoScrollDirection; return direction as VideoScrollDirection;
}) })
.filter((d) => Boolean(d)) as VideoScrollDirection[]; .filter((d) => Boolean(d)) as VideoScrollDirection[];
console.debug(`[SVG/VIDEOSCROLLS] Fetching ${filesURL}...`); console.debug(`[SVG/VIDEOSCROLLS] Fetching ${filesURL}...`);
const fileFetch = await fetch(`content/${filesURL}`); const fileFetch = await fetch(`content/${filesURL}`);
const preURL = fileFetch.url.replace(/\/files.lst$/, ""); const preURL = fileFetch.url.replace(/\/files.lst$/, "");
const files = (await fileFetch.text()) const files = (await fileFetch.text())
.split("\n") .split("\n")
.filter(Boolean) .filter(Boolean)
.map((str) => `${preURL}/${str}`); .map((str) => `${preURL}/${str}`);
let x = el.x.baseVal.value; let x = el.x.baseVal.value;
let y = el.y.baseVal.value; let y = el.y.baseVal.value;
let w = el.width.baseVal.value; let w = el.width.baseVal.value;
let h = el.height.baseVal.value; let h = el.height.baseVal.value;
let angle = 0; let angle = 0;
const transform = el.attributes.getNamedItem("transform"); const transform = el.attributes.getNamedItem("transform");
const rotateResult = /rotate\((-?[0-9.]+)\)/.exec( const rotateResult = /rotate\((-?[0-9.]+)\)/.exec(
transform?.value || "" transform?.value || ""
); );
if (rotateResult) { if (rotateResult) {
angle = parseFloat(rotateResult[1]); angle = parseFloat(rotateResult[1]);
const [ncx, ncy] = rotate(x + w / 2, y + h / 2, 0, 0, angle); const [ncx, ncy] = rotate(x + w / 2, y + h / 2, 0, 0, angle);
x = ncx - w / 2; x = ncx - w / 2;
y = ncy - h / 2; y = ncy - h / 2;
} }
return { return {
id: el.id, id: el.id,
top: y * ratio, top: y * ratio,
left: x * ratio, left: x * ratio,
angle, angle,
width: w * ratio, width: w * ratio,
height: h * ratio, height: h * ratio,
directions, directions,
files, files,
}; };
}) })
); );
} }
function processAudio(svg: XMLDocument): AudioAreaDef[] { function processAudio(svg: SVGElement): AudioAreaDef[] {
const circles: (SVGCircleElement | SVGEllipseElement)[] = Array.from( const circles: (SVGCircleElement | SVGEllipseElement)[] = Array.from(
svg.getElementsByTagName("circle") svg.getElementsByTagName("circle")
); );