Demo stand for 3D bars (vanilla version)
<!DOCTYPE html> | |
<html lang="en" style="background: black;"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |
<title>Neon 3D bars demo</title> | |
<style> | |
#root { | |
display: flex; | |
flex-wrap: wrap; | |
} | |
.container { | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
} | |
.plane { | |
transform-style: preserve-3d; | |
animation: rotate 6s linear infinite; | |
} | |
.face { | |
background: #ffffff11; | |
border: 1px solid #ffffff22; | |
box-shadow: inset 0 0 8px 8px #ffffff22; | |
position: absolute; | |
overflow: hidden; | |
} | |
@keyframes rotate { | |
from { | |
transform: rotate3d(1, 1, 1, 0deg); | |
} | |
to { | |
transform: rotate3d(1, 1, 1, 360deg); | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<div id="root"></div> | |
<script type="text/javascript"> | |
const faceFront = 0; | |
const faceBack = 1; | |
const faceRight = 2; | |
const faceLeft = 3; | |
const faceTop = 4; | |
const faceBottom = 5; | |
const faces = 6; | |
const barsCount = () => Math.floor(Math.random() * 5) + 1; | |
const objectSize = () => Math.floor(Math.random() * 250) + 100; | |
const objectDepth = () => Math.floor(Math.random() * 125) + 100; | |
const objectPerspective = () => Math.floor(Math.random() * 1000) + 250; | |
const root = document.getElementById("root"); | |
/** | |
* @param {number} order | |
* @param {number} steps | |
* @param {number} width | |
* @param {number} height | |
* @param {number} depth | |
* @return {[number, number]} | |
*/ | |
function calcSize(order, steps, width, height, depth) { | |
switch (order) { | |
case faceFront: | |
case faceBack: | |
return [width, height / steps]; | |
case faceRight: | |
case faceLeft: | |
return [depth * 2, height / steps]; | |
case faceTop: | |
case faceBottom: | |
return [width, depth * 2]; | |
} | |
} | |
function transform( | |
order, | |
nHeight, | |
nSizeY, | |
planeDepth, | |
planeWidth, | |
sizeX, | |
faceHeight | |
) { | |
switch (order) { | |
case faceFront: | |
return `translate3d(0, ${nHeight}px, ${planeDepth}px)`; | |
case faceBack: | |
return `rotateY(180deg) translate3d(0, ${nHeight}px, ${planeDepth}px)`; | |
case faceRight: | |
return `rotateY(90deg) translate3d(0, ${nHeight}px, ${sizeX / | |
-2}px)`; | |
case faceLeft: | |
return `rotateY(-90deg) translate3d(0, ${nHeight}px, ${sizeX / 2 - | |
planeWidth}px)`; | |
case faceTop: | |
return `rotateX(90deg) translate3d(0, 0, ${nSizeY - nHeight}px)`; | |
case faceBottom: | |
return `rotateX(-90deg) translate3d(0, 0, ${nHeight + | |
faceHeight - | |
nSizeY}px)`; | |
} | |
} | |
/** | |
* @param {HTMLDivElement} face | |
* @param {number} faceNumber | |
* @param {number} faceHeight | |
* @param {number} faceStep | |
* @param {number} planeWidth | |
* @param {number} planeHeight | |
* @param {number} planeDepth | |
*/ | |
function configure( | |
face, | |
faceNumber, | |
faceHeight, | |
faceStep, | |
planeWidth, | |
planeHeight, | |
planeDepth | |
) { | |
const order = faceNumber % faces; | |
const nHeight = ((faceNumber - order) / 3) * faceHeight; | |
const [sizeX, sizeY] = calcSize( | |
order, | |
faceStep, | |
planeWidth, | |
planeHeight, | |
planeDepth | |
); | |
const nSizeY = sizeY / 2; | |
face.className = "face"; | |
face.style.width = `${sizeX}px`; | |
face.style.height = `${sizeY}px`; | |
face.style.transform = transform( | |
order, | |
nHeight, | |
nSizeY, | |
planeDepth, | |
planeWidth, | |
sizeX, | |
faceHeight | |
); | |
} | |
/** | |
* @param {HTMLDivElement} container | |
* @param {number} bars | |
* @param {number} width | |
* @param {number} height | |
* @param {number} depth | |
*/ | |
function build(container, bars, width, height, depth) { | |
if (!container) { | |
return; | |
} | |
container.style.width = `${width}px`; | |
container.style.height = `${height}px`; | |
const planeWidth = width / 2; | |
const planeHeight = height / 2; | |
const planeDepth = depth / 2; | |
const faceStep = bars * 2 - 1; | |
const faceHeight = planeHeight / faceStep; | |
const plane = document.createElement("div"); | |
plane.className = "plane"; | |
plane.style.width = `${planeWidth}px`; | |
plane.style.height = `${planeHeight}px`; | |
for (var i = 0; i < bars * faces; i++) { | |
const face = document.createElement("div"); | |
configure( | |
face, | |
i, | |
faceHeight, | |
faceStep, | |
planeWidth, | |
planeHeight, | |
planeDepth | |
); | |
plane.appendChild(face); | |
} | |
container.appendChild(plane); | |
} | |
for (var i = 1; i <= 10; i++) { | |
const container = document.createElement("div"); | |
container.className = "container"; | |
container.style.perspective = `${objectPerspective()}px`; | |
build( | |
container, | |
barsCount(), | |
objectSize(), | |
objectSize(), | |
objectDepth() | |
); | |
root.appendChild(container); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment