new 3d loading animation

This commit is contained in:
Adrien MALINGREY 2024-09-30 21:21:50 +02:00
parent d9397c4bcb
commit 2a25dbe4b0
7 changed files with 196 additions and 287 deletions

8
app.js
View File

@ -1,10 +1,10 @@
import * as THREE from 'three'
import { scheduler } from './jsm/scheduler.js'
import { TRANSLATION, ROTATION, environment, Mino, Playfield, HoldQueue, NextQueue } from './jsm/Tetrominoes.js'
import { Settings } from './jsm/Settings.js'
import Settings from './jsm/Settings.js'
import { Stats } from './jsm/Stats.js'
import { TetraGUI } from './jsm/TetraGUI.js'
import { TetraControls } from './jsm/TetraControls.js'
import TetraControls from './jsm/TetraControls.js'
import { TetraScene } from './jsm/TetraScene.js'
@ -277,7 +277,7 @@ renderer.domElement.tabIndex = 1
let loadingManager = new THREE.LoadingManager(
function() {
loaddingCircle.style.display = "none"
loadingDiv.style.display = "none"
gui.startButton.show()
renderer.setAnimationLoop(animate)
},
@ -290,7 +290,7 @@ let loadingManager = new THREE.LoadingManager(
)
loadingManager.onStart = function (url, itemsLoaded, itemsTotal) {
loadingPercent.innerText = "0%"
loaddingCircle.style.display = "block"
loadingDiv.style.display = "block"
}
const stats = new Stats()

View File

@ -1,279 +1,64 @@
@-webkit-keyframes outerRotate1 {
0% {
transform: translate(-50%, -50%) rotate(0);
}
body { background-color: black; }
100% {
transform: translate(-50%, -50%) rotate(360deg);
}
}
@-moz-keyframes outerRotate1 {
0% {
transform: translate(-50%, -50%) rotate(0);
}
100% {
transform: translate(-50%, -50%) rotate(360deg);
}
}
@-o-keyframes outerRotate1 {
0% {
transform: translate(-50%, -50%) rotate(0);
}
100% {
transform: translate(-50%, -50%) rotate(360deg);
}
}
@keyframes outerRotate1 {
0% {
transform: translate(-50%, -50%) rotate(0);
}
100% {
transform: translate(-50%, -50%) rotate(360deg);
}
}
@-webkit-keyframes outerRotate2 {
0% {
transform: translate(-50%, -50%) rotate(0);
}
100% {
transform: translate(-50%, -50%) rotate(-360deg);
}
}
@-moz-keyframes outerRotate2 {
0% {
transform: translate(-50%, -50%) rotate(0);
}
100% {
transform: translate(-50%, -50%) rotate(-360deg);
}
}
@-o-keyframes outerRotate2 {
0% {
transform: translate(-50%, -50%) rotate(0);
}
100% {
transform: translate(-50%, -50%) rotate(-360deg);
}
}
@keyframes outerRotate2 {
0% {
transform: translate(-50%, -50%) rotate(0);
}
100% {
transform: translate(-50%, -50%) rotate(-360deg);
}
}
@-webkit-keyframes textColour {
0% {
color: #fff;
}
100% {
color: #3BB2D0;
}
}
@-moz-keyframes textColour {
0% {
color: #fff;
}
100% {
color: #3BB2D0;
}
}
@-o-keyframes textColour {
0% {
color: #fff;
}
100% {
color: #3BB2D0;
}
}
@keyframes textColour {
0% {
color: #fff;
}
100% {
color: #3BB2D0;
}
}
body {
background-color: #222;
}
#loaddingCircle {
margin: 0;
padding: 0;
width: 100vw;
height: 100vh;
cursor: progress;
}
.e-loadholder {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-51%, -50%);
-moz-transform: translate(-51%, -50%);
-ms-transform: translate(-51%, -50%);
-o-transform: translate(-51%, -50%);
transform: translate(-51%, -50%);
width: 240px;
height: 240px;
border: 5px solid #1B5F70;
border-radius: 120px;
#loadingDiv {
box-sizing: border-box;
}
.e-loadholder:after {
font-family: "Open Sans", sans-serif;
font-size: 1.4rem;
color: hsla(240, 100%, 70%, 0.6);
text-align: center;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-51%, -50%);
-moz-transform: translate(-51%, -50%);
-ms-transform: translate(-51%, -50%);
-o-transform: translate(-51%, -50%);
transform: translate(-51%, -50%);
content: " ";
display: block;
background: #222;
transform-origin: center;
z-index: 0;
transform: translate(-50%, -50%);
}
.e-loadholder:after {
width: 100px;
height: 200%;
-webkit-animation: outerRotate2 30s infinite linear;
-moz-animation: outerRotate2 30s infinite linear;
-o-animation: outerRotate2 30s infinite linear;
animation: outerRotate2 30s infinite linear;
}
.e-loadholder .m-loader {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-51%, -50%);
-moz-transform: translate(-51%, -50%);
-ms-transform: translate(-51%, -50%);
-o-transform: translate(-51%, -50%);
transform: translate(-51%, -50%);
.scene {
width: 200px;
height: 200px;
color: #888;
text-align: center;
border: 5px solid #2a93ae;
border-radius: 100px;
box-sizing: border-box;
z-index: 20;
text-transform: uppercase;
margin: auto;
perspective: 200px;
}
.e-loadholder .m-loader:after {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-51%, -50%);
-moz-transform: translate(-51%, -50%);
-ms-transform: translate(-51%, -50%);
-o-transform: translate(-51%, -50%);
transform: translate(-51%, -50%);
content: " ";
display: block;
background: #222;
transform-origin: center;
z-index: -1;
}
.e-loadholder .m-loader:after {
width: 100px;
height: 106%;
-webkit-animation: outerRotate1 15s infinite linear;
-moz-animation: outerRotate1 15s infinite linear;
-o-animation: outerRotate1 15s infinite linear;
animation: outerRotate1 15s infinite linear;
}
.e-loadholder .m-loader .e-text {
font-family: "Open Sans", sans-serif;
font-size: 10px;
font-size: 1rem;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-51%, -50%);
-moz-transform: translate(-51%, -50%);
-ms-transform: translate(-51%, -50%);
-o-transform: translate(-51%, -50%);
transform: translate(-51%, -50%);
-webkit-animation: textColour 1s alternate linear infinite;
-moz-animation: textColour 1s alternate linear infinite;
-o-animation: textColour 1s alternate linear infinite;
animation: textColour 1s alternate linear infinite;
display: flex;
flex-direction: column;
justify-content: center;
width: 140px;
height: 140px;
text-align: center;
border: 5px solid #3bb2d0;
border-radius: 70px;
box-sizing: border-box;
z-index: 20;
}
.e-loadholder .m-loader .e-text:before, .e-loadholder .m-loader .e-text:after {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-51%, -50%);
-moz-transform: translate(-51%, -50%);
-ms-transform: translate(-51%, -50%);
-o-transform: translate(-51%, -50%);
transform: translate(-51%, -50%);
content: " ";
display: block;
background: #222;
transform-origin: center;
z-index: -1;
}
.e-loadholder .m-loader .e-text:before {
width: 110%;
height: 40px;
-webkit-animation: outerRotate2 3.5s infinite linear;
-moz-animation: outerRotate2 3.5s infinite linear;
-o-animation: outerRotate2 3.5s infinite linear;
animation: outerRotate2 3.5s infinite linear;
}
.e-loadholder .m-loader .e-text:after {
.cube {
width: 40px;
height: 110%;
-webkit-animation: outerRotate1 8s infinite linear;
-moz-animation: outerRotate1 8s infinite linear;
-o-animation: outerRotate1 8s infinite linear;
animation: outerRotate1 8s infinite linear;
height: 40px;
position: relative;
transform-style: preserve-3d;
transform: translateZ(20px);
left: 80px;
top: 80px;
}
.cube.is-spinning {
animation: spinCube 5s infinite ease-in-out;
}
@keyframes spinCube {
0% { transform: translateZ(20px) rotateX( 0deg) rotateY( 0deg) rotateZ( 0deg); }
100% { transform: translateZ(20px) rotateX(360deg) rotateY( 0deg) rotateZ(360deg); }
}
.face {
position: absolute;
width: 40px;
height: 40px;
padding: 0;
background: hsla(240, 100%, 0%, 0.4);
border: 1px solid hsla(240, 100%, 70%, 0.6);
}
.front { transform: rotateY( 0deg) translateZ(20px); }
.right { transform: rotateY( 90deg) translateZ(20px); }
.back { transform: rotateY(180deg) translateZ(20px); }
.left { transform: rotateY(-90deg) translateZ(20px); }
.top { transform: rotateX( 90deg) translateZ(20px); }
.bottom { transform: rotateX(-90deg) translateZ(20px); }
.cube.is-backface-hidden .face {
backface-visibility: hidden;
}
.mino0 { left: -40px; top: -20px; }
.mino1 { left: 0px; top: -20px; }
.mino2 { left: 40px; top: -20px; }
.mino3 { left: 0px; top: 20px; }

View File

@ -20,14 +20,38 @@
</head>
<body>
<div id="loaddingCircle">
<div class="e-loadholder">
<div class="m-loader">
<span class="e-text">
<div id="loadingDiv">
<div class="scene">
<div class="cube is-spinning">
<div class="mino0 front face"></div>
<div class="mino0 back face"></div>
<div class="mino0 right face"></div>
<div class="mino0 left face"></div>
<div class="mino0 top face"></div>
<div class="mino0 bottom face"></div>
<div class="mino1 front face"></div>
<div class="mino1 back face"></div>
<div class="mino1 right face"></div>
<div class="mino1 left face"></div>
<div class="mino1 top face"></div>
<div class="mino1 bottom face"></div>
<div class="mino2 front face"></div>
<div class="mino2 back face"></div>
<div class="mino2 right face"></div>
<div class="mino2 left face"></div>
<div class="mino2 top face"></div>
<div class="mino2 bottom face"></div>
<div class="mino3 front face"></div>
<div class="mino3 back face"></div>
<div class="mino3 right face"></div>
<div class="mino3 left face"></div>
<div class="mino3 top face"></div>
<div class="mino3 bottom face"></div>
</div>
</div>
<div>
<div>Chargement</div>
<div id="loadingPercent">0%</div>
</span>
</div>
</div>
</div>
<span id="messagesSpan"></span>

View File

@ -27,7 +27,7 @@ let friendyKeyRenamer = new Proxy({
}
})
class Settings {
export default class Settings {
constructor() {
this.startLevel = 1
@ -80,6 +80,3 @@ class Settings {
this.theme = "Plasma"
}
}
export { Settings }

View File

@ -1,8 +1,7 @@
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
class TetraControls extends OrbitControls {
export default class TetraControls extends OrbitControls {
constructor(camera, domElement) {
super(camera, domElement)
this.autoRotate
@ -20,5 +19,3 @@ class TetraControls extends OrbitControls {
this.addEventListener("end", () => domElement.style.cursor = "grab")
}
}
export { TetraControls }

View File

@ -33,6 +33,4 @@ class Scheduler {
}
const scheduler = new Scheduler()
export { scheduler }
export const scheduler = new Scheduler()

108
load.html Normal file
View File

@ -0,0 +1,108 @@
<!DOCTYPE html>
<html>
<head>
<style>
body { background-color: black; }
.loading {
box-sizing: border-box;
font-family: "Open Sans", sans-serif;
font-size: 1.4rem;
color: hsla(240, 100%, 70%, 0.6);
text-align: center;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.scene {
width: 200px;
height: 200px;
margin: auto;
perspective: 200px;
}
.cube {
width: 40px;
height: 40px;
position: relative;
transform-style: preserve-3d;
transform: translateZ(20px);
left: 80px;
top: 80px;
}
.cube.is-spinning {
animation: spinCube 5s infinite ease-in-out;
}
@keyframes spinCube {
0% { transform: translateZ(20px) rotateX( 0deg) rotateY( 0deg) rotateZ( 0deg); }
100% { transform: translateZ(20px) rotateX(360deg) rotateY( 0deg) rotateZ(360deg); }
}
.face {
position: absolute;
width: 40px;
height: 40px;
padding: 0;
background: hsla(240, 100%, 0%, 0.4);
border: 1px solid hsla(240, 100%, 70%, 0.6);
}
.front { transform: rotateY( 0deg) translateZ(20px); }
.right { transform: rotateY( 90deg) translateZ(20px); }
.back { transform: rotateY(180deg) translateZ(20px); }
.left { transform: rotateY(-90deg) translateZ(20px); }
.top { transform: rotateX( 90deg) translateZ(20px); }
.bottom { transform: rotateX(-90deg) translateZ(20px); }
.cube.is-backface-hidden .face {
backface-visibility: hidden;
}
.mino0 { left: -40px; top: -20px; }
.mino1 { left: 0px; top: -20px; }
.mino2 { left: 40px; top: -20px; }
.mino3 { left: 0px; top: 20px; }
</style>
</head>
<body>
<div class="loading">
<div class="scene">
<div class="cube is-spinning">
<div class="mino0 front face"></div>
<div class="mino0 back face"></div>
<div class="mino0 right face"></div>
<div class="mino0 left face"></div>
<div class="mino0 top face"></div>
<div class="mino0 bottom face"></div>
<div class="mino1 front face"></div>
<div class="mino1 back face"></div>
<div class="mino1 right face"></div>
<div class="mino1 left face"></div>
<div class="mino1 top face"></div>
<div class="mino1 bottom face"></div>
<div class="mino2 front face"></div>
<div class="mino2 back face"></div>
<div class="mino2 right face"></div>
<div class="mino2 left face"></div>
<div class="mino2 top face"></div>
<div class="mino2 bottom face"></div>
<div class="mino3 front face"></div>
<div class="mino3 back face"></div>
<div class="mino3 right face"></div>
<div class="mino3 left face"></div>
<div class="mino3 top face"></div>
<div class="mino3 bottom face"></div>
</div>
</div>
<div>
<div>Chargement</div>
<div id="loadingPercent">0%</div>
</div>
</div>
</body>
</html>