From 75b66e245eb2ebc33cb23884965414e9cf4749c9 Mon Sep 17 00:00:00 2001 From: Joe Date: Fri, 18 Apr 2025 14:35:30 +0100 Subject: [PATCH] this is garbage from chatty mc fuckin chat face --- assets/instruments/instruments.json | 14 ++-- src/render.js | 102 +++++++++++++++++++--------- styles.css | 17 +++-- 3 files changed, 91 insertions(+), 42 deletions(-) diff --git a/assets/instruments/instruments.json b/assets/instruments/instruments.json index 3d3512c..4dfbf0b 100644 --- a/assets/instruments/instruments.json +++ b/assets/instruments/instruments.json @@ -8,7 +8,7 @@ "bdrumnew-hit-v7-rr1-sum-(1).mp3" ], "midi-channel-name": "conductorOrchestralBass", - "image": { "filename": "bass.svg", "yPos": "13%", "width": "15vw", "height": "15vw" } + "image": { "filename": "bass.svg", "yPos": "13%", "width": "100", "height": "100" } }, "Snare": { "directory": "/assets/instruments/snare", @@ -17,19 +17,19 @@ "ropesnare-low-tsn-main-vl4-rr1.mp3" ], "midi-channel-name": "conductorSnare", - "image": { "filename": "snare.svg", "yPos": "26%", "width": "15vw", "height": "15vw" } + "image": { "filename": "snare.svg", "yPos": "26%", "width": "100", "height": "100" } }, "Surdo": { "directory": "/assets/instruments/surdo", "filenames": ["surdo-5.mp3", "surdo-6.mp3", "surdo-7.mp3"], "midi-channel-name":"conductorSnare", - "image": { "filename": "surdo.svg", "yPos": "39%" , "width": "15vw", "height": "15vw"} + "image": { "filename": "surdo.svg", "yPos": "39%" , "width": "100", "height": "100"} }, "Surdo Napa": { "directory": "/assets/instruments/surdo-napa", "filenames": ["surdo-1.mp3", "surdo-3.mp3", "surdo-4.mp3"], "midi-channel-name": "conductorSurdoNapa", - "image": { "filename": "surdo-napa.svg", "yPos": "42%" , "width": "15vw", "height": "15vw" + "image": { "filename": "surdo-napa.svg", "yPos": "42%" , "width": "100", "height": "100" } }, "Timpani Large": { "directory": "/assets/instruments/timpani-large", @@ -40,7 +40,7 @@ "timpani7d-hit-v2-rr1-main.mp3" ], "midi-channel-name":"conductorTimpaniLarge", - "image": { "filename": "timpani-large.svg", "yPos": "55%" , "width": "15vw", "height": "15vw" + "image": { "filename": "timpani-large.svg", "yPos": "55%" , "width": "100", "height": "100" } }, "Timpani Small": { "directory": "/assets/instruments/timpani-small", "filenames": [ @@ -49,7 +49,7 @@ "timpani4-hit-v2-rr1-sum.mp3" ], "midi-channel-name": "conductorTimpaniSmall", - "image": { "filename": "timpani-small.svg", "yPos": "68%" , "width": "15vw", "height": "15vw"} + "image": { "filename": "timpani-small.svg", "yPos": "68%" , "width": "100", "height": "100"} }, "Toms": { "directory": "/assets/instruments/toms", @@ -59,6 +59,6 @@ "toml-rollm-v2-rr1-mid.mp3" ], "midi-channel-name": "conductorToms", - "image": { "filename": "toms.svg", "yPos": "81%" , "width": "15vw", "height": "15vw"} + "image": { "filename": "toms.svg", "yPos": "81%" , "width": "100", "height": "100"} } } diff --git a/src/render.js b/src/render.js index 4c4be3d..06403ab 100644 --- a/src/render.js +++ b/src/render.js @@ -9,8 +9,8 @@ export class Renderer { ctx; canvasWidth; canvasHeight; - iconCache = []; // stores drawn icons - imageCache = new Map(); // for memoizing loaded images + iconCache = []; // stores { image, x, y, width, height } + imageCache = new Map(); // memoized constructor() { this.numStaves = 6; @@ -58,48 +58,78 @@ export class Renderer { this.canvasHeight = this.sheetWindow.offsetHeight; this.eventCanvas.width = this.canvasWidth; this.eventCanvas.height = this.canvasHeight; + console.log("Canvas size:", this.canvasWidth, this.canvasHeight); } async placeIcon(instrument) { if (this.currStaveNumber > this.numStaves) this.currStaveNumber = 1; - const targetWrapper = document.getElementById( - `stave-wrapper-${this.currStaveNumber}` - ); const rect = this.timeIndicator.getBoundingClientRect(); const sheetLeft = this.sheetWindow.getBoundingClientRect().left; const xPosition = rect.left + window.scrollX - sheetLeft; - const newObject = document.createElement("div"); - newObject.classList.add("event-icon"); - newObject.style.position = "absolute"; - newObject.style.left = `${xPosition}px`; - newObject.style.top = instrument.yPos; - newObject.style.width = instrument.width; - newObject.style.height = instrument.height; + const yPercent = parseFloat(instrument.yPos); // e.g., "55%" => 55 + const y = (yPercent / 100) * this.canvasHeight; - // ✅ Detect and decode base64 if needed + // Handle image caching let svgString = instrument.image; if (svgString.startsWith("data:image/svg+xml;base64,")) { const base64 = svgString.split(",")[1]; svgString = atob(base64); } - const parser = new DOMParser(); - const svgDoc = parser.parseFromString(svgString, "image/svg+xml"); - const svgElement = svgDoc.documentElement; + // Ensure SVG has dimensions + svgString = this.ensureSvgHasDimensions( + svgString, + instrument.width || 50, + instrument.height || 50 + ); - // ✅ Handle parsing error - if (svgElement.nodeName === "parsererror") { - console.error("Failed to parse SVG:", svgString); - return; + const img = await this.loadImageFromSVG(svgString); + + // Fallback if instrument.width/height not provided + const naturalWidth = img.naturalWidth || 50; + const naturalHeight = img.naturalHeight || 50; + const scale = 0.25; + const width = parseFloat(instrument.width || naturalWidth) * scale; + const height = parseFloat(instrument.height || naturalHeight) * scale; + + this.ctx.drawImage(img, xPosition, y, width, height); + + // Store for redrawing later + this.iconCache.push({ + image: img, + x: xPosition, + y, + width, + height, + }); + + console.log("Drawing position:", xPosition, y); + console.log("width", width, "height", height); + console.log( + "Canvas size:", + this.eventCanvas.width, + this.eventCanvas.height + ); + console.log( + "Canvas offset size:", + this.eventCanvas.offsetWidth, + this.eventCanvas.offsetHeight + ); + } + ensureSvgHasDimensions(svgString, defaultWidth = 50, defaultHeight = 50) { + const hasWidth = /]*\bwidth=/.test(svgString); + const hasHeight = /]*\bheight=/.test(svgString); + + if (!hasWidth || !hasHeight) { + svgString = svgString.replace( + /]*)>/, + `` + ); } - svgElement.style.width = "100%"; - svgElement.style.height = "100%"; - - newObject.appendChild(svgElement); - targetWrapper.appendChild(newObject); + return svgString; } async loadImageFromSVG(svgString) { @@ -107,15 +137,25 @@ export class Renderer { return this.imageCache.get(svgString); } - return new Promise((resolve) => { + return new Promise((resolve, reject) => { const blob = new Blob([svgString], { type: "image/svg+xml" }); const url = URL.createObjectURL(blob); const img = new Image(); img.onload = () => { - URL.revokeObjectURL(url); // clean up after load - this.imageCache.set(svgString, img); - resolve(img); + console.log("Image loaded:", img.width, img.height); // should no longer be 0 + + const scale = 0.25; + const width = instrument.width * scale || img.width * scale; + const height = instrument.height * scale || img.height * scale; + + ctx.drawImage(img, xPosition, y, width, height); + URL.revokeObjectURL(url); + }; + + img.onerror = (err) => { + console.error("Image failed to load from SVG:", err); + reject(err); }; img.src = url; @@ -124,8 +164,8 @@ export class Renderer { redrawIcons() { this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight); - this.iconCache.forEach(({ image, x, y }) => { - this.ctx.drawImage(image, x, y, 24, 24); // Adjust size as needed + this.iconCache.forEach(({ image, x, y, width, height }) => { + this.ctx.drawImage(image, x, y, width, height); }); } diff --git a/styles.css b/styles.css index 61e7175..d7ea433 100644 --- a/styles.css +++ b/styles.css @@ -75,9 +75,14 @@ html { } #event-canvas { - background-color: rgba(255, 255, 255, 0.02); /* lightly visible canvas for debugging */ + background: rgba(255, 0, 0, 0.2); /* light red overlay */ + position: absolute; + top: 0; + left: 0; + z-index: 1000; } + .logo { color: #fff; width: 20%; @@ -189,6 +194,7 @@ html { border: 1px solid rgb(24,24,24); padding-top: 30px; padding-bottom: 20px; + z-index: 1; } .time-indicator { @@ -198,15 +204,18 @@ html { width: 2px; /* height: 100%; */ animation: moveRight 10s linear infinite; - z-index: 3; + z-index: 999; } - +.stave-svg { + position: relative; + z-index: 1; /* Same here */ + } #event-canvas { position: absolute; top: 0; left: 0; pointer-events: none; - z-index: 2; + z-index: 999; } #time-indicator {