perf(CustomGameModal): optimize difficulty map rendering with caching
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user