🌐 URLs de Variantes
Las variantes se generan dinámicamente usando parámetros URL:
https://limbo.lefebvre.es/assets/{assetId}/transform?w=800&h=600&f=webp&q=85
Ejemplos de Transformaciones
1920×1080
Original
Sin transformaciones
?w=800&h=600
Redimensionado a 800×600
?w=400&h=400&c=fill
Cuadrado con recorte
?blur=10&w=400
Con efecto blur
⚙️ Parámetros de Transformación
Lista completa de parámetros disponibles para personalizar tus imágenes:
📏 Parámetros de Tamaño
w
w=800
h
h=600
dpr
dpr=2
ar
ar=16:9
# Ancho fijo, alto proporcional
?w=800
# Dimensiones específicas
?w=800&h=600
# Para pantallas Retina
?w=400&h=300&dpr=2
# Aspect ratio específico
?w=800&ar=16:9
✂️ Parámetros de Recorte
c
c=fill
g
g=center
x
x=100
y
y=50
Modos de Recorte
scale
Escala sin recortar, puede distorsionar
fit
Encaja completo, puede haber barras
fill
Llena completamente, recorta si es necesario
crop
Recorte manual con coordenadas
🖼️ Parámetros de Formato
f
f=webp
q
q=85
auto
auto=format
Formatos Soportados
webp
Moderno
Excelente compresión, soporte amplio
avif
Avanzado
Mejor compresión, soporte limitado
jpeg
Universal
Compatibilidad total
png
Universal
Soporte para transparencia
# Formato automático basado en soporte del navegador
?auto=format&w=800
# Calidad automática basada en contenido
?auto=quality&w=800
# Ambos: formato y calidad automáticos
?auto=format,quality&w=800
✨ Parámetros de Efectos
blur
blur=10
sharpen
sharpen=50
brightness
brightness=20
contrast
contrast=15
saturation
saturation=-30
grayscale
grayscale=true
# Imagen en blanco y negro
?w=800&grayscale=true
# Efecto vintage
?w=800&brightness=-10&contrast=20&saturation=-40
# Imagen para placeholder
?w=400&h=300&blur=50&brightness=-50
# Thumbnail con enfoque
?w=200&h=200&c=fill&sharpen=30
📱 Implementación Responsiva
Ejemplos prácticos para implementar imágenes responsivas y optimizadas:
<!-- Picture element con formato automático -->
<picture>
<source
media="(min-width: 1200px)"
srcset="https://limbo.lefebvre.es/assets/{id}/transform?w=1200&auto=format&dpr=1 1x,
https://limbo.lefebvre.es/assets/{id}/transform?w=1200&auto=format&dpr=2 2x"
>
<source
media="(min-width: 768px)"
srcset="https://limbo.lefebvre.es/assets/{id}/transform?w=800&auto=format&dpr=1 1x,
https://limbo.lefebvre.es/assets/{id}/transform?w=800&auto=format&dpr=2 2x"
>
<img
src="https://limbo.lefebvre.es/assets/{id}/transform?w=400&auto=format"
srcset="https://limbo.lefebvre.es/assets/{id}/transform?w=400&auto=format&dpr=1 1x,
https://limbo.lefebvre.es/assets/{id}/transform?w=400&auto=format&dpr=2 2x"
alt="Descripción de la imagen"
loading="lazy"
>
</picture>
<!-- Hero image con múltiples breakpoints -->
<div class="hero">
<picture>
<source
media="(min-width: 1400px)"
srcset="https://limbo.lefebvre.es/assets/{id}/transform?w=1400&h=600&c=fill&g=center&f=webp"
>
<source
media="(min-width: 1024px)"
srcset="https://limbo.lefebvre.es/assets/{id}/transform?w=1200&h=500&c=fill&g=center&f=webp"
>
<source
media="(min-width: 768px)"
srcset="https://limbo.lefebvre.es/assets/{id}/transform?w=800&h=400&c=fill&g=center&f=webp"
>
<img
src="https://limbo.lefebvre.es/assets/{id}/transform?w=600&h=300&c=fill&g=center&f=jpeg"
alt="Hero image"
class="hero-image">
</picture>
</div>
<!-- Grid de productos -->
<div class="product-grid">
<article class="product-card">
<img
src="https://limbo.lefebvre.es/assets/{id}/transform?w=300&h=300&c=fill&auto=format&q=85"
srcset="https://limbo.lefebvre.es/assets/{id}/transform?w=300&h=300&c=fill&auto=format&q=85&dpr=1 1x,
https://limbo.lefebvre.es/assets/{id}/transform?w=300&h=300&c=fill&auto=format&q=85&dpr=2 2x"
alt="Producto"
loading="lazy"
class="product-image">
</article>
</div>
/* Background images responsivos */
.hero {
min-height: 60vh;
background-image: url('https://limbo.lefebvre.es/assets/{id}/transform?w=600&h=300&c=fill&f=webp');
background-size: cover;
background-position: center;
}
@media (min-width: 768px) {
.hero {
background-image: url('https://limbo.lefebvre.es/assets/{id}/transform?w=1200&h=500&c=fill&f=webp');
}
}
@media (min-width: 1200px) {
.hero {
background-image: url('https://limbo.lefebvre.es/assets/{id}/transform?w=1600&h=600&c=fill&f=webp');
}
}
/* Grid de imágenes adaptativo */
.image-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
.image-grid img {
width: 100%;
height: 200px;
object-fit: cover;
border-radius: 8px;
}
/* Placeholder con blur */
.image-placeholder {
background-image: url('https://limbo.lefebvre.es/assets/{id}/transform?w=50&h=50&blur=20&q=20');
background-size: cover;
filter: blur(5px);
transition: filter 0.3s ease;
}
.image-placeholder.loaded {
filter: none;
}
/* Aspectos ratio fijos */
.aspect-16-9 {
aspect-ratio: 16 / 9;
}
.aspect-4-3 {
aspect-ratio: 4 / 3;
}
.aspect-1-1 {
aspect-ratio: 1 / 1;
}
class ResponsiveImageManager {
constructor(baseUrl = 'https://limbo.lefebvre.es') {
this.baseUrl = baseUrl;
this.breakpoints = {
mobile: 480,
tablet: 768,
desktop: 1024,
wide: 1400
};
}
generateVariantUrl(assetId, options = {}) {
const params = new URLSearchParams();
Object.entries(options).forEach(([key, value]) => {
if (value !== undefined && value !== null) {
params.append(key, value);
}
});
return `${this.baseUrl}/assets/${assetId}/transform?${params.toString()}`;
}
createResponsiveSrcSet(assetId, widths, options = {}) {
return widths.map(width => {
const variantOptions = { ...options, w: width };
const url = this.generateVariantUrl(assetId, variantOptions);
return `${url} ${width}w`;
}).join(', ');
}
createRetinaSrcSet(assetId, width, options = {}) {
const normalUrl = this.generateVariantUrl(assetId, { ...options, w: width });
const retinaUrl = this.generateVariantUrl(assetId, { ...options, w: width, dpr: 2 });
return `${normalUrl} 1x, ${retinaUrl} 2x`;
}
optimizeImagesOnLoad() {
// Detectar soporte de formatos modernos
const supportsWebP = this.checkWebPSupport();
const supportsAVIF = this.checkAVIFSupport();
document.querySelectorAll('[data-limbo-asset]').forEach(img => {
const assetId = img.dataset.limboAsset;
const width = img.dataset.width || 800;
const height = img.dataset.height;
const crop = img.dataset.crop || 'fit';
const options = {
w: width,
auto: 'format,quality',
c: crop
};
if (height) options.h = height;
// Aplicar formato óptimo
if (supportsAVIF) {
options.f = 'avif';
} else if (supportsWebP) {
options.f = 'webp';
}
img.src = this.generateVariantUrl(assetId, options);
// Configurar srcset para diferentes densidades
img.srcset = this.createRetinaSrcSet(assetId, width, options);
});
}
checkWebPSupport() {
return new Promise(resolve => {
const webP = new Image();
webP.onload = webP.onerror = () => resolve(webP.height === 2);
webP.src = 'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
});
}
checkAVIFSupport() {
return new Promise(resolve => {
const avif = new Image();
avif.onload = avif.onerror = () => resolve(avif.height === 2);
avif.src = 'data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgABogQEAwgMg8f8D///8WfhwB8+ErK42A=';
});
}
lazyLoadImages() {
if ('IntersectionObserver' in window) {
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
const assetId = img.dataset.limboAsset;
if (assetId && !img.src) {
this.loadImage(img, assetId);
}
observer.unobserve(img);
}
});
});
document.querySelectorAll('[data-limbo-asset]:not([src])').forEach(img => {
imageObserver.observe(img);
});
}
}
loadImage(img, assetId) {
const width = img.dataset.width || img.offsetWidth || 400;
const height = img.dataset.height;
const crop = img.dataset.crop || 'fit';
const options = {
w: width,
auto: 'format,quality',
c: crop
};
if (height) options.h = height;
// Mostrar placeholder blur mientras carga
const placeholderUrl = this.generateVariantUrl(assetId, {
w: 50,
h: 50,
blur: 20,
q: 20
});
img.style.backgroundImage = `url(${placeholderUrl})`;
img.style.backgroundSize = 'cover';
// Cargar imagen principal
const fullImg = new Image();
fullImg.onload = () => {
img.src = fullImg.src;
img.srcset = this.createRetinaSrcSet(assetId, width, options);
img.style.backgroundImage = '';
img.classList.add('loaded');
};
fullImg.src = this.generateVariantUrl(assetId, options);
}
}
// Inicializar
const imageManager = new ResponsiveImageManager();
document.addEventListener('DOMContentLoaded', () => {
imageManager.optimizeImagesOnLoad();
imageManager.lazyLoadImages();
});
⚡ Performance y Cache
Las variantes se optimizan automáticamente para máximo rendimiento:
Cache Inteligente
Las variantes se cachean automáticamente con TTL de 1 año. Cache invalidation automático al actualizar assets.
CDN Global
Distribución mundial con edge caching para latencia mínima. Optimización automática de rutas.
Compresión Avanzada
Algoritmos de última generación para máxima compresión sin pérdida de calidad visual.
Métricas en Tiempo Real
Monitoreo de performance, cache hit rate y optimización de bandwidth automática.
Headers de Cache
Cache-Control: public, max-age=31536000, immutable
ETag: "a1b2c3d4e5f6g7h8i9j0"
Last-Modified: Wed, 15 Jan 2024 14:35:18 GMT
Content-Type: image/webp
Vary: Accept, DPR, Width
🎯 Casos de Uso Avanzados
E-commerce
Galerías de productos con zoom, múltiples vistas y optimización automática para conversión máxima.
?w=400&h=400&c=fill&q=90&sharpen=10
Blog/Magazine
Imágenes editoriales adaptativas con múltiples breakpoints y formatos optimizados para lectura.
?w=800&ar=16:9&auto=format,quality
Portfolio
Presentación de trabajos artísticos con máxima calidad y efectos visuales personalizados.
?w=1200&f=jpeg&q=95&sharpen=5
Móvil First
Optimización extrema para conexiones lentas con progressive loading y placeholders inteligentes.
?w=400&f=webp&q=75&auto=format