WEBLEB
होम
संपादक
लॉग इन करें
Pro
हिंदी
English
Français
Español
Português
Deutsch
Italiano
हिंदी
कृत्रिम-3D सीएसएस क्षेत्र / बनावट के साथ
1183
zegarkidawida
संपादक में खोलें
अपना कोड प्रकाशित करें
अनुशंसित
7 March 2025
क्रॉसी रोड three.js के साथ
23 August 2024
व्याख्याता एमपी3 और एचटीएमएल सीएसएस और जेएस
16 October 2025
फ़्रैगमेंट प्रभावों के साथ CSS लोडिंग एनीमेशन
HTML
Copy
bands
cells
size
speed
texture
↗
↗
↗
borders
CSS
Copy
@layer cosmetics, utilities, demo; @layer demo { body { height: 100dvh; display: grid; place-content: center; } .world { --bands: 130; --cells: 60; --_size: 80; --size: calc(var(--_size) * 1dvmin); --_speed: 15; --speed: calc((20.5 - var(--_speed)) * 1s); --image: url(https://assets.codepen.io/25387/Gall_Stereographic_projection_SW_centered.jpg); display: flex; align-items: center; flex-direction: column; clip-path: circle(); } .band { --latitude: calc(sin(PI / var(--bands) * var(--i)) * 1.2); --width: calc(var(--size) * var(--latitude)); width: var(--width); height: calc(var(--size) / var(--bands) * var(--latitude)); display: flex; justify-content: center; } .cell { --longitude: calc(sin(PI / var(--cells) * var(--j)) * 1.2); --bg-width: calc(var(--width) * var(--longitude) * 1.25); --bg-height: calc(var(--size) * 0.9); height: calc(var(--size) * var(--longitude)); width: calc(var(--width) / var(--cells) * var(--longitude)); background: var(--image) 50% fixed; background-size: var(--bg-width) var(--bg-height); animation: spin var(--speed) linear infinite; } .with-borders .cell { box-shadow: 0 0 0 1px chartreuse; } @keyframes spin { 100% { background-position-x: calc(50% + var(--bg-width)); } } } @layer cosmetics { body { overflow: hidden; margin: 0; background: cornsilk; } .world::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: cornsilk; opacity: .5; mix-blend-mode: color; } } @layer utilities { .utilities { position: absolute; top: 0; right: 0; z-index: 1; padding: 1em; } .utilities .control { display: flex; justify-content: center; align-items: center; min-height: 24px; gap: .5em; font-size: 1.1em; font-family: monospace; font-variant: small-caps; letter-spacing: .05em; } .utilities #image:has(:focus) { border: 2px solid royalblue; } .utilities #image input { position: absolute; top: -100dvh; left: -100dvw; opacity: 0; } .utilities .image-wrapper { --color-1: #ddd; --color-2: royalblue; position: relative; width: max(10dvmin, 48px); height: max(10dvmin, 48px); color: var(--color-1); } .utilities .image-wrapper a { display: none; position: absolute; bottom: 0; right: 0; translate: 30% 30%; width: 30%; height: 30%; justify-content: center; align-items: center; font-size: 1.5em; text-decoration: none; background: var(--color-1); color: var(--color-2); border-radius: 50%; } .utilities .image-wrapper img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; border: .5dvmin solid var(--color-1); } .utilities #image :checked + .image-wrapper { --color-1: royalblue; --color-2: #ddd; } .utilities #image :checked + .image-wrapper a { display: inline-flex; } }
JS
Copy
/* * JS just handles the playground of parameters * and inserts the repeated markup. */ const UI = { bands: document.querySelector('#bands'), cells: document.querySelector('#cells'), size: document.querySelector('#size'), speed: document.querySelector('#speed'), image: document.querySelectorAll('#image input'), borders: document.querySelector('#with-border'), world: document.querySelector('.world') } const state = { bands: +UI.bands.value, cells: +UI.cells.value, size: +UI.size.value, speed: +UI.speed.value, image: UI.image[0].value, borders: UI.borders.checked } UI.bands.addEventListener('input', (e) => { state.bands = +e.target.value render() }) UI.cells.addEventListener('input', (e) => { state.cells = +e.target.value render() }) UI.size.addEventListener('input', (e) => { state.size = +e.target.value render() }) UI.speed.addEventListener('input', (e) => { state.speed = +e.target.value render() }) Array.from(UI.image).forEach(input => { input.addEventListener('change', () => { state.image = input.value render() }) }) UI.borders.addEventListener('input', (e) => { state.borders = e.target.checked render() }) render() function render() { UI.world.style.setProperty('--bands', state.bands) UI.world.style.setProperty('--cells', state.cells) UI.world.style.setProperty('--_size', state.size) UI.world.style.setProperty('--_speed', state.speed) UI.world.style.setProperty('--image', state.image) UI.world.classList.toggle('with-borders', state.borders) UI.world.innerHTML = chunk(state.bands, i => ` <div class="band" style="--i: ${i}"> ${chunk(state.cells, j => ` <div class="cell" style="--j: ${j}"></div> `)} </div> `) } function chunk(howMany, mapFn) { return Array .from({ length: howMany }, (_, i) => mapFn(i)) .join('') }