perf(CustomGameModal): optimize difficulty map rendering with caching

This commit is contained in:
2026-02-11 04:50:13 +01:00
parent 43822d03ac
commit a264ac75e3

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,8 +26,11 @@ 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) {
ctx.putImageData(cachedBackground.value, 0, 0);
} else {
// Draw Gradient Background (Heavy calculation)
const imgData = ctx.createImageData(width, height); const imgData = ctx.createImageData(width, height);
const data = imgData.data; const data = imgData.data;
@@ -36,10 +40,6 @@ const drawMap = () => {
for (let y = 0; y < height; y++) { for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) { 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; const normalizedX = x / width;
const normalizedY = 1 - (y / height); // 0 at bottom, 1 at top const normalizedY = 1 - (y / height); // 0 at bottom, 1 at top
@@ -48,13 +48,8 @@ const drawMap = () => {
const { value } = calculateDifficulty(fRate, sSize); const { value } = calculateDifficulty(fRate, sSize);
// Color Mapping: // Color Mapping
// Green (0%) -> Yellow (50%) -> Red (100%)
// Hue: 120 -> 0
const hue = 120 * (1 - value / 100); const hue = 120 * (1 - value / 100);
// Convert HSL to RGB (Simplified)
// Saturation 100%, Lightness 50%
const [r, g, b] = hslToRgb(hue / 360, 1, 0.5); const [r, g, b] = hslToRgb(hue / 360, 1, 0.5);
const index = (y * width + x) * 4; const index = (y * width + x) * 4;
@@ -65,6 +60,8 @@ const drawMap = () => {
} }
} }
ctx.putImageData(imgData, 0, 0); ctx.putImageData(imgData, 0, 0);
cachedBackground.value = imgData;
}
// 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);
} }
}; };