{"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#96ceb4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#ff6b6b', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.03;\n cube.rotation.y += 0.03;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 0} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#4ecdc4');\n scene.fog = new THREE.Fog('#4ecdc4', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 1} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 12, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.05,\n y: (Math.random() - 0.5) * 0.05,\n z: (Math.random() - 0.5) * 0.05\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#6c5ce7', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 2} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#96ceb4');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#45b7d1', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#fab1a0',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.005;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 3} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#45b7d1' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 4} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e17055');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#45b7d1', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#a29bfe' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.1;\n torus.rotation.y += 0.1 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 5} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 6} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #00b894;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 7} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 8} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 9} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 10} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 11} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 12} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 13} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 14} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #e84393; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 15} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 16} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#45b7d1';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 17} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 18} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$200px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 19} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#6c5ce7';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 20} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 21} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 22} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#4ecdc4');\n// renderer.registerTile(1, '#dfe6e9');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 23} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 15,\n speed = 0.01,\n life = 1.0,\n colors = ['#4ecdc4', '#e84393', '#0984e3'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#ffeaa7', '#fd79a8', '#e17055'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 24} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00cec9');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#00cec9', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.015;\n cube.rotation.y += 0.015;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 25} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n scene.fog = new THREE.Fog('#fab1a0', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 26} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 12, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.02,\n y: (Math.random() - 0.5) * 0.02,\n z: (Math.random() - 0.5) * 0.02\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#fd79a8', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 27} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#ff6b6b');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#6c5ce7', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#96ceb4',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.005;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 28} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#a29bfe');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#55efc4' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 29} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#96ceb4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#ffeaa7', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#00b894' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.02;\n torus.rotation.y += 0.02 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 30} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 31} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #74b9ff;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 32} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 33} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 34} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 35} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 36} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 37} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 38} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 39} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #ff6b6b; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 40} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 41} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#fdcb6e';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 42} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 43} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$100%`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 44} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#a29bfe';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 45} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 46} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 47} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#e84393');\n// renderer.registerTile(1, '#6c5ce7');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 48} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 12,\n speed = 0.02,\n life = 1.0,\n colors = ['#74b9ff', '#e84393', '#45b7d1'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#a29bfe', '#00b894', '#6c5ce7'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 49} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ffeaa7');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#ffeaa7', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.03;\n cube.rotation.y += 0.03;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 50} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#74b9ff');\n scene.fog = new THREE.Fog('#74b9ff', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 51} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 10, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.005,\n y: (Math.random() - 0.5) * 0.005,\n z: (Math.random() - 0.5) * 0.005\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#ff6b6b', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 52} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#fdcb6e');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#0984e3', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#ff6b6b',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.03;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 53} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#ff6b6b' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 54} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#74b9ff', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#fd79a8' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.015;\n torus.rotation.y += 0.015 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 55} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 56} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #fd79a8;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 57} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 58} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 59} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 60} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 61} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 62} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 63} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 64} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #0984e3; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 65} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 66} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#00b894';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 67} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 68} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$250px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 69} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#e17055';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 70} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 71} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 72} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#fdcb6e');\n// renderer.registerTile(1, '#e17055');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 73} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 20,\n speed = 0.01,\n life = 1.0,\n colors = ['#6c5ce7', '#0984e3', '#e17055'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#dfe6e9', '#a29bfe', '#dfe6e9'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 74} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#4ecdc4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#a29bfe', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.01;\n cube.rotation.y += 0.01;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 75} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#96ceb4');\n scene.fog = new THREE.Fog('#96ceb4', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 76} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 20, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.03,\n y: (Math.random() - 0.5) * 0.03,\n z: (Math.random() - 0.5) * 0.03\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#e17055', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 77} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#6c5ce7');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#45b7d1', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#4ecdc4',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.005;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 78} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ff6b6b');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#00b894' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 79} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#0984e3');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#45b7d1', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#0984e3' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.05;\n torus.rotation.y += 0.05 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 80} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 81} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #fab1a0;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 82} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 83} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 84} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 85} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 86} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 87} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 88} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 89} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #00cec9; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 90} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 91} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#0984e3';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 92} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 93} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$250px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 94} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#fab1a0';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 95} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 96} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 97} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#fab1a0');\n// renderer.registerTile(1, '#00b894');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 98} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 5,\n speed = 0.03,\n life = 1.0,\n colors = ['#4ecdc4', '#e17055', '#6c5ce7'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#a29bfe', '#fd79a8', '#00b894'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 99} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#4ecdc4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#55efc4', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.03;\n cube.rotation.y += 0.03;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 100} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e84393');\n scene.fog = new THREE.Fog('#e84393', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 101} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 15, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.015,\n y: (Math.random() - 0.5) * 0.015,\n z: (Math.random() - 0.5) * 0.015\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#45b7d1', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 102} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#00b894');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#e84393', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#96ceb4',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.005;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 103} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#0984e3');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#ff6b6b' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 104} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#96ceb4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#ffeaa7', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#4ecdc4' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.01;\n torus.rotation.y += 0.01 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 105} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 106} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(50%, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #4ecdc4;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 107} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 108} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 109} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 110} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 111} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 112} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 113} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 114} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #00cec9; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 115} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 116} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#00b894';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 117} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 118} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$80vh`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 119} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#96ceb4';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 120} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 121} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 122} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#dfe6e9');\n// renderer.registerTile(1, '#55efc4');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 123} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 12,\n speed = 0.1,\n life = 1.0,\n colors = ['#fd79a8', '#00cec9', '#96ceb4'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#00b894', '#6c5ce7', '#fdcb6e'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 124} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#55efc4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#fdcb6e', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.005;\n cube.rotation.y += 0.005;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 125} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#4ecdc4');\n scene.fog = new THREE.Fog('#4ecdc4', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 126} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 10, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.005,\n y: (Math.random() - 0.5) * 0.005,\n z: (Math.random() - 0.5) * 0.005\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#0984e3', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 127} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#fab1a0');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#4ecdc4', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#fdcb6e',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.015;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 128} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e17055');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#96ceb4' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 129} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#96ceb4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#a29bfe', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#fdcb6e' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.01;\n torus.rotation.y += 0.01 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 130} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 131} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #a29bfe;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 132} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 133} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 134} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 135} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 136} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 137} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 138} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 139} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #fab1a0; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 140} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 141} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#a29bfe';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 142} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 143} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$250px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 144} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#6c5ce7';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 145} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 146} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 147} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#4ecdc4');\n// renderer.registerTile(1, '#fab1a0');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 148} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 50,\n speed = 0.015,\n life = 1.0,\n colors = ['#ffeaa7', '#0984e3', '#6c5ce7'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#96ceb4', '#74b9ff', '#ffeaa7'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 149} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ff6b6b');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#45b7d1', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.005;\n cube.rotation.y += 0.005;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 150} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e17055');\n scene.fog = new THREE.Fog('#e17055', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 151} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 20, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.02,\n y: (Math.random() - 0.5) * 0.02,\n z: (Math.random() - 0.5) * 0.02\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#e17055', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 152} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#45b7d1');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#00cec9', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#e84393',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.01;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 153} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#55efc4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#00b894' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 154} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#55efc4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#e84393', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#74b9ff' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.03;\n torus.rotation.y += 0.03 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 155} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 156} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(50%, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #e84393;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 157} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 158} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 159} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 160} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 161} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 162} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 163} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 164} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #00cec9; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 165} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 166} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#45b7d1';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 167} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 168} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$400px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 169} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#74b9ff';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 170} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 171} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 172} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#00cec9');\n// renderer.registerTile(1, '#dfe6e9');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 173} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 12,\n speed = 0.1,\n life = 1.0,\n colors = ['#e17055', '#0984e3', '#a29bfe'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#00b894', '#fd79a8', '#fdcb6e'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 174} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#e17055', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.02;\n cube.rotation.y += 0.02;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 175} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fd79a8');\n scene.fog = new THREE.Fog('#fd79a8', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 176} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 12, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.01,\n y: (Math.random() - 0.5) * 0.01,\n z: (Math.random() - 0.5) * 0.01\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#e84393', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 177} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#96ceb4');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#4ecdc4', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#e17055',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.02;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 178} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#dfe6e9');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#0984e3' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 179} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#a29bfe');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#fd79a8', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#55efc4' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.1;\n torus.rotation.y += 0.1 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 180} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 181} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #e84393;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 182} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 183} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 184} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 185} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 186} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 187} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 188} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 189} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #dfe6e9; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 190} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 191} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#55efc4';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 192} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 193} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$50%`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 194} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#4ecdc4';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 195} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 196} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 197} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#96ceb4');\n// renderer.registerTile(1, '#74b9ff');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 198} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 12,\n speed = 0.03,\n life = 1.0,\n colors = ['#dfe6e9', '#ff6b6b', '#74b9ff'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#00b894', '#fd79a8', '#96ceb4'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 199} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e17055');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#fd79a8', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.015;\n cube.rotation.y += 0.015;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 200} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n scene.fog = new THREE.Fog('#fab1a0', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 201} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 15, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.05,\n y: (Math.random() - 0.5) * 0.05,\n z: (Math.random() - 0.5) * 0.05\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#00b894', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 202} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#6c5ce7');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#e17055', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#dfe6e9',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.03;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 203} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#a29bfe');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#a29bfe' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 204} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#a29bfe');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#45b7d1', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#00cec9' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.01;\n torus.rotation.y += 0.01 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 205} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 206} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #4ecdc4;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 207} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 208} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 209} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 210} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 211} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 212} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 213} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 214} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #a29bfe; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 215} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 216} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#00cec9';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 217} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 218} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$200px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 219} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#00b894';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 220} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 221} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 222} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#6c5ce7');\n// renderer.registerTile(1, '#96ceb4');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 223} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 8,\n speed = 0.05,\n life = 1.0,\n colors = ['#fd79a8', '#74b9ff', '#a29bfe'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#ff6b6b', '#00b894', '#e84393'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 224} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#a29bfe', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.05;\n cube.rotation.y += 0.05;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 225} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#55efc4');\n scene.fog = new THREE.Fog('#55efc4', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 226} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 8, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.01,\n y: (Math.random() - 0.5) * 0.01,\n z: (Math.random() - 0.5) * 0.01\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#ff6b6b', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 227} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#55efc4');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#4ecdc4', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#0984e3',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.01;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 228} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e84393');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#e17055' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 229} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#a29bfe');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#fd79a8', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#00cec9' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.015;\n torus.rotation.y += 0.015 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 230} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 231} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #fab1a0;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 232} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 233} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 234} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 235} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 236} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 237} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 238} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 239} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #dfe6e9; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 240} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 241} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#fab1a0';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 242} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 243} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$80vh`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 244} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#fdcb6e';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 245} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 246} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 247} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#fdcb6e');\n// renderer.registerTile(1, '#0984e3');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 248} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 3,\n speed = 0.005,\n life = 1.0,\n colors = ['#55efc4', '#45b7d1', '#96ceb4'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#6c5ce7', '#0984e3', '#fab1a0'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 249} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#a29bfe');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#55efc4', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.005;\n cube.rotation.y += 0.005;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 250} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ff6b6b');\n scene.fog = new THREE.Fog('#ff6b6b', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 251} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 12, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.01,\n y: (Math.random() - 0.5) * 0.01,\n z: (Math.random() - 0.5) * 0.01\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#00cec9', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 252} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#ffeaa7');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#55efc4', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#e17055',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.005;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 253} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#6c5ce7');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#6c5ce7' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 254} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#dfe6e9');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#a29bfe', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#00cec9' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.05;\n torus.rotation.y += 0.05 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 255} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 256} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #fd79a8;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 257} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 258} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 259} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 260} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 261} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 262} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 263} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 264} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #e84393; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 265} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 266} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#45b7d1';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 267} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 268} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$100%`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 269} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#74b9ff';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 270} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 271} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 272} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#e17055');\n// renderer.registerTile(1, '#74b9ff');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 273} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 20,\n speed = 0.01,\n life = 1.0,\n colors = ['#fd79a8', '#ffeaa7', '#e17055'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#6c5ce7', '#ff6b6b', '#96ceb4'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 274} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#dfe6e9');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#00b894', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.01;\n cube.rotation.y += 0.01;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 275} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e17055');\n scene.fog = new THREE.Fog('#e17055', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 276} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 5, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.015,\n y: (Math.random() - 0.5) * 0.015,\n z: (Math.random() - 0.5) * 0.015\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#00cec9', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 277} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#45b7d1');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#a29bfe', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#fab1a0',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.01;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 278} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#ffeaa7' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 279} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ffeaa7');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#fdcb6e', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#6c5ce7' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.02;\n torus.rotation.y += 0.02 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 280} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 281} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #00cec9;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 282} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 283} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 284} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 285} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 286} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 287} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 288} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 289} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #fdcb6e; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 290} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 291} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#4ecdc4';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 292} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 293} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$200px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 294} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#e84393';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 295} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 296} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 297} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#ffeaa7');\n// renderer.registerTile(1, '#00b894');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 298} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 8,\n speed = 0.1,\n life = 1.0,\n colors = ['#a29bfe', '#e17055', '#00b894'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#00cec9', '#ffeaa7', '#fab1a0'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 299} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#74b9ff');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#fab1a0', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.02;\n cube.rotation.y += 0.02;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 300} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ffeaa7');\n scene.fog = new THREE.Fog('#ffeaa7', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 301} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 12, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.02,\n y: (Math.random() - 0.5) * 0.02,\n z: (Math.random() - 0.5) * 0.02\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#e17055', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 302} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#ffeaa7');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#45b7d1', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#a29bfe',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.01;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 303} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#6c5ce7' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 304} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#4ecdc4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#a29bfe', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#ffeaa7' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.03;\n torus.rotation.y += 0.03 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 305} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 306} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(60vw, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #fdcb6e;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 307} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 308} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 309} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 310} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 311} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 312} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 313} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 314} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #ff6b6b; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 315} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 316} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#74b9ff';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 317} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 318} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$80vh`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 319} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#dfe6e9';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 320} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 321} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 322} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#ff6b6b');\n// renderer.registerTile(1, '#74b9ff');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 323} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 20,\n speed = 0.005,\n life = 1.0,\n colors = ['#dfe6e9', '#4ecdc4', '#96ceb4'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#74b9ff', '#0984e3', '#ff6b6b'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 324} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#74b9ff');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#fd79a8', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.03;\n cube.rotation.y += 0.03;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 325} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#96ceb4');\n scene.fog = new THREE.Fog('#96ceb4', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 326} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 8, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.02,\n y: (Math.random() - 0.5) * 0.02,\n z: (Math.random() - 0.5) * 0.02\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#e17055', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 327} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#96ceb4');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#e17055', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#fab1a0',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.01;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 328} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#55efc4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#dfe6e9' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 329} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ffeaa7');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#96ceb4', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#45b7d1' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.1;\n torus.rotation.y += 0.1 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 330} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 331} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #00cec9;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 332} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 333} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 334} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 335} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 336} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 337} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 338} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 339} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #00cec9; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 340} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 341} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#55efc4';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 342} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 343} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$50%`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 344} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#fdcb6e';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 345} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 346} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 347} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#45b7d1');\n// renderer.registerTile(1, '#74b9ff');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 348} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 50,\n speed = 0.03,\n life = 1.0,\n colors = ['#e17055', '#00b894', '#fdcb6e'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#4ecdc4', '#fab1a0', '#74b9ff'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 349} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#fab1a0', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.05;\n cube.rotation.y += 0.05;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 350} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00cec9');\n scene.fog = new THREE.Fog('#00cec9', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 351} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 10, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.05,\n y: (Math.random() - 0.5) * 0.05,\n z: (Math.random() - 0.5) * 0.05\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#dfe6e9', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 352} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#55efc4');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#00b894', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#e17055',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.01;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 353} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#00cec9' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 354} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ffeaa7');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#74b9ff', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#dfe6e9' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.03;\n torus.rotation.y += 0.03 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 355} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 356} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #fab1a0;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 357} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 358} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 359} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 360} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 361} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 362} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 363} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 364} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #0984e3; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 365} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 366} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#0984e3';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 367} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 368} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$300px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 369} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#55efc4';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 370} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 371} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 372} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#fdcb6e');\n// renderer.registerTile(1, '#6c5ce7');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 373} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 3,\n speed = 0.02,\n life = 1.0,\n colors = ['#ff6b6b', '#dfe6e9', '#0984e3'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#fdcb6e', '#a29bfe', '#0984e3'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 374} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#0984e3');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#dfe6e9', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.05;\n cube.rotation.y += 0.05;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 375} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e84393');\n scene.fog = new THREE.Fog('#e84393', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 376} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 20, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.1,\n y: (Math.random() - 0.5) * 0.1,\n z: (Math.random() - 0.5) * 0.1\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#96ceb4', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 377} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#e17055');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#00cec9', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#e84393',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.05;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 378} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#74b9ff');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#e84393' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 379} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ff6b6b');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#74b9ff', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#55efc4' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.005;\n torus.rotation.y += 0.005 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 380} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 381} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #fd79a8;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 382} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 383} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 384} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 385} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 386} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 387} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 388} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 389} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #a29bfe; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 390} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 391} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#e17055';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 392} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 393} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$100%`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 394} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#dfe6e9';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 395} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 396} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 397} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#00b894');\n// renderer.registerTile(1, '#e84393');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 398} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 3,\n speed = 0.015,\n life = 1.0,\n colors = ['#45b7d1', '#fd79a8', '#00cec9'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#fd79a8', '#74b9ff', '#00cec9'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 399} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fdcb6e');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#96ceb4', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.03;\n cube.rotation.y += 0.03;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 400} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#74b9ff');\n scene.fog = new THREE.Fog('#74b9ff', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 401} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 15, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.1,\n y: (Math.random() - 0.5) * 0.1,\n z: (Math.random() - 0.5) * 0.1\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#fdcb6e', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 402} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#e84393');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#ff6b6b', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#45b7d1',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.05;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 403} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e17055');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#6c5ce7' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 404} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#e84393', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#e17055' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.03;\n torus.rotation.y += 0.03 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 405} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 406} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(100%, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #00cec9;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 407} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 408} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 409} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 410} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 411} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 412} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 413} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 414} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #00cec9; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 415} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 416} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#0984e3';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 417} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 418} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$60vw`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 419} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#0984e3';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 420} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 421} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 422} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#ffeaa7');\n// renderer.registerTile(1, '#dfe6e9');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 423} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 12,\n speed = 0.03,\n life = 1.0,\n colors = ['#45b7d1', '#fd79a8', '#6c5ce7'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#dfe6e9', '#00cec9', '#fab1a0'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 424} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#0984e3');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#0984e3', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.015;\n cube.rotation.y += 0.015;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 425} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#74b9ff');\n scene.fog = new THREE.Fog('#74b9ff', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 426} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 5, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.015,\n y: (Math.random() - 0.5) * 0.015,\n z: (Math.random() - 0.5) * 0.015\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#96ceb4', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 427} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#e84393');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#ff6b6b', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#fdcb6e',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.015;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 428} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#0984e3');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#fab1a0' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 429} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#45b7d1');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#e17055', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#e84393' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.01;\n torus.rotation.y += 0.01 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 430} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 431} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #55efc4;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 432} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 433} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 434} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 435} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 436} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 437} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 438} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 439} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #fd79a8; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 440} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 441} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#a29bfe';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 442} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 443} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$300px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 444} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#dfe6e9';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 445} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 446} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 447} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#4ecdc4');\n// renderer.registerTile(1, '#00cec9');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 448} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 10,\n speed = 0.01,\n life = 1.0,\n colors = ['#fab1a0', '#96ceb4', '#74b9ff'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#96ceb4', '#00cec9', '#6c5ce7'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 449} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#55efc4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#00b894', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.05;\n cube.rotation.y += 0.05;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 450} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#0984e3');\n scene.fog = new THREE.Fog('#0984e3', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 451} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 20, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.1,\n y: (Math.random() - 0.5) * 0.1,\n z: (Math.random() - 0.5) * 0.1\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#a29bfe', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 452} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#0984e3');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#ff6b6b', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#dfe6e9',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.015;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 453} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e84393');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#4ecdc4' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 454} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#6c5ce7');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#74b9ff', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#00b894' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.005;\n torus.rotation.y += 0.005 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 455} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 456} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #6c5ce7;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 457} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 458} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 459} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 460} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 461} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 462} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 463} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 464} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #55efc4; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 465} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 466} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#e84393';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 467} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 468} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$200px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 469} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#fd79a8';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 470} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 471} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 472} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#fab1a0');\n// renderer.registerTile(1, '#45b7d1');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 473} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 50,\n speed = 0.02,\n life = 1.0,\n colors = ['#96ceb4', '#00cec9', '#fd79a8'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#a29bfe', '#fab1a0', '#6c5ce7'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 474} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#0984e3');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#fab1a0', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.03;\n cube.rotation.y += 0.03;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 475} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fd79a8');\n scene.fog = new THREE.Fog('#fd79a8', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 476} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 50, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.005,\n y: (Math.random() - 0.5) * 0.005,\n z: (Math.random() - 0.5) * 0.005\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#96ceb4', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 477} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#a29bfe');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#dfe6e9', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#0984e3',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.015;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 478} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e84393');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#96ceb4' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 479} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#55efc4', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#ffeaa7' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.03;\n torus.rotation.y += 0.03 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 480} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 481} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #6c5ce7;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 482} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 483} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 484} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 485} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 486} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 487} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 488} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 489} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #fdcb6e; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 490} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 491} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#e84393';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 492} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 493} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$300px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 494} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#e17055';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 495} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 496} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 497} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#74b9ff');\n// renderer.registerTile(1, '#e84393');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 498} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 5,\n speed = 0.05,\n life = 1.0,\n colors = ['#0984e3', '#4ecdc4', '#fab1a0'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#a29bfe', '#fdcb6e', '#e17055'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 499} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00b894');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#45b7d1', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.015;\n cube.rotation.y += 0.015;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 500} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n scene.fog = new THREE.Fog('#fab1a0', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 501} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 15, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.05,\n y: (Math.random() - 0.5) * 0.05,\n z: (Math.random() - 0.5) * 0.05\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#45b7d1', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 502} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#ff6b6b');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#e17055', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#dfe6e9',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.005;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 503} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fd79a8');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#55efc4' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 504} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#96ceb4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#e17055', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#6c5ce7' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.02;\n torus.rotation.y += 0.02 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 505} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 506} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #e17055;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 507} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 508} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 509} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 510} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 511} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 512} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 513} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 514} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #ff6b6b; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 515} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 516} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#55efc4';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 517} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 518} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$400px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 519} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#fab1a0';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 520} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 521} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 522} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#00cec9');\n// renderer.registerTile(1, '#ffeaa7');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 523} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 10,\n speed = 0.005,\n life = 1.0,\n colors = ['#6c5ce7', '#45b7d1', '#00b894'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#fdcb6e', '#74b9ff', '#6c5ce7'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 524} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#74b9ff');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#dfe6e9', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.03;\n cube.rotation.y += 0.03;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 525} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00cec9');\n scene.fog = new THREE.Fog('#00cec9', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 526} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 50, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.03,\n y: (Math.random() - 0.5) * 0.03,\n z: (Math.random() - 0.5) * 0.03\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#dfe6e9', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 527} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#ffeaa7');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#fd79a8', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#ff6b6b',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.1;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 528} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#a29bfe');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#fd79a8' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 529} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#4ecdc4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#dfe6e9', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#ffeaa7' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.01;\n torus.rotation.y += 0.01 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 530} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 531} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(80vh, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #55efc4;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 532} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 533} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 534} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 535} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 536} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 537} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 538} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 539} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #6c5ce7; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 540} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 541} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#dfe6e9';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 542} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 543} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$250px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 544} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#74b9ff';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 545} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 546} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 547} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#96ceb4');\n// renderer.registerTile(1, '#00b894');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 548} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 12,\n speed = 0.01,\n life = 1.0,\n colors = ['#74b9ff', '#6c5ce7', '#4ecdc4'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#00b894', '#ffeaa7', '#e17055'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 549} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ffeaa7');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#ff6b6b', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.1;\n cube.rotation.y += 0.1;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 550} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#dfe6e9');\n scene.fog = new THREE.Fog('#dfe6e9', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 551} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 10, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.1,\n y: (Math.random() - 0.5) * 0.1,\n z: (Math.random() - 0.5) * 0.1\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#96ceb4', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 552} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#55efc4');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#fab1a0', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#dfe6e9',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.015;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 553} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#45b7d1');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#0984e3' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 554} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00cec9');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#96ceb4', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#fab1a0' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.005;\n torus.rotation.y += 0.005 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 555} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 556} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #fdcb6e;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 557} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 558} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 559} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 560} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 561} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 562} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 563} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 564} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #fdcb6e; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 565} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 566} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#a29bfe';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 567} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 568} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$100px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 569} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#74b9ff';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 570} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 571} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 572} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#ffeaa7');\n// renderer.registerTile(1, '#6c5ce7');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 573} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 50,\n speed = 0.02,\n life = 1.0,\n colors = ['#dfe6e9', '#fd79a8', '#55efc4'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#45b7d1', '#ffeaa7', '#ffeaa7'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 574} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#4ecdc4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#00b894', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.1;\n cube.rotation.y += 0.1;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 575} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n scene.fog = new THREE.Fog('#fab1a0', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 576} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 15, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.005,\n y: (Math.random() - 0.5) * 0.005,\n z: (Math.random() - 0.5) * 0.005\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#74b9ff', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 577} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#00b894');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#00b894', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#96ceb4',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.1;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 578} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#dfe6e9');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#74b9ff' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 579} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00cec9');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#96ceb4', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#6c5ce7' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.05;\n torus.rotation.y += 0.05 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 580} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 581} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #dfe6e9;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 582} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 583} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 584} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 585} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 586} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 587} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 588} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 589} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #fd79a8; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 590} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 591} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#e84393';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 592} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 593} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$300px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 594} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#6c5ce7';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 595} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 596} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 597} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#a29bfe');\n// renderer.registerTile(1, '#4ecdc4');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 598} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 50,\n speed = 0.1,\n life = 1.0,\n colors = ['#ffeaa7', '#fd79a8', '#e84393'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#ff6b6b', '#ff6b6b', '#dfe6e9'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 599} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00b894');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#00cec9', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.005;\n cube.rotation.y += 0.005;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 600} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e17055');\n scene.fog = new THREE.Fog('#e17055', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 601} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 3, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.05,\n y: (Math.random() - 0.5) * 0.05,\n z: (Math.random() - 0.5) * 0.05\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#00cec9', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 602} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#0984e3');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#0984e3', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#dfe6e9',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.01;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 603} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00b894');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#74b9ff' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 604} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00cec9');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#96ceb4', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#45b7d1' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.005;\n torus.rotation.y += 0.005 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 605} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 606} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #45b7d1;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 607} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 608} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 609} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 610} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 611} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 612} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 613} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 614} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #ffeaa7; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 615} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 616} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#00cec9';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 617} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 618} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$250px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 619} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#55efc4';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 620} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 621} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 622} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#fdcb6e');\n// renderer.registerTile(1, '#e84393');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 623} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 15,\n speed = 0.005,\n life = 1.0,\n colors = ['#74b9ff', '#0984e3', '#6c5ce7'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#ff6b6b', '#a29bfe', '#00cec9'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 624} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#6c5ce7');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#e17055', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.02;\n cube.rotation.y += 0.02;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 625} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ffeaa7');\n scene.fog = new THREE.Fog('#ffeaa7', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 626} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 12, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.1,\n y: (Math.random() - 0.5) * 0.1,\n z: (Math.random() - 0.5) * 0.1\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#a29bfe', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 627} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#e84393');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#4ecdc4', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#74b9ff',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.1;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 628} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ff6b6b');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#fab1a0' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 629} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e17055');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#0984e3', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#e17055' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.015;\n torus.rotation.y += 0.015 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 630} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 631} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(50%, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #74b9ff;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 632} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 633} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 634} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 635} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 636} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 637} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 638} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 639} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #dfe6e9; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 640} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 641} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#74b9ff';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 642} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 643} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$80vh`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 644} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#00cec9';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 645} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 646} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 647} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#dfe6e9');\n// renderer.registerTile(1, '#e17055');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 648} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 3,\n speed = 0.01,\n life = 1.0,\n colors = ['#0984e3', '#fdcb6e', '#4ecdc4'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#fd79a8', '#ffeaa7', '#45b7d1'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 649} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fd79a8');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#96ceb4', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.1;\n cube.rotation.y += 0.1;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 650} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e17055');\n scene.fog = new THREE.Fog('#e17055', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 651} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 10, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.02,\n y: (Math.random() - 0.5) * 0.02,\n z: (Math.random() - 0.5) * 0.02\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#ffeaa7', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 652} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#ff6b6b');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#00cec9', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#fd79a8',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.02;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 653} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#55efc4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#dfe6e9' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 654} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00cec9');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#a29bfe', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#fdcb6e' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.1;\n torus.rotation.y += 0.1 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 655} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 656} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(100%, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #e17055;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 657} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 658} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 659} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 660} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 661} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 662} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 663} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 664} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #fdcb6e; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 665} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 666} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#e84393';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 667} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 668} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$80vh`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 669} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#a29bfe';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 670} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 671} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 672} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#74b9ff');\n// renderer.registerTile(1, '#0984e3');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 673} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 12,\n speed = 0.01,\n life = 1.0,\n colors = ['#fab1a0', '#a29bfe', '#45b7d1'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#0984e3', '#45b7d1', '#e84393'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 674} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#96ceb4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#74b9ff', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.1;\n cube.rotation.y += 0.1;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 675} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e17055');\n scene.fog = new THREE.Fog('#e17055', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 676} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 8, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.015,\n y: (Math.random() - 0.5) * 0.015,\n z: (Math.random() - 0.5) * 0.015\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#6c5ce7', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 677} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#00b894');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#e84393', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#fdcb6e',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.005;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 678} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#a29bfe');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#ffeaa7' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 679} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e17055');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#dfe6e9', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#00b894' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.1;\n torus.rotation.y += 0.1 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 680} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 681} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #00b894;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 682} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 683} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 684} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 685} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 686} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 687} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 688} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 689} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #6c5ce7; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 690} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 691} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#ff6b6b';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 692} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 693} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$80vh`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 694} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#55efc4';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 695} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 696} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 697} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#fd79a8');\n// renderer.registerTile(1, '#fd79a8');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 698} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 12,\n speed = 0.01,\n life = 1.0,\n colors = ['#00b894', '#a29bfe', '#6c5ce7'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#e17055', '#fd79a8', '#fdcb6e'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 699} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#a29bfe');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#55efc4', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.02;\n cube.rotation.y += 0.02;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 700} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fdcb6e');\n scene.fog = new THREE.Fog('#fdcb6e', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 701} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 20, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.05,\n y: (Math.random() - 0.5) * 0.05,\n z: (Math.random() - 0.5) * 0.05\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#ff6b6b', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 702} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#dfe6e9');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#00b894', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#dfe6e9',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.1;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 703} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ffeaa7');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#00b894' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 704} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00b894');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#00b894', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#00cec9' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.05;\n torus.rotation.y += 0.05 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 705} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 706} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #96ceb4;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 707} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 708} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 709} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 710} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 711} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 712} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 713} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 714} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #00cec9; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 715} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 716} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#00cec9';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 717} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 718} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$100%`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 719} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#96ceb4';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 720} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 721} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 722} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#fab1a0');\n// renderer.registerTile(1, '#e17055');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 723} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 10,\n speed = 0.015,\n life = 1.0,\n colors = ['#45b7d1', '#e17055', '#6c5ce7'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#fd79a8', '#0984e3', '#ffeaa7'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 724} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ffeaa7');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#0984e3', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.02;\n cube.rotation.y += 0.02;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 725} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#6c5ce7');\n scene.fog = new THREE.Fog('#6c5ce7', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 726} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 50, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.1,\n y: (Math.random() - 0.5) * 0.1,\n z: (Math.random() - 0.5) * 0.1\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#0984e3', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 727} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#4ecdc4');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#00cec9', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#ff6b6b',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.005;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 728} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#96ceb4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#0984e3' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 729} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#55efc4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#6c5ce7', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#a29bfe' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.005;\n torus.rotation.y += 0.005 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 730} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 731} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #fd79a8;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 732} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 733} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 734} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 735} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 736} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 737} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 738} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 739} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #fdcb6e; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 740} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 741} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#00cec9';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 742} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 743} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$250px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 744} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#fd79a8';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 745} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 746} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 747} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#e17055');\n// renderer.registerTile(1, '#e17055');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 748} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 20,\n speed = 0.015,\n life = 1.0,\n colors = ['#45b7d1', '#e84393', '#4ecdc4'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#55efc4', '#6c5ce7', '#96ceb4'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 749} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fdcb6e');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#ffeaa7', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.05;\n cube.rotation.y += 0.05;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 750} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00b894');\n scene.fog = new THREE.Fog('#00b894', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 751} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 10, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.01,\n y: (Math.random() - 0.5) * 0.01,\n z: (Math.random() - 0.5) * 0.01\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#6c5ce7', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 752} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#dfe6e9');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#e84393', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#55efc4',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.01;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 753} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00cec9');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#ffeaa7' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 754} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ffeaa7');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#fdcb6e', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#4ecdc4' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.02;\n torus.rotation.y += 0.02 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 755} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 756} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #ffeaa7;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 757} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 758} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 759} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 760} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 761} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 762} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 763} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 764} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #fdcb6e; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 765} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 766} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#a29bfe';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 767} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 768} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$300px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 769} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#fab1a0';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 770} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 771} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 772} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#ffeaa7');\n// renderer.registerTile(1, '#ff6b6b');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 773} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 20,\n speed = 0.015,\n life = 1.0,\n colors = ['#55efc4', '#fab1a0', '#dfe6e9'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#e84393', '#ff6b6b', '#6c5ce7'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 774} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ff6b6b');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#96ceb4', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.01;\n cube.rotation.y += 0.01;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 775} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fd79a8');\n scene.fog = new THREE.Fog('#fd79a8', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 776} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 12, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.015,\n y: (Math.random() - 0.5) * 0.015,\n z: (Math.random() - 0.5) * 0.015\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#ff6b6b', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 777} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#e84393');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#fd79a8', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#dfe6e9',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.03;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 778} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00cec9');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#00b894' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 779} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fdcb6e');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#4ecdc4', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#74b9ff' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.01;\n torus.rotation.y += 0.01 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 780} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 781} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #45b7d1;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 782} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 783} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 784} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 785} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 786} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 787} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 788} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 789} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #4ecdc4; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 790} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 791} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#fdcb6e';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 792} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 793} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$50%`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 794} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#fab1a0';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 795} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 796} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 797} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#00b894');\n// renderer.registerTile(1, '#96ceb4');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 798} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 20,\n speed = 0.005,\n life = 1.0,\n colors = ['#45b7d1', '#96ceb4', '#ffeaa7'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#6c5ce7', '#a29bfe', '#55efc4'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 799} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ffeaa7');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#fd79a8', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.05;\n cube.rotation.y += 0.05;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 800} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e84393');\n scene.fog = new THREE.Fog('#e84393', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 801} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 20, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.02,\n y: (Math.random() - 0.5) * 0.02,\n z: (Math.random() - 0.5) * 0.02\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#45b7d1', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 802} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#00cec9');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#6c5ce7', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#dfe6e9',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.005;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 803} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#4ecdc4' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 804} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fdcb6e');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#fab1a0', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#dfe6e9' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.01;\n torus.rotation.y += 0.01 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 805} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 806} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(100%, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #fdcb6e;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 807} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 808} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 809} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 810} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 811} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 812} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 813} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 814} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #e84393; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 815} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 816} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#45b7d1';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 817} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 818} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$60vw`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 819} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#45b7d1';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 820} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 821} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 822} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#dfe6e9');\n// renderer.registerTile(1, '#fdcb6e');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 823} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 5,\n speed = 0.05,\n life = 1.0,\n colors = ['#fd79a8', '#0984e3', '#fdcb6e'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#4ecdc4', '#a29bfe', '#dfe6e9'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 824} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e84393');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#96ceb4', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.015;\n cube.rotation.y += 0.015;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 825} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00b894');\n scene.fog = new THREE.Fog('#00b894', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 826} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 8, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.03,\n y: (Math.random() - 0.5) * 0.03,\n z: (Math.random() - 0.5) * 0.03\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#fab1a0', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 827} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#6c5ce7');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#45b7d1', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#45b7d1',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.03;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 828} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#dfe6e9');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#dfe6e9' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 829} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#45b7d1');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#ff6b6b', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#00b894' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.02;\n torus.rotation.y += 0.02 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 830} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 831} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #fd79a8;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 832} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 833} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 834} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 835} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 836} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 837} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 838} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 839} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #4ecdc4; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 840} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 841} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#74b9ff';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 842} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 843} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$250px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 844} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#fd79a8';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 845} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 846} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 847} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#00b894');\n// renderer.registerTile(1, '#fab1a0');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 848} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 15,\n speed = 0.015,\n life = 1.0,\n colors = ['#0984e3', '#fab1a0', '#fdcb6e'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#0984e3', '#fd79a8', '#ffeaa7'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 849} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#55efc4', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.1;\n cube.rotation.y += 0.1;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 850} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fd79a8');\n scene.fog = new THREE.Fog('#fd79a8', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 851} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 8, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.03,\n y: (Math.random() - 0.5) * 0.03,\n z: (Math.random() - 0.5) * 0.03\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#a29bfe', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 852} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#00b894');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#a29bfe', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#dfe6e9',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.03;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 853} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fdcb6e');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#dfe6e9' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 854} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#96ceb4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#55efc4', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#ffeaa7' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.03;\n torus.rotation.y += 0.03 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 855} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 856} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(50%, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #dfe6e9;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 857} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 858} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 859} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 860} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 861} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 862} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 863} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 864} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #ff6b6b; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 865} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 866} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#ffeaa7';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 867} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 868} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$100%`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 869} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#45b7d1';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 870} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 871} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 872} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#fdcb6e');\n// renderer.registerTile(1, '#74b9ff');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 873} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 50,\n speed = 0.1,\n life = 1.0,\n colors = ['#ffeaa7', '#e17055', '#e84393'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#e84393', '#6c5ce7', '#74b9ff'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 874} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#4ecdc4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#74b9ff', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.05;\n cube.rotation.y += 0.05;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 875} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fab1a0');\n scene.fog = new THREE.Fog('#fab1a0', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 876} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 20, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.05,\n y: (Math.random() - 0.5) * 0.05,\n z: (Math.random() - 0.5) * 0.05\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#e17055', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 877} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#fab1a0');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#45b7d1', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#00cec9',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.03;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 878} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#4ecdc4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#e17055' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 879} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fd79a8');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#fd79a8', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#ff6b6b' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.03;\n torus.rotation.y += 0.03 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 880} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 881} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #a29bfe;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 882} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 883} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 884} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 885} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 886} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 887} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 888} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 889} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #e84393; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 890} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 891} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#00b894';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 892} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 893} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$200px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 894} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#45b7d1';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 895} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 896} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 897} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#e84393');\n// renderer.registerTile(1, '#e84393');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 898} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 10,\n speed = 0.03,\n life = 1.0,\n colors = ['#fdcb6e', '#6c5ce7', '#dfe6e9'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#ffeaa7', '#fab1a0', '#00b894'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 899} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#6c5ce7');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#55efc4', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.1;\n cube.rotation.y += 0.1;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 900} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fdcb6e');\n scene.fog = new THREE.Fog('#fdcb6e', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 901} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 8, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.03,\n y: (Math.random() - 0.5) * 0.03,\n z: (Math.random() - 0.5) * 0.03\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#e17055', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 902} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#fab1a0');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#ff6b6b', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#fd79a8',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.03;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 903} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#6c5ce7');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#dfe6e9' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 904} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fdcb6e');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#0984e3', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#fab1a0' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.05;\n torus.rotation.y += 0.05 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 905} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 906} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #6c5ce7;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 907} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 908} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 909} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 910} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 911} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 912} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 913} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 914} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #ff6b6b; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 915} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 916} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#00cec9';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 917} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 918} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$100px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 919} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#00b894';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 920} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 921} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 922} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#55efc4');\n// renderer.registerTile(1, '#55efc4');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 923} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 50,\n speed = 0.02,\n life = 1.0,\n colors = ['#96ceb4', '#45b7d1', '#74b9ff'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#96ceb4', '#ffeaa7', '#96ceb4'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 924} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e17055');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#0984e3', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.01;\n cube.rotation.y += 0.01;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 925} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e84393');\n scene.fog = new THREE.Fog('#e84393', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 926} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 10, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.015,\n y: (Math.random() - 0.5) * 0.015,\n z: (Math.random() - 0.5) * 0.015\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#00b894', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 927} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#dfe6e9');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#6c5ce7', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#00cec9',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.1;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 928} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#dfe6e9');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#fd79a8' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 929} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#00b894');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#e84393', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#96ceb4' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.005;\n torus.rotation.y += 0.005 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 930} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 931} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #55efc4;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 932} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 933} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 934} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 935} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 936} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 937} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 938} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 939} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #fd79a8; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 940} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 941} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#00cec9';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 942} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 943} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$200px`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 944} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#fdcb6e';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 945} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 946} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 947} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#74b9ff');\n// renderer.registerTile(1, '#ffeaa7');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 948} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 50,\n speed = 0.005,\n life = 1.0,\n colors = ['#e84393', '#a29bfe', '#fab1a0'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#ffeaa7', '#a29bfe', '#fab1a0'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 949} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#45b7d1');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#fdcb6e', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.03;\n cube.rotation.y += 0.03;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 950} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fd79a8');\n scene.fog = new THREE.Fog('#fd79a8', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 951} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 10, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.02,\n y: (Math.random() - 0.5) * 0.02,\n z: (Math.random() - 0.5) * 0.02\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#6c5ce7', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 952} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#ffeaa7');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#fab1a0', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#ff6b6b',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.01;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 953} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#ff6b6b');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#ffeaa7' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 954} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#0984e3');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#ffeaa7', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#00cec9' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.1;\n torus.rotation.y += 0.1 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 955} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 956} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(100%, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #6c5ce7;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 957} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 958} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 959} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 960} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 961} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 962} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 963} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 964} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #4ecdc4; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 965} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 966} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#e17055';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 967} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 968} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$80vh`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 969} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#00b894';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 970} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 971} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 972} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#96ceb4');\n// renderer.registerTile(1, '#e17055');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 973} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 50,\n speed = 0.015,\n life = 1.0,\n colors = ['#96ceb4', '#45b7d1', '#dfe6e9'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#45b7d1', '#55efc4', '#6c5ce7'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 974} {"problem": "Create a Three.js scene with a rotating colored cube", "solution": "import * as THREE from 'three';\n\nfunction createCubeScene(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found: ' + containerId);\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#96ceb4');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.setPixelRatio(window.devicePixelRatio);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BoxGeometry(1, 1, 1);\n const material = new THREE.MeshStandardMaterial({ color: '#fab1a0', roughness: 0.3, metalness: 0.1 });\n const cube = new THREE.Mesh(geometry, material);\n scene.add(cube);\n\n const light = new THREE.DirectionalLight(0xffffff, 1);\n light.position.set(5, 5, 5);\n scene.add(light);\n scene.add(new THREE.AmbientLight(0x404040));\n\n function animate() {\n requestAnimationFrame(animate);\n cube.rotation.x += 0.01;\n cube.rotation.y += 0.01;\n renderer.render(scene, camera);\n }\n animate();\n\n window.addEventListener('resize', () => {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n renderer.setSize(container.clientWidth, container.clientHeight);\n });\n\n return { scene, camera, renderer, cube };\n}\n\n// Usage: createCubeScene();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 975} {"problem": "Load a GLTF 3D model in Three.js with orbit controls", "solution": "import * as THREE from 'three';\nimport { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\n\nasync function loadModel(url, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#0984e3');\n scene.fog = new THREE.Fog('#0984e3', 10, 50);\n\n const camera = new THREE.PerspectiveCamera(45, container.clientWidth / container.clientHeight, 0.1, 100);\n camera.position.set(0, 2, 5);\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.shadowMap.enabled = true;\n container.appendChild(renderer.domElement);\n\n const controls = new OrbitControls(camera, renderer.domElement);\n controls.enableDamping = true;\n controls.dampingFactor = 0.05;\n\n scene.add(new THREE.AmbientLight(0xffffff, 0.5));\n const dirLight = new THREE.DirectionalLight(0xffffff, 1);\n dirLight.position.set(5, 10, 7);\n dirLight.castShadow = true;\n scene.add(dirLight);\n\n const loader = new GLTFLoader();\n try {\n const gltf = await loader.loadAsync(url);\n const model = gltf.scene;\n model.traverse(child => { if (child.isMesh) child.castShadow = true; });\n scene.add(model);\n } catch (err) {\n console.error('Failed to load model:', err);\n throw err;\n }\n\n function animate() {\n requestAnimationFrame(animate);\n controls.update();\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, controls };\n}\n\n// Usage: loadModel('/models/character.glb');", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 976} {"problem": "Create a particle system in Three.js with random motion", "solution": "import * as THREE from 'three';\n\nfunction createParticles(count = 3, containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 30;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.BufferGeometry();\n const positions = new Float32Array(count * 3);\n const velocities = [];\n\n for (let i = 0; i < count; i++) {\n positions[i * 3] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 1] = (Math.random() - 0.5) * 50;\n positions[i * 3 + 2] = (Math.random() - 0.5) * 50;\n velocities.push({\n x: (Math.random() - 0.5) * 0.02,\n y: (Math.random() - 0.5) * 0.02,\n z: (Math.random() - 0.5) * 0.02\n });\n }\n\n geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3));\n const material = new THREE.PointsMaterial({ color: '#fab1a0', size: 0.5, transparent: true, opacity: 0.8 });\n const particles = new THREE.Points(geometry, material);\n scene.add(particles);\n\n function animate() {\n requestAnimationFrame(animate);\n const pos = geometry.attributes.position.array;\n for (let i = 0; i < count; i++) {\n pos[i * 3] += velocities[i].x;\n pos[i * 3 + 1] += velocities[i].y;\n pos[i * 3 + 2] += velocities[i].z;\n if (Math.abs(pos[i * 3]) > 25) velocities[i].x *= -1;\n if (Math.abs(pos[i * 3 + 1]) > 25) velocities[i].y *= -1;\n if (Math.abs(pos[i * 3 + 2]) > 25) velocities[i].z *= -1;\n }\n geometry.attributes.position.needsUpdate = true;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, particles, renderer };\n}\n\n// Usage: createParticles(200);", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 977} {"problem": "Create a reflective sphere with environment mapping in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createReflectiveSphere(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 3;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n renderer.toneMapping = THREE.ACESFilmicToneMapping;\n container.appendChild(renderer.domElement);\n\n const pmremGenerator = new THREE.PMREMGenerator(renderer);\n const envScene = new THREE.Scene();\n envScene.background = new THREE.Color('#00b894');\n envScene.add(new THREE.Mesh(\n new THREE.SphereGeometry(10, 32, 32),\n new THREE.MeshBasicMaterial({ color: '#00b894', side: THREE.BackSide })\n ));\n const envMap = pmremGenerator.fromScene(envScene).texture;\n\n const geometry = new THREE.SphereGeometry(1, 64, 64);\n const material = new THREE.MeshPhysicalMaterial({\n color: '#dfe6e9',\n metalness: 1.0,\n roughness: 0.1,\n envMap,\n envMapIntensity: 1.0\n });\n const sphere = new THREE.Mesh(geometry, material);\n scene.add(sphere);\n\n function animate() {\n requestAnimationFrame(animate);\n sphere.rotation.y += 0.05;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, sphere, renderer };\n}\n\n// Usage: createReflectiveSphere();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 978} {"problem": "Build a Three.js first-person camera controller with WASD movement", "solution": "import * as THREE from 'three';\n\nfunction createFPSController(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#fdcb6e');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.y = 1.7;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n // Floor\n const floor = new THREE.Mesh(\n new THREE.PlaneGeometry(50, 50),\n new THREE.MeshStandardMaterial({ color: '#00cec9' })\n );\n floor.rotation.x = -Math.PI / 2;\n floor.receiveShadow = true;\n scene.add(floor);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);\n dirLight.position.set(5, 10, 5);\n scene.add(dirLight);\n\n const keys = { w: false, a: false, s: false, d: false };\n const velocity = new THREE.Vector3();\n const direction = new THREE.Vector3();\n\n document.addEventListener('keydown', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = true; });\n document.addEventListener('keyup', (e) => { if (keys.hasOwnProperty(e.key.toLowerCase())) keys[e.key.toLowerCase()] = false; });\n\n container.addEventListener('click', () => container.requestPointerLock());\n document.addEventListener('mousemove', (e) => {\n if (document.pointerLockElement === container) {\n camera.rotation.y -= e.movementX * 0.002;\n camera.rotation.x -= e.movementY * 0.002;\n camera.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, camera.rotation.x));\n }\n });\n\n const clock = new THREE.Clock();\n function animate() {\n requestAnimationFrame(animate);\n const delta = clock.getDelta();\n velocity.x -= velocity.x * 10 * delta;\n velocity.z -= velocity.z * 10 * delta;\n direction.z = Number(keys.w) - Number(keys.s);\n direction.x = Number(keys.a) - Number(keys.d);\n direction.normalize();\n if (keys.w || keys.s) velocity.z -= direction.z * 40 * delta;\n if (keys.a || keys.d) velocity.x -= direction.x * 40 * delta;\n camera.translateX(-velocity.x * delta);\n camera.translateZ(-velocity.z * delta);\n camera.position.y = 1.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, camera, renderer };\n}\n\n// Usage: createFPSController();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 979} {"problem": "Create an animated torus knot with wireframe overlay in Three.js", "solution": "import * as THREE from 'three';\n\nfunction createTorusKnot(containerId = 'canvas-container') {\n const container = document.getElementById(containerId);\n if (!container) throw new Error('Container not found');\n\n const scene = new THREE.Scene();\n scene.background = new THREE.Color('#e17055');\n\n const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000);\n camera.position.z = 5;\n\n const renderer = new THREE.WebGLRenderer({ antialias: true });\n renderer.setSize(container.clientWidth, container.clientHeight);\n container.appendChild(renderer.domElement);\n\n const geometry = new THREE.TorusKnotGeometry(1, 0.3, 100, 16);\n const material = new THREE.MeshStandardMaterial({ color: '#dfe6e9', roughness: 0.4, metalness: 0.3 });\n const torus = new THREE.Mesh(geometry, material);\n scene.add(torus);\n\n const wireGeo = new THREE.WireframeGeometry(geometry);\n const wireMat = new THREE.LineBasicMaterial({ color: '#fd79a8' });\n const wireframe = new THREE.LineSegments(wireGeo, wireMat);\n torus.add(wireframe);\n\n scene.add(new THREE.AmbientLight(0x404040));\n const pointLight = new THREE.PointLight(0xffffff, 1, 100);\n pointLight.position.set(2, 3, 4);\n scene.add(pointLight);\n\n function animate() {\n requestAnimationFrame(animate);\n torus.rotation.x += 0.1;\n torus.rotation.y += 0.1 * 0.7;\n renderer.render(scene, camera);\n }\n animate();\n\n return { scene, torus, renderer };\n}\n\n// Usage: createTorusKnot();", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 980} {"problem": "Raycast from mouse to detect 3D object clicks in Three.js", "solution": "import * as THREE from 'three';\n\nfunction setupRaycasting(scene, camera, renderer, onIntersect) {\n const raycaster = new THREE.Raycaster();\n const mouse = new THREE.Vector2();\n\n renderer.domElement.addEventListener('click', (event) => {\n const rect = renderer.domElement.getBoundingClientRect();\n mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;\n mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;\n\n raycaster.setFromCamera(mouse, camera);\n const intersects = raycaster.intersectObjects(scene.children, true);\n\n if (intersects.length > 0) {\n const hit = intersects[0];\n console.log('Clicked:', hit.object.name || hit.object.uuid);\n if (typeof onIntersect === 'function') onIntersect(hit);\n }\n });\n}\n\n// Usage example:\n// const mesh = new THREE.Mesh(geometry, material);\n// mesh.name = 'clickable-box';\n// scene.add(mesh);\n// setupRaycasting(scene, camera, renderer, (hit) => {\n// hit.object.material.color.setHex(Math.random() * 0xffffff);\n// });", "domain": "threejs", "language": "javascript", "tags": ["frontend", "threejs", "webgl"], "variant": 981} {"problem": "Build a responsive CSS grid layout with auto-fit columns", "solution": "/* Responsive grid layout */\n.grid-container {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(60vw, 1fr));\n gap: 1.5rem;\n padding: 2rem;\n max-width: 1200px;\n margin: 0 auto;\n}\n\n.grid-item {\n background: #ffeaa7;\n border-radius: 12px;\n padding: 1.5rem;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n}\n\n.grid-item:hover {\n transform: translateY(-4px);\n box-shadow: 0 12px 24px rgba(0,0,0,0.15);\n}\n\n@media (max-width: 600px) {\n .grid-container {\n grid-template-columns: 1fr;\n padding: 1rem;\n }\n}", "domain": "html-css-js", "language": "css", "tags": ["frontend", "css", "dom"], "variant": 982} {"problem": "Create a sticky navigation bar that changes style on scroll", "solution": "/* Sticky nav styles */\n.nav-bar {\n position: sticky;\n top: 0;\n z-index: 1000;\n background: transparent;\n padding: 1rem 2rem;\n transition: background 0.3s ease, box-shadow 0.3s ease;\n}\n\n.nav-bar.scrolled {\n background: rgba(255, 255, 255, 0.95);\n backdrop-filter: blur(10px);\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\n/* JavaScript */\nfunction initStickyNav(navSelector = '.nav-bar') {\n const nav = document.querySelector(navSelector);\n if (!nav) throw new Error('Nav element not found');\n\n function onScroll() {\n if (window.scrollY > 50) {\n nav.classList.add('scrolled');\n } else {\n nav.classList.remove('scrolled');\n }\n }\n\n window.addEventListener('scroll', onScroll, { passive: true });\n onScroll(); // Initialize state\n return nav;\n}\n\n// Usage: initStickyNav();", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 983} {"problem": "Implement debounced search input with fetch API", "solution": "async function debouncedSearch(inputSelector, endpoint, renderFn, delay = 300) {\n const input = document.querySelector(inputSelector);\n if (!input) throw new Error('Input element not found');\n\n let timeoutId = null;\n let controller = null;\n\n input.addEventListener('input', (e) => {\n const query = e.target.value.trim();\n clearTimeout(timeoutId);\n if (controller) controller.abort();\n\n if (!query) {\n renderFn([]);\n return;\n }\n\n timeoutId = setTimeout(async () => {\n controller = new AbortController();\n try {\n const res = await fetch(`${endpoint}?q=${encodeURIComponent(query)}`, {\n signal: controller.signal\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = await res.json();\n renderFn(data);\n } catch (err) {\n if (err.name !== 'AbortError') {\n console.error('Search failed:', err);\n renderFn([], err);\n }\n }\n }, delay);\n });\n}\n\n// Usage:\n// debouncedSearch('#search', '/api/search', (results, err) => {\n// if (err) return showError(err);\n// updateDOM(results);\n// });", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 984} {"problem": "Create a CSS-only modal with backdrop blur and focus trap", "solution": "/* Modal styles */\n.modal-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.5);\n backdrop-filter: blur(4px);\n display: flex;\n align-items: center;\n justify-content: center;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.3s ease, visibility 0.3s ease;\n}\n\n.modal-overlay.active {\n opacity: 1;\n visibility: visible;\n}\n\n.modal-content {\n background: white;\n border-radius: 16px;\n padding: 2rem;\n max-width: 500px;\n width: 90%;\n transform: scale(0.9);\n transition: transform 0.3s ease;\n box-shadow: 0 20px 60px rgba(0,0,0,0.3);\n}\n\n.modal-overlay.active .modal-content {\n transform: scale(1);\n}\n\n/* JavaScript for focus trap and keyboard */\nfunction initModal(triggerSelector, modalSelector) {\n const trigger = document.querySelector(triggerSelector);\n const modal = document.querySelector(modalSelector);\n if (!trigger || !modal) throw new Error('Modal elements not found');\n\n const content = modal.querySelector('.modal-content');\n const focusables = content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])');\n\n function open() {\n modal.classList.add('active');\n (focusables[0] || content).focus();\n document.addEventListener('keydown', onKey);\n }\n\n function close() {\n modal.classList.remove('active');\n document.removeEventListener('keydown', onKey);\n trigger.focus();\n }\n\n function onKey(e) {\n if (e.key === 'Escape') close();\n if (e.key === 'Tab' && focusables.length > 0) {\n const first = focusables[0];\n const last = focusables[focusables.length - 1];\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n }\n\n trigger.addEventListener('click', open);\n modal.addEventListener('click', (e) => { if (e.target === modal) close(); });\n\n return { open, close };\n}\n\n// Usage: initModal('#open-modal', '#my-modal');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 985} {"problem": "Build a custom dropdown select with keyboard navigation", "solution": "function createCustomSelect(selectElement) {\n if (!(selectElement instanceof HTMLSelectElement)) {\n throw new TypeError('Expected HTMLSelectElement');\n }\n\n const wrapper = document.createElement('div');\n wrapper.className = 'custom-select';\n wrapper.style.position = 'relative';\n wrapper.style.width = selectElement.offsetWidth + 'px';\n\n const trigger = document.createElement('button');\n trigger.type = 'button';\n trigger.className = 'select-trigger';\n trigger.textContent = selectElement.options[selectElement.selectedIndex]?.text || 'Select...';\n trigger.setAttribute('aria-haspopup', 'listbox');\n\n const list = document.createElement('ul');\n list.className = 'select-options';\n list.setAttribute('role', 'listbox');\n list.style.cssText = 'position:absolute;top:100%;left:0;right:0;max-height:200px;overflow:auto;list-style:none;margin:0;padding:0;border:1px solid #ccc;background:#fff;z-index:100;display:none;';\n\n Array.from(selectElement.options).forEach((opt, i) => {\n const li = document.createElement('li');\n li.textContent = opt.text;\n li.setAttribute('role', 'option');\n li.setAttribute('aria-selected', String(opt.selected));\n li.dataset.value = opt.value;\n li.style.padding = '0.5rem 1rem';\n li.style.cursor = 'pointer';\n li.addEventListener('click', () => {\n selectElement.value = opt.value;\n trigger.textContent = opt.text;\n close();\n selectElement.dispatchEvent(new Event('change'));\n });\n list.appendChild(li);\n });\n\n wrapper.appendChild(trigger);\n wrapper.appendChild(list);\n selectElement.style.display = 'none';\n selectElement.parentNode.insertBefore(wrapper, selectElement);\n\n let activeIndex = -1;\n function open() {\n list.style.display = 'block';\n trigger.setAttribute('aria-expanded', 'true');\n activeIndex = Array.from(selectElement.options).findIndex(o => o.selected);\n }\n function close() {\n list.style.display = 'none';\n trigger.setAttribute('aria-expanded', 'false');\n }\n\n trigger.addEventListener('click', () => {\n list.style.display === 'block' ? close() : open();\n });\n\n document.addEventListener('click', (e) => {\n if (!wrapper.contains(e.target)) close();\n });\n\n trigger.addEventListener('keydown', (e) => {\n const items = list.querySelectorAll('li');\n if (e.key === 'ArrowDown') { open(); activeIndex = Math.min(activeIndex + 1, items.length - 1); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'ArrowUp') { open(); activeIndex = Math.max(activeIndex - 1, 0); items[activeIndex]?.focus(); e.preventDefault(); }\n if (e.key === 'Enter' || e.key === ' ') { if (list.style.display === 'block' && items[activeIndex]) items[activeIndex].click(); else open(); e.preventDefault(); }\n if (e.key === 'Escape') close();\n });\n\n return wrapper;\n}\n\n// Usage: createCustomSelect(document.getElementById('my-select'));", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 986} {"problem": "Implement smooth scroll-to-section with intersection observer highlighting", "solution": "function initScrollSpy(navSelector, sectionSelector, options = {}) {\n const navLinks = document.querySelectorAll(`${navSelector} a[href^=\"#\"]`);\n const sections = document.querySelectorAll(sectionSelector);\n if (!navLinks.length || !sections.length) {\n console.warn('Scroll spy: no nav links or sections found');\n return;\n }\n\n const offset = options.offset || 80;\n\n // Smooth scroll on click\n navLinks.forEach(link => {\n link.addEventListener('click', (e) => {\n e.preventDefault();\n const targetId = link.getAttribute('href').slice(1);\n const target = document.getElementById(targetId);\n if (target) {\n window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' });\n }\n });\n });\n\n // Intersection observer for active state\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n navLinks.forEach(l => l.classList.remove('active'));\n const active = document.querySelector(`${navSelector} a[href=\"#${entry.target.id}\"]`);\n if (active) active.classList.add('active');\n }\n });\n }, { rootMargin: `-${offset}px 0px -60% 0px` });\n\n sections.forEach(section => observer.observe(section));\n return observer;\n}\n\n// Usage: initScrollSpy('.side-nav', 'section[data-section]');", "domain": "html-css-js", "language": "javascript", "tags": ["frontend", "css", "dom"], "variant": 987} {"problem": "Create a draggable range slider with real-time value display", "solution": "function createRangeSlider(container, options = {}) {\n const { min = 0, max = 100, step = 1, value = 50, onChange } = options;\n container = typeof container === 'string' ? document.querySelector(container) : container;\n if (!container) throw new Error('Slider container not found');\n\n const wrapper = document.createElement('div');\n wrapper.className = 'range-slider';\n wrapper.style.cssText = 'display:flex;align-items:center;gap:1rem;font-family:sans-serif;';\n\n const input = document.createElement('input');\n input.type = 'range';\n input.min = min;\n input.max = max;\n input.step = step;\n input.value = value;\n input.style.flex = '1';\n\n const valueDisplay = document.createElement('span');\n valueDisplay.className = 'slider-value';\n valueDisplay.textContent = value;\n valueDisplay.style.minWidth = '3ch';\n valueDisplay.style.textAlign = 'right';\n valueDisplay.style.fontVariantNumeric = 'tabular-nums';\n\n input.addEventListener('input', (e) => {\n valueDisplay.textContent = e.target.value;\n if (typeof onChange === 'function') onChange(Number(e.target.value));\n });\n\n wrapper.appendChild(input);\n wrapper.appendChild(valueDisplay);\n container.appendChild(wrapper);\n\n return { input, valueDisplay, getValue: () => Number(input.value) };\n}\n\n// Usage:\n// createRangeSlider('#slider-box', {\n// min: 0, max: 255, value: 128,\n// onChange: (v) => { document.body.style.background = `rgb(${v},${v},${v})`; }\n// });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 988} {"problem": "Build a color picker canvas with eyedropper and palette export", "solution": "function createColorPicker(canvasId, exportBtnId) {\n const canvas = document.getElementById(canvasId);\n const exportBtn = document.getElementById(exportBtnId);\n if (!canvas || !exportBtn) throw new Error('Color picker elements not found');\n\n const ctx = canvas.getContext('2d', { willReadFrequently: true });\n let isDragging = false;\n const palette = new Set();\n\n // Draw a hue-saturation gradient\n function drawGradient() {\n const w = canvas.width;\n const h = canvas.height;\n for (let x = 0; x < w; x++) {\n const hue = (x / w) * 360;\n const grad = ctx.createLinearGradient(0, 0, 0, h);\n grad.addColorStop(0, `hsl(${hue}, 100%, 50%)`);\n grad.addColorStop(1, `hsl(${hue}, 100%, 0%)`);\n ctx.fillStyle = grad;\n ctx.fillRect(x, 0, 1, h);\n }\n }\n drawGradient();\n\n function pickColor(x, y) {\n const pixel = ctx.getImageData(x, y, 1, 1).data;\n const hex = '#' + [pixel[0], pixel[1], pixel[2]].map(c => c.toString(16).padStart(2, '0')).join('');\n return hex;\n }\n\n function handleMove(e) {\n const rect = canvas.getBoundingClientRect();\n const x = Math.min(Math.max(e.clientX - rect.left, 0), canvas.width - 1);\n const y = Math.min(Math.max(e.clientY - rect.top, 0), canvas.height - 1);\n const color = pickColor(x, y);\n canvas.style.cursor = 'crosshair';\n if (isDragging) {\n palette.add(color);\n canvas.dispatchEvent(new CustomEvent('colorpicked', { detail: { color, x, y } }));\n }\n return color;\n }\n\n canvas.addEventListener('mousedown', (e) => { isDragging = true; handleMove(e); });\n canvas.addEventListener('mousemove', handleMove);\n canvas.addEventListener('mouseup', () => { isDragging = false; });\n canvas.addEventListener('mouseleave', () => { isDragging = false; });\n\n exportBtn.addEventListener('click', () => {\n const colors = Array.from(palette);\n const blob = new Blob([JSON.stringify(colors, null, 2)], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = 'palette.json';\n a.click();\n URL.revokeObjectURL(url);\n });\n\n return { canvas, palette, pickColor };\n}\n\n// Usage: createColorPicker('picker-canvas', 'export-btn');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 989} {"problem": "Create a live code preview playground with iframe sandbox", "solution": "function createCodePlayground(containerSelector) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Playground container not found');\n\n container.innerHTML = `\n
\n
\n \n \n \n \n
\n \n \n
\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '

