2 Commits

Author SHA1 Message Date
460de9fac9 1.8.3 2026-02-11 04:50:21 +01:00
a264ac75e3 perf(CustomGameModal): optimize difficulty map rendering with caching 2026-02-11 04:50:13 +01:00
3 changed files with 39 additions and 40 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "vue-nonograms-solid", "name": "vue-nonograms-solid",
"version": "1.8.2", "version": "1.8.3",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "vue-nonograms-solid", "name": "vue-nonograms-solid",
"version": "1.8.2", "version": "1.8.3",
"dependencies": { "dependencies": {
"fireworks-js": "^2.10.8", "fireworks-js": "^2.10.8",
"flag-icons": "^7.5.0", "flag-icons": "^7.5.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "vue-nonograms-solid", "name": "vue-nonograms-solid",
"version": "1.8.2", "version": "1.8.3",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -14,6 +14,7 @@ const fillRate = ref(50);
const errorMsg = ref(''); const errorMsg = ref('');
const difficultyCanvas = ref(null); const difficultyCanvas = ref(null);
const isDragging = ref(false); const isDragging = ref(false);
const cachedBackground = ref(null);
const drawMap = () => { const drawMap = () => {
const canvas = difficultyCanvas.value; const canvas = difficultyCanvas.value;
@@ -25,46 +26,42 @@ const drawMap = () => {
// Clear // Clear
ctx.clearRect(0, 0, width, height); ctx.clearRect(0, 0, width, height);
// Draw Gradient Background // Use cached background if available
// Optimization: Create an image data once if static, but here it's small enough. if (cachedBackground.value) {
const imgData = ctx.createImageData(width, height); ctx.putImageData(cachedBackground.value, 0, 0);
const data = imgData.data; } else {
// Draw Gradient Background (Heavy calculation)
const imgData = ctx.createImageData(width, height);
const data = imgData.data;
// Ranges: // Ranges:
// X: Fill Rate 10% -> 90% // X: Fill Rate 10% -> 90%
// Y: Size 5 -> 80 // Y: Size 5 -> 80
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
// Map x, y to fillRate, size
// y=0 -> size 80 (top), y=height -> size 5 (bottom)
// x=0 -> fill 10%, x=width -> fill 90%
const normalizedX = x / width; for (let y = 0; y < height; y++) {
const normalizedY = 1 - (y / height); // 0 at bottom, 1 at top for (let x = 0; x < width; x++) {
const normalizedX = x / width;
const fRate = 0.1 + normalizedX * 0.8; // 0.1 to 0.9 const normalizedY = 1 - (y / height); // 0 at bottom, 1 at top
const sSize = 5 + normalizedY * 75; // 5 to 80
const fRate = 0.1 + normalizedX * 0.8; // 0.1 to 0.9
const { value } = calculateDifficulty(fRate, sSize); const sSize = 5 + normalizedY * 75; // 5 to 80
// Color Mapping: const { value } = calculateDifficulty(fRate, sSize);
// Green (0%) -> Yellow (50%) -> Red (100%)
// Hue: 120 -> 0 // Color Mapping
const hue = 120 * (1 - value / 100); const hue = 120 * (1 - value / 100);
const [r, g, b] = hslToRgb(hue / 360, 1, 0.5);
// Convert HSL to RGB (Simplified)
// Saturation 100%, Lightness 50% const index = (y * width + x) * 4;
const [r, g, b] = hslToRgb(hue / 360, 1, 0.5); data[index] = r;
data[index + 1] = g;
const index = (y * width + x) * 4; data[index + 2] = b;
data[index] = r; data[index + 3] = 255; // Alpha
data[index + 1] = g; }
data[index + 2] = b; }
data[index + 3] = 255; // Alpha ctx.putImageData(imgData, 0, 0);
} cachedBackground.value = imgData;
} }
ctx.putImageData(imgData, 0, 0);
// Draw current position // Draw current position
// Map current fillRate/size to x,y // Map current fillRate/size to x,y
@@ -166,6 +163,8 @@ const showAdvanced = ref(false);
const toggleAdvanced = () => { const toggleAdvanced = () => {
showAdvanced.value = !showAdvanced.value; showAdvanced.value = !showAdvanced.value;
if (showAdvanced.value) { if (showAdvanced.value) {
// Reset cache when opening to ensure size is correct if canvas resized
cachedBackground.value = null;
nextTick(drawMap); nextTick(drawMap);
} }
}; };