Some checks failed
Architecture Lint / Linter Tests (pull_request) Successful in 18s
Smoke Test / smoke (pull_request) Failing after 11s
Validate Config / YAML Lint (pull_request) Failing after 16s
Validate Config / JSON Validate (pull_request) Successful in 20s
Validate Config / Python Syntax & Import Check (pull_request) Failing after 59s
Validate Config / Python Test Suite (pull_request) Has been skipped
Validate Config / Shell Script Lint (pull_request) Failing after 41s
Validate Config / Cron Syntax Check (pull_request) Successful in 3s
Validate Config / Deploy Script Dry Run (pull_request) Successful in 3s
Validate Config / Playbook Schema Validation (pull_request) Successful in 8s
Validate Training Data / validate (pull_request) Successful in 6s
Architecture Lint / Lint Repository (pull_request) Failing after 7s
PR Checklist / pr-checklist (pull_request) Failing after 7m7s
Adds training/scripts/generate_code_patterns_frontend.py — a deterministic generator that produces problem-to-solution training pairs for: - Three.js (280 pairs): scenes, loaders, particles, raycasting, controllers - HTML/CSS/JS (240 pairs): grids, sticky navs, debounced search, modals, dropdowns, scroll spy - Playground UI (160 pairs): sliders, color pickers, code preview, split panes - Gallery (120 pairs): masonry grid, carousel, infinite feed - Games (200 pairs): game loop, AABB collision, sprite animation, tilemap, particle explosions Each pair includes imports, error handling, and usage context. Output: training-data/code-patterns-frontend-\&-creative.jsonl (1000 lines, ~1.9 MB) Generator is seeded (seed=42) for reproducibility.
1001 lines
1.9 MiB
1001 lines
1.9 MiB
{"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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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 <div class=\"playground\" style=\"display:flex;flex-direction:column;height:100%;font-family:monospace;\">\n <div style=\"display:flex;gap:0.5rem;padding:0.5rem;background:#f5f5f5;border-bottom:1px solid #ddd;\">\n <button data-lang=\"html\">HTML</button>\n <button data-lang=\"css\">CSS</button>\n <button data-lang=\"js\">JS</button>\n <button data-action=\"run\" style=\"margin-left:auto;\">Run</button>\n </div>\n <textarea class=\"editor\" style=\"flex:1;resize:none;border:none;padding:1rem;background:#1e1e1e;color:#d4d4d4;font-size:14px;\" spellcheck=\"false\"></textarea>\n <iframe class=\"preview\" sandbox=\"allow-scripts\" style=\"flex:1;border:none;border-top:1px solid #ddd;\"></iframe>\n </div>\n `;\n\n const editor = container.querySelector('.editor');\n const preview = container.querySelector('.preview');\n const files = { html: '<h1>Hello World</h1>', 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 <!DOCTYPE html>\n <html>\n <head><style>${files.css}</style></head>\n <body>${files.html}<script>try { ${files.js} } catch(e) { document.body.innerHTML += '<pre style=\"color:red\">' + e + '</pre>'; }</script></body>\n </html>\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 <div class=\"carousel\" style=\"position:relative;overflow:hidden;border-radius:12px;\">\n <div class=\"track\" style=\"display:flex;transition:transform 0.4s ease;\"></div>\n <button class=\"prev\" style=\"position:absolute;left:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Previous slide\">←</button>\n <button class=\"next\" style=\"position:absolute;right:1rem;top:50%;transform:translateY(-50%);\" aria-label=\"Next slide\">→</button>\n <div class=\"indicators\" style=\"position:absolute;bottom:1rem;left:50%;transform:translateX(-50%);display:flex;gap:0.5rem;\"></div>\n </div>\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', ['<img src=\"a.jpg\">', '<img src=\"b.jpg\">']);", "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}
|