/** * Image Optimizer Web Component * Automatically optimizes image loading with lazy loading, placeholders, and responsive images */ class ImageOptimizer extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); } connectedCallback() { const src = this.getAttribute('src') || ''; const alt = this.getAttribute('alt') || ''; const width = this.getAttribute('width') || '100%'; const height = this.getAttribute('height') || 'auto'; const lazy = this.hasAttribute('lazy'); const placeholder = this.getAttribute('placeholder') || 'https://static.photos/abstract/100x100'; const category = this.getAttribute('category') || 'general'; // Generate optimized image URL based on static.photos API const optimizeURL = (url) => { // If it's already a static.photos URL, keep it if (url.includes('static.photos')) return url; // For other URLs, we could add resize parameters if needed // For now, just return the original return url; }; // Create responsive image sets for different screen sizes const generateSrcSet = (baseUrl) => { if (!baseUrl.includes('static.photos')) return ''; // Extract dimensions if present const dimMatch = baseUrl.match(/\/(\d+)x(\d+)\//); if (!dimMatch) return ''; const [_, width, height] = dimMatch; const base = baseUrl.replace(`/${width}x${height}/`, ''); // Generate srcset for common breakpoints const sizes = [ { width: 320, height: Math.round(320 * height / width) }, { width: 640, height: Math.round(640 * height / width) }, { width: 768, height: Math.round(768 * height / width) }, { width: 1024, height: Math.round(1024 * height / width) }, { width: 1280, height: Math.round(1280 * height / width) } ]; return sizes.map(size => `${base.replace(/\/\d+x\d+\//, `/${size.width}x${size.height}/`)} ${size.width}w` ).join(', '); }; const optimizedSrc = optimizeURL(src); const srcset = generateSrcSet(optimizedSrc); this.shadowRoot.innerHTML = `
${alt}
`; } static get observedAttributes() { return ['src', 'alt', 'width', 'height']; } attributeChangedCallback(name, oldValue, newValue) { if (oldValue !== newValue) { this.connectedCallback(); } } } customElements.define('optimized-image', ImageOptimizer);