JSFiddle - React, Tailwind, and code Playground
HTML
<!-- Import maps polyfill -->
<!-- Remove this when import maps will be widely supported -->
<script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.160.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.160.0/examples/jsm/",
"threeCSSLayout": "https://www.unpkg.com/three-css-layout/dist/three-css-layout.js"
}
}
</script>
<div id="layout">
<div class="grid-item"><i></i></div>
<div class="grid-item"><i></i></div>
<div class="grid-item"><i></i></div>
<div class="grid-item"><i></i></div>
<div class="grid-item"><i></i></div>
<div class="grid-item"><i></i></div>
</div>
CSS
body {
margin: 0;
}
canvas {
display: block;
position: absolute;
top: 0;
left: 0;
}
#layout {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 10px;
height: 100vh;
width: 100vw;
}
.grid-item {
position: relative;
flex: 1;
display: flex;
justify-content: center;
align-items: center;
background-color: #ddd;
padding: 20px;
text-align: center;
}
.grid-item i {
min-width: 80%;
min-height: 80%;
border: 2px solid #999;
}
.grid-item:nth-child(4) i {
animation: timeAnimation 2s infinite;
}
@keyframes timeAnimation {
0%, 100% {
transform: rotate(0deg);
}
25% {
transform: rotate(30deg);
}
50% {
transform: rotate(0deg);
}
75% {
transform: rotate(-30deg);
}
}
JavaScript
import * as THREE from 'three';
import {
CSSLayout,
CSSLayoutObject
} from "threeCSSLayout";
// init
const camera = new THREE.PerspectiveCamera(24, window.innerWidth / window.innerHeight, 0.001, 100);
camera.position.z = 10;
const scene = new THREE.Scene();
const cssLayout = new CSSLayout("#layout");
scene.add(cssLayout);
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshNormalMaterial();
for (let i = 1; i < 7; i++) {
const cssLayoutObject = new CSSLayoutObject(
`.grid-item:nth-child(${i}) i`,
i%2 ? "fill": "contain"
);
const mesh = new THREE.Mesh(geometry, material);
cssLayoutObject.add(mesh)
cssLayout.add(cssLayoutObject);
}
cssLayout.fitCamera(camera, "contain");
const renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearAlpha(0);
renderer.setAnimationLoop(animation);
document.body.appendChild(renderer.domElement);
// animation
function animation(time) {
cssLayout.updateObjects();
renderer.render(scene, camera);
}
window.onresize = () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
cssLayout.fitCamera(camera, "contain");
}