Hello World

', css: 'h1 { color: #00cec9; }', js: 'console.log(\"ready\");' };\n let currentLang = 'html';\n\n editor.value = files.html;\n\n container.querySelectorAll('button[data-lang]').forEach(btn => {\n btn.addEventListener('click', () => {\n files[currentLang] = editor.value;\n currentLang = btn.dataset.lang;\n editor.value = files[currentLang];\n });\n });\n\n container.querySelector('button[data-action=\"run\"]').addEventListener('click', () => {\n files[currentLang] = editor.value;\n const doc = `\n \n \n \n ${files.html}\n \n `;\n preview.srcdoc = doc;\n });\n\n return { editor, preview, getFiles: () => ({ ...files }) };\n}\n\n// Usage: createCodePlayground('#playground');", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 990} {"problem": "Build a resizable split-pane layout with drag handle", "solution": "function createSplitPane(containerSelector, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Split pane container not found');\n\n const { direction = 'horizontal', initialRatio = 0.5, minSize = 100 } = options;\n const isHorizontal = direction === 'horizontal';\n\n container.style.display = 'flex';\n container.style.flexDirection = isHorizontal ? 'row' : 'column';\n container.style.height = '100%';\n container.style.overflow = 'hidden';\n\n const pane1 = document.createElement('div');\n pane1.className = 'pane pane-1';\n pane1.style.flex = `0 0 calc(${initialRatio * 100}% - 4px)`;\n pane1.style.overflow = 'auto';\n pane1.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane1.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n const handle = document.createElement('div');\n handle.className = 'split-handle';\n handle.style.flex = '0 0 8px';\n handle.style.background = '#e0e0e0';\n handle.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n handle.style.userSelect = 'none';\n\n const pane2 = document.createElement('div');\n pane2.className = 'pane pane-2';\n pane2.style.flex = '1 1 auto';\n pane2.style.overflow = 'auto';\n pane2.style.minWidth = isHorizontal ? minSize + 'px' : 'auto';\n pane2.style.minHeight = !isHorizontal ? minSize + 'px' : 'auto';\n\n container.appendChild(pane1);\n container.appendChild(handle);\n container.appendChild(pane2);\n\n let isDragging = false;\n const sizeProp = isHorizontal ? 'clientWidth' : 'clientHeight';\n\n handle.addEventListener('mousedown', (e) => {\n isDragging = true;\n document.body.style.cursor = isHorizontal ? 'col-resize' : 'row-resize';\n });\n\n document.addEventListener('mousemove', (e) => {\n if (!isDragging) return;\n const rect = container.getBoundingClientRect();\n const pos = isHorizontal ? e.clientX - rect.left : e.clientY - rect.top;\n const ratio = Math.max(minSize, Math.min(pos, rect[sizeProp] - minSize)) / rect[sizeProp];\n pane1.style.flex = `0 0 calc(${ratio * 100}% - 4px)`;\n });\n\n document.addEventListener('mouseup', () => {\n isDragging = false;\n document.body.style.cursor = '';\n });\n\n return { pane1, pane2, handle };\n}\n\n// Usage: createSplitPane('#editor-layout', { direction: 'horizontal', initialRatio: 0.4 });", "domain": "playground", "language": "javascript", "tags": ["frontend", "ui", "interactive"], "variant": 991} {"problem": "Implement a masonry image grid with lazy loading and lightbox", "solution": "function createMasonryGallery(containerSelector, imageUrls) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Gallery container not found');\n\n container.style.columnCount = '3';\n container.style.columnGap = '1rem';\n\n if (!Array.isArray(imageUrls)) throw new TypeError('imageUrls must be an array');\n\n // Lightbox overlay\n const lightbox = document.createElement('div');\n lightbox.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,0.9);display:none;align-items:center;justify-content:center;z-index:1000;';\n const img = document.createElement('img');\n img.style.maxWidth = '90vw';\n img.style.maxHeight = '90vh';\n img.style.objectFit = 'contain';\n lightbox.appendChild(img);\n lightbox.addEventListener('click', () => { lightbox.style.display = 'none'; });\n document.body.appendChild(lightbox);\n\n imageUrls.forEach((src, i) => {\n const wrapper = document.createElement('div');\n wrapper.style.breakInside = 'avoid';\n wrapper.style.marginBottom = '1rem';\n\n const image = document.createElement('img');\n image.dataset.src = src;\n image.alt = `Gallery image ${i + 1}`;\n image.style.width = '100%';\n image.style.borderRadius = '8px';\n image.style.display = 'block';\n image.style.background = '#a29bfe';\n image.style.minHeight = '150px';\n\n image.addEventListener('click', () => {\n img.src = src;\n lightbox.style.display = 'flex';\n });\n\n wrapper.appendChild(image);\n container.appendChild(wrapper);\n });\n\n // Lazy loading\n const observer = new IntersectionObserver((entries) => {\n entries.forEach(entry => {\n if (entry.isIntersecting && entry.target.dataset.src) {\n entry.target.src = entry.target.dataset.src;\n delete entry.target.dataset.src;\n observer.unobserve(entry.target);\n }\n });\n }, { rootMargin: '200px' });\n\n container.querySelectorAll('img[data-src]').forEach(img => observer.observe(img));\n return { container, lightbox, observer };\n}\n\n// Usage: createMasonryGallery('#gallery', ['/img/1.jpg', '/img/2.jpg']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 992} {"problem": "Create an image carousel with touch swipe and keyboard controls", "solution": "function createCarousel(containerSelector, slides) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Carousel container not found');\n if (!Array.isArray(slides) || slides.length === 0) throw new Error('Slides array required');\n\n let current = 0;\n\n container.innerHTML = `\n
\n
\n \n \n
\n
\n `;\n\n const track = container.querySelector('.track');\n const indicators = container.querySelector('.indicators');\n\n slides.forEach((slide, i) => {\n const div = document.createElement('div');\n div.style.minWidth = '100%';\n div.innerHTML = slide;\n track.appendChild(div);\n\n const dot = document.createElement('button');\n dot.style.width = '10px';\n dot.style.height = '10px';\n dot.style.borderRadius = '50%';\n dot.style.border = 'none';\n dot.style.background = i === 0 ? '#fff' : 'rgba(255,255,255,0.4)';\n dot.addEventListener('click', () => goTo(i));\n indicators.appendChild(dot);\n });\n\n function goTo(index) {\n current = ((index % slides.length) + slides.length) % slides.length;\n track.style.transform = `translateX(-${current * 100}%)`;\n Array.from(indicators.children).forEach((dot, i) => {\n dot.style.background = i === current ? '#fff' : 'rgba(255,255,255,0.4)';\n });\n }\n\n container.querySelector('.prev').addEventListener('click', () => goTo(current - 1));\n container.querySelector('.next').addEventListener('click', () => goTo(current + 1));\n\n // Touch swipe\n let startX = 0;\n container.addEventListener('touchstart', (e) => { startX = e.touches[0].clientX; });\n container.addEventListener('touchend', (e) => {\n const diff = startX - e.changedTouches[0].clientX;\n if (Math.abs(diff) > 50) goTo(current + (diff > 0 ? 1 : -1));\n });\n\n // Keyboard\n container.setAttribute('tabindex', '0');\n container.addEventListener('keydown', (e) => {\n if (e.key === 'ArrowLeft') goTo(current - 1);\n if (e.key === 'ArrowRight') goTo(current + 1);\n });\n\n return { goTo, getCurrent: () => current };\n}\n\n// Usage: createCarousel('#carousel', ['', '']);", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 993} {"problem": "Build an infinite scroll image feed with skeleton placeholders", "solution": "function createInfiniteFeed(containerSelector, fetchPage, options = {}) {\n const container = document.querySelector(containerSelector);\n if (!container) throw new Error('Feed container not found');\n if (typeof fetchPage !== 'function') throw new TypeError('fetchPage must be a function');\n\n const { pageSize = 20, threshold = 300 } = options;\n let page = 1;\n let isLoading = false;\n let hasMore = true;\n\n function createSkeletons(count) {\n const frag = document.createDocumentFragment();\n for (let i = 0; i < count; i++) {\n const div = document.createElement('div');\n div.className = 'skeleton';\n div.style.cssText = 'height:200px;background:linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:8px;';\n frag.appendChild(div);\n }\n return frag;\n }\n\n // Add shimmer keyframes if not present\n if (!document.getElementById('skeleton-styles')) {\n const style = document.createElement('style');\n style.id = 'skeleton-styles';\n style.textContent = '@keyframes shimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }';\n document.head.appendChild(style);\n }\n\n async function loadMore() {\n if (isLoading || !hasMore) return;\n isLoading = true;\n const skeletons = createSkeletons(pageSize);\n container.appendChild(skeletons);\n\n try {\n const items = await fetchPage(page, pageSize);\n skeletons.remove();\n if (!items || items.length === 0) {\n hasMore = false;\n return;\n }\n items.forEach(item => container.appendChild(item));\n page++;\n } catch (err) {\n console.error('Feed load error:', err);\n skeletons.remove();\n } finally {\n isLoading = false;\n }\n }\n\n const sentinel = document.createElement('div');\n sentinel.style.height = '1px';\n container.appendChild(sentinel);\n\n const observer = new IntersectionObserver((entries) => {\n if (entries[0].isIntersecting) loadMore();\n }, { rootMargin: `${threshold}px` });\n observer.observe(sentinel);\n\n loadMore();\n return { loadMore, observer };\n}\n\n// Usage:\n// createInfiniteFeed('#feed', async (page, size) => {\n// const res = await fetch(`/api/images?page=${page}&size=$50%`);\n// const data = await res.json();\n// return data.map(url => { const img = document.createElement('img'); img.src = url; return img; });\n// });", "domain": "gallery", "language": "javascript", "tags": ["frontend", "images", "performance"], "variant": 994} {"problem": "Create a 2D canvas game loop with delta-time physics", "solution": "class GameEngine {\n constructor(canvasId, options = {}) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found: ' + canvasId);\n this.ctx = this.canvas.getContext('2d');\n this.entities = [];\n this.lastTime = 0;\n this.running = false;\n this.fps = 60;\n\n this.canvas.width = options.width || 800;\n this.canvas.height = options.height || 600;\n this.canvas.style.background = options.bg || '#ffeaa7';\n }\n\n addEntity(entity) {\n if (!entity.update || !entity.draw) {\n throw new TypeError('Entity must have update(dt) and draw(ctx) methods');\n }\n this.entities.push(entity);\n return this;\n }\n\n start() {\n this.running = true;\n requestAnimationFrame((t) => this.loop(t));\n }\n\n stop() {\n this.running = false;\n }\n\n loop(timestamp) {\n if (!this.running) return;\n const dt = Math.min((timestamp - this.lastTime) / 1000, 0.05); // Cap delta\n this.lastTime = timestamp;\n\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n\n for (const entity of this.entities) {\n entity.update(dt, this.canvas.width, this.canvas.height);\n entity.draw(this.ctx);\n }\n\n requestAnimationFrame((t) => this.loop(t));\n }\n}\n\n// Usage:\n// const engine = new GameEngine('game-canvas', { width: 800, height: 600 });\n// engine.addEntity({ update(dt, w, h) { this.x += 100 * dt; }, draw(ctx) { ctx.fillRect(this.x, 100, 20, 20); }, x: 0 });\n// engine.start();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 995} {"problem": "Implement AABB collision detection for rectangular game entities", "solution": "function checkAABBCollision(a, b) {\n if (!a || !b) throw new Error('Both entities required for collision check');\n return (\n a.x < b.x + b.width &&\n a.x + a.width > b.x &&\n a.y < b.y + b.height &&\n a.y + a.height > b.y\n );\n}\n\nfunction resolveAABBOverlap(a, b) {\n const overlapX = Math.min(a.x + a.width, b.x + b.width) - Math.max(a.x, b.x);\n const overlapY = Math.min(a.y + a.height, b.y + b.height) - Math.max(a.y, b.y);\n\n if (overlapX < overlapY) {\n const dir = a.x < b.x ? -1 : 1;\n a.x += (overlapX / 2) * dir;\n b.x -= (overlapX / 2) * dir;\n } else {\n const dir = a.y < b.y ? -1 : 1;\n a.y += (overlapY / 2) * dir;\n b.y -= (overlapY / 2) * dir;\n }\n}\n\nclass PhysicsWorld {\n constructor() {\n this.bodies = [];\n }\n\n add(body) {\n if (typeof body.x !== 'number' || typeof body.y !== 'number') {\n throw new TypeError('Body must have numeric x and y properties');\n }\n this.bodies.push(body);\n }\n\n step() {\n for (let i = 0; i < this.bodies.length; i++) {\n for (let j = i + 1; j < this.bodies.length; j++) {\n if (checkAABBCollision(this.bodies[i], this.bodies[j])) {\n resolveAABBOverlap(this.bodies[i], this.bodies[j]);\n if (this.bodies[i].onCollision) this.bodies[i].onCollision(this.bodies[j]);\n if (this.bodies[j].onCollision) this.bodies[j].onCollision(this.bodies[i]);\n }\n }\n }\n }\n}\n\n// Usage:\n// const world = new PhysicsWorld();\n// world.add({ x: 0, y: 0, width: 32, height: 32, onCollision(other) { console.log('hit!'); } });\n// world.step();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 996} {"problem": "Build a sprite animation system with frame clipping and playback controls", "solution": "class SpriteAnimator {\n constructor(image, frameWidth, frameHeight, frameCount) {\n if (!(image instanceof HTMLImageElement)) throw new TypeError('Expected HTMLImageElement');\n this.image = image;\n this.frameWidth = frameWidth;\n this.frameHeight = frameHeight;\n this.frameCount = frameCount;\n this.currentFrame = 0;\n this.elapsed = 0;\n this.fps = 10;\n this.playing = true;\n this.loop = true;\n }\n\n update(dt) {\n if (!this.playing) return;\n this.elapsed += dt;\n const frameDuration = 1 / this.fps;\n if (this.elapsed >= frameDuration) {\n this.elapsed -= frameDuration;\n this.currentFrame++;\n if (this.currentFrame >= this.frameCount) {\n if (this.loop) this.currentFrame = 0;\n else { this.currentFrame = this.frameCount - 1; this.playing = false; }\n }\n }\n }\n\n draw(ctx, x, y, options = {}) {\n const sx = (this.currentFrame * this.frameWidth) % this.image.width;\n const sy = Math.floor((this.currentFrame * this.frameWidth) / this.image.width) * this.frameHeight;\n const scale = options.scale || 1;\n ctx.drawImage(\n this.image,\n sx, sy, this.frameWidth, this.frameHeight,\n x, y, this.frameWidth * scale, this.frameHeight * scale\n );\n }\n\n play() { this.playing = true; }\n pause() { this.playing = false; }\n reset() { this.currentFrame = 0; this.elapsed = 0; }\n setFrame(index) { this.currentFrame = Math.max(0, Math.min(index, this.frameCount - 1)); }\n}\n\n// Usage:\n// const img = new Image();\n// img.src = '/sprites/player.png';\n// img.onload = () => {\n// const anim = new SpriteAnimator(img, 32, 32, 8);\n// // In game loop: anim.update(dt); anim.draw(ctx, 100, 100);\n// };", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 997} {"problem": "Implement a tilemap renderer with camera scrolling and culling", "solution": "class TilemapRenderer {\n constructor(canvasId, tileSize = 32) {\n this.canvas = document.getElementById(canvasId);\n if (!this.canvas) throw new Error('Canvas not found');\n this.ctx = this.canvas.getContext('2d');\n this.tileSize = tileSize;\n this.camera = { x: 0, y: 0 };\n this.tiles = []; // 2D array of tile IDs\n this.tileset = new Map(); // ID -> color or image\n }\n\n loadMap(tiles) {\n if (!Array.isArray(tiles) || !tiles.every(row => Array.isArray(row))) {\n throw new TypeError('tiles must be a 2D array');\n }\n this.tiles = tiles;\n }\n\n registerTile(id, renderable) {\n this.tileset.set(id, renderable);\n }\n\n setCamera(x, y) {\n this.camera.x = x;\n this.camera.y = y;\n }\n\n render() {\n const cols = Math.ceil(this.canvas.width / this.tileSize) + 1;\n const rows = Math.ceil(this.canvas.height / this.tileSize) + 1;\n const startCol = Math.floor(this.camera.x / this.tileSize);\n const startRow = Math.floor(this.camera.y / this.tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n const tileRow = startRow + r;\n const tileCol = startCol + c;\n if (tileRow < 0 || tileRow >= this.tiles.length) continue;\n if (tileCol < 0 || tileCol >= this.tiles[tileRow].length) continue;\n\n const tileId = this.tiles[tileRow][tileCol];\n const screenX = c * this.tileSize - (this.camera.x % this.tileSize);\n const screenY = r * this.tileSize - (this.camera.y % this.tileSize);\n\n const renderable = this.tileset.get(tileId);\n if (typeof renderable === 'string') {\n this.ctx.fillStyle = renderable;\n this.ctx.fillRect(screenX, screenY, this.tileSize, this.tileSize);\n } else if (renderable instanceof HTMLImageElement) {\n this.ctx.drawImage(renderable, screenX, screenY, this.tileSize, this.tileSize);\n }\n }\n }\n }\n}\n\n// Usage:\n// const renderer = new TilemapRenderer('game-canvas', 32);\n// renderer.loadMap([[0,0,1],[0,1,1],[1,1,1]]);\n// renderer.registerTile(0, '#e17055');\n// renderer.registerTile(1, '#00b894');\n// renderer.setCamera(100, 50);\n// renderer.render();", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 998} {"problem": "Create a particle explosion effect on canvas for game feedback", "solution": "class ParticleSystem {\n constructor() {\n this.particles = [];\n }\n\n emit(x, y, options = {}) {\n const {\n count = 20,\n speed = 0.02,\n life = 1.0,\n colors = ['#fab1a0', '#74b9ff', '#6c5ce7'],\n size = 4,\n gravity = 200\n } = options;\n\n for (let i = 0; i < count; i++) {\n const angle = (Math.PI * 2 * i) / count + (Math.random() - 0.5) * 0.5;\n const velocity = speed * (0.5 + Math.random() * 0.5);\n this.particles.push({\n x, y,\n vx: Math.cos(angle) * velocity,\n vy: Math.sin(angle) * velocity,\n life,\n maxLife: life,\n color: colors[Math.floor(Math.random() * colors.length)],\n size: size * (0.5 + Math.random()),\n gravity\n });\n }\n }\n\n update(dt) {\n for (let i = this.particles.length - 1; i >= 0; i--) {\n const p = this.particles[i];\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n p.vy += p.gravity * dt;\n p.life -= dt;\n if (p.life <= 0) this.particles.splice(i, 1);\n }\n }\n\n draw(ctx) {\n for (const p of this.particles) {\n const alpha = Math.max(0, p.life / p.maxLife);\n ctx.globalAlpha = alpha;\n ctx.fillStyle = p.color;\n ctx.beginPath();\n ctx.arc(p.x, p.y, p.size * alpha, 0, Math.PI * 2);\n ctx.fill();\n }\n ctx.globalAlpha = 1;\n }\n}\n\n// Usage:\n// const particles = new ParticleSystem();\n// particles.emit(400, 300, { count: 30, speed: 150, colors: ['#0984e3', '#ff6b6b', '#fdcb6e'] });\n// // In game loop: particles.update(dt); particles.draw(ctx);", "domain": "games", "language": "javascript", "tags": ["frontend", "canvas", "game-dev"], "variant": 999}