"use strict"; const ImageBackground = (function(){ const ImageBackground = function(xgravity){ const self = this; let image = null, is_loaded = false, offset_x = 0, offset_y = 0; const constructor = () => { if(xgravity.values.bg_image_url){ image = new Image(); image.onload = () => { is_loaded = true; }; image.onerror = event => { console.error("[XGravity] Error al cargar bg_image_url:", xgravity.values.bg_image_url, event); }; image.src = xgravity.values.bg_image_url; if(image.complete && image.naturalWidth > 0) is_loaded = true; }; }; this.resize = (width, height) => {}; this.render = (context, width, height, delta_time) => { if(!is_loaded || !image || !image.naturalWidth){ context.fillStyle = "#020408"; context.fillRect(0, 0, width, height); return; }; // Relación de aspecto cover const canvas_ratio = width / height, image_ratio = image.naturalWidth / image.naturalHeight; let draw_width, draw_height; if(canvas_ratio > image_ratio){ draw_width = width; draw_height = width / image_ratio; }else{ draw_height = height; draw_width = height * image_ratio; }; // Si es completamente estática (como en el juego original) if(xgravity.values.bg_image_pan_x === 0 && xgravity.values.bg_image_pan_y === 0){ context.drawImage(image, (width - draw_width) / 2, (height - draw_height) / 2, draw_width, draw_height); return; }; // Si tiene movimiento const start_x = ((width - draw_width) / 2) + (offset_x = (offset_x + xgravity.values.bg_image_pan_x * delta_time) % draw_width), start_y = ((height - draw_height) / 2) + (offset_y = (offset_y + xgravity.values.bg_image_pan_y * delta_time) % draw_height); // Dibujar la cuadrícula de repetición necesaria para cubrir cualquier espacio for(let x = start_x - draw_width; x < width; x += draw_width) for(let y = start_y - draw_height; y < height; y += draw_height) context.drawImage(image, x, y, draw_width, draw_height); }; constructor(); }; return ImageBackground; })();