53 Commits

Author SHA1 Message Date
36112f1ec8 less drop-shadows 2026-03-04 00:30:50 +01:00
b28b44507b white border 2026-03-03 14:52:31 +01:00
24b0e72eab more bounce 2026-03-03 14:51:59 +01:00
ab105bf485 settings reorder 2026-03-01 21:29:21 +01:00
ea8dbff564 pseudo 3d 2026-03-01 21:29:10 +01:00
9a2989616a top side 2026-03-01 15:32:02 +01:00
d6006e657f ghost 2026-03-01 11:48:18 +01:00
ce758c1e92 update cleared line animation 2026-02-28 10:31:24 +01:00
8a0590f1b3 hsl 2026-02-23 23:21:11 +01:00
70caed8fb8 ridge 2026-02-23 18:15:31 +01:00
b6eeae15b9 pop is the new classic 2026-02-23 17:11:34 +01:00
45c0e090e5 less brilliant 2026-02-21 11:52:26 +01:00
73ec2015ba more more brilliant 2026-02-21 02:23:48 +01:00
91e1ea9d3a more brilliant 2026-02-20 21:02:52 +01:00
798ac21372 pause on fullscreen exit 2026-02-20 09:05:23 +01:00
2820c42ba8 cover 2026-02-16 00:20:54 +01:00
8e043b9e8c background position 2026-02-16 00:18:31 +01:00
136ea4156f fix hold glich; prefered theme pop 2026-02-16 00:07:32 +01:00
c01c6dcf58 new theme 2026-02-01 16:30:01 +01:00
25826565af bootstrap checkbox 2026-01-27 11:04:09 +01:00
56b906723c fullscreen checkbox 2026-01-27 08:56:28 +01:00
20b96da34b fix border 2026-01-23 08:22:58 +01:00
bd195f7da6 softer blink 2026-01-23 08:21:15 +01:00
06b444c37e more transparency 2026-01-23 00:56:55 +01:00
71945a7ade clearPiece 2026-01-23 00:54:17 +01:00
0956e3d6e0 don't close game over modal 2026-01-21 20:45:44 +01:00
cc4c477a10 classic locked-animation box-shadow 2026-01-21 20:36:47 +01:00
e196d931ca speed up css 2026-01-18 05:29:07 +01:00
a4117b782a locked-animation 2026-01-16 21:16:05 +01:00
3e3fd6d7f4 tweaks 2026-01-16 03:38:58 +01:00
50a4536994 100px 2026-01-16 03:27:09 +01:00
a4e210526f 3D cleared line animation 2026-01-16 03:23:26 +01:00
cb49d42266 3D cleared line animation 2026-01-16 02:31:13 +01:00
90b1251ebf restart hard dropped animation 2026-01-16 01:31:15 +01:00
26a4d113b5 no cleared line animation 2026-01-15 17:55:24 +01:00
b3d012f489 3d trail 2026-01-15 16:51:02 +01:00
021d67b877 less grab 2026-01-15 16:15:51 +01:00
3af40de841 scroll backward 2026-01-15 13:39:47 +01:00
2d700f1927 fix border translation 2026-01-12 08:45:19 +01:00
280ff0ef9f more light 2026-01-12 01:21:44 +01:00
8e5b45bf6f fix border translation 2026-01-12 01:19:21 +01:00
18977dfd1b more light 2026-01-12 00:23:34 +01:00
334e0e0178 tweaks 2026-01-11 22:38:06 +01:00
02a24ec1f2 border 2026-01-11 22:26:58 +01:00
0cb9fd4c27 more shadows 2026-01-11 18:07:00 +01:00
e21f9c7dfa text-shadow 2026-01-11 17:56:25 +01:00
baf5672de8 hold and next light 2026-01-11 00:55:54 +01:00
9ed62d1e79 hold and next light 2026-01-11 00:51:01 +01:00
2a5ce8faab more text-shadow 2026-01-10 03:49:30 +01:00
4f7d44de4b text-shadow 2026-01-10 03:28:11 +01:00
44e048624a top light 2026-01-10 02:30:12 +01:00
d7fa6c4fe5 Merge branch 'master' of https://git.malingrey.fr/adrien/quatuor 2026-01-10 02:18:05 +01:00
b5ece6f892 stats 2026-01-10 02:15:57 +01:00
11 changed files with 266 additions and 186 deletions

View File

@@ -1,123 +1,119 @@
.minoes-table {
filter:
drop-shadow(-1px -1px 0 white)
drop-shadow( 1px 1px 0 white);
}
.minoes-table tr {
z-index: calc(100 - var(--row));
position: sticky;
}
tr.matrix td:not(.mino) {
border-left: none;
border-bottom: none;
border-right: 1px solid #30303003;
border-top: 1px solid #30303003;
}
.mino { .mino {
background: radial-gradient( --color: hsl(var(--hue), var(--saturation), 40%);
ellipse 140% 66% at 122% 88%, --light: hsl(var(--hue), calc(0.66 * var(--saturation)), 84%);
var(--background-color) 100%, --top: hsl(var(--hue), calc(0.6 * var(--saturation)), 68%);
var(--frontier-color) 105%, background-color: var(--color);
var(--light-color) 130% background-image:
radial-gradient(
ellipse 22% 8% at 25% 22%,
#ffffff66,
#ffffff33 40%,
transparent 70%
),
radial-gradient(
ellipse 140% 85% at 50% -15%,
var(--light) 0%,
#ffffff77 40%,
#00000005 55%
),
radial-gradient(
ellipse 120% 220% at 50% 140%,
var(--light) 0%,
var(--color) 55%,
#00000066 95%
); );
border: 4px solid; border: 4px ridge var(--color);
padding: 0; border-top-color: var(--light);
opacity: 100%; border-radius: 3px;
border-radius: 1px;
box-shadow: 2px 2px 4px #000a;
}
.I.mino {
--background-color : #00d6fb;
--frontier-color : #43e7fd;
--light-color : #afeff9;
border-top-color : #7cf2fd;
border-left-color : #2ed5e5;
border-right-color : #01b8ca;
border-bottom-color: #00a4b0;
}
.J.mino {
--background-color : #2E00FB;
--frontier-color : #7054fb;
--light-color : #b8b4ff;
border-top-color : #4985fd;
border-left-color : #2f36ea;
border-right-color : #0006ca;
border-bottom-color: #00009d;
}
.L.mino {
--background-color : #FF7900;
--frontier-color : #fe9551;
--light-color : #fdd0b7;
border-top-color : #fd9f6b;
border-left-color : #e76d28;
border-right-color : #e74f00;
border-bottom-color: #c54800;
}
.O.mino {
--background-color : #FeCB00;
--frontier-color : #fce15c;
--light-color : #ffedac;;
border-top-color : #ffe364;
border-left-color : #e7ba23;
border-right-color : #e3a707;
border-bottom-color: #ca9501;
}
.S.mino {
--background-color : #67EE12;
--frontier-color : #93f85a;
--light-color : #C8FBA8;
border-top-color : #a4fc6d;
border-left-color : #5ee82b;
border-right-color : #35db00;
border-bottom-color: #1cbc02;
}
.T.mino {
--background-color : #B000FE;
--frontier-color : #c541fc;
--light-color : #edb2ff;
border-top-color : #d380ff;
border-left-color : #b42deb;
border-right-color : #8000cd;
border-bottom-color: #6e019a;
}
.Z.mino {
--background-color : #ed2939;
--frontier-color : #fe6483;
--light-color : #ffb8c5;
border-top-color : #fd718d;
border-left-color : #e62250;
border-right-color : #e20332;
border-bottom-color: #ad1936;
}
.ghost.mino {
margin: 1px;
opacity: 30%;
filter: brightness(300%) saturate(10%) blur(1px);
}
.moving.mino {
filter: saturate(80%) brightness(150%);
}
.locking.mino {
filter: saturate(50%) brightness(200%);
box-shadow: box-shadow:
-1px -1px 4px #FFF2, inset 2px 0 4px rgba(0,0,0,.06),
-1px 1px 4px #FFF2, inset -2px 0 4px rgba(0,0,0,.12),
1px -1px 4px #FFF2, 0 -4px 0 var(--top);
1px 1px 4px #FFF2; filter: saturate(1.1) contrast(1.05);
} }
.disabled.mino { .I {
filter: brightness(50%) contrast(80%); --hue: 193;
opacity: 70%; --saturation: 100%;
} }
@keyframes locked-animation { .J {
--hue: 215;
--saturation: 100%;
}
.L {
--hue: 25;
--saturation: 100%;
}
.O {
--hue: 42;
--saturation: 100%;
}
.S {
--hue: 95;
--saturation: 100%;
}
.T {
--hue: 300;
--saturation: 56%;
}
.Z {
--hue: 357;
--saturation: 84%;
}
.ghost {
border: 3px solid #fff1;
padding: 2px;
background-color: #fff1;
background-clip: content-box;
background-image: none;
box-shadow: none;
}
@keyframes trail-animation {
from { from {
filter: saturate(50%) brightness(400%); background-color: #ceffff10;
box-shadow: }
-1px -1px 4px #FFF2, to {
-1px 1px 4px #FFF2, background-color: transparent;
1px -1px 4px #FFF2,
1px 1px 4px #FFF2;
} }
} }
.locked.mino { @keyframes cleared-line-animation {
animation: locked-animation; from {
animation-duration: 0.2s; background-color: #fff6;
filter: saturate(50%) brightness(300%);
box-shadow: 0 0 0 #adb5bd66, 0 0 0 #adb5bd66;
}
60% {
box-shadow: -60px 0 2px #adb5bd33, 60px 0 2px #adb5bd33;
}
to {
background-color: transparent;
box-shadow: -100px 0 5px transparent, 100px 0 5px transparent;
}
} }

View File

@@ -1,5 +1,5 @@
:root { :root {
--cell-side: 24px; --cell-side: 25px;
--rX: -15; --rX: -15;
--rY: 0; --rY: 0;
--tZ: 25px; --tZ: 25px;
@@ -67,7 +67,7 @@ td#timeCell {
@keyframes hard-dropped-table-animation { @keyframes hard-dropped-table-animation {
25% { 25% {
transform: translateY(2px); transform: translateY(3px);
} }
} }
.hard-dropped-table-animation { .hard-dropped-table-animation {
@@ -89,30 +89,45 @@ td {
overflow: hidden; overflow: hidden;
width: var(--cell-side); width: var(--cell-side);
height: var(--cell-side); height: var(--cell-side);
box-sizing: border-box;
} }
@keyframes trail-animation { @keyframes trail-animation {
from { from {
background-color: #ceffff40; background-color: #ceffff40;
filter: saturate(50%) brightness(300%);
} }
to { to {
background-color: transparent; background-color: transparent;
} }
} }
@keyframes locked-animation {
from {
filter: saturate(50%) brightness(400%);
}
}
.locked.mino {
animation: locked-animation;
animation-duration: 0.2s;
}
td.trail-animation { td.trail-animation {
animation: trail-animation ease-out .3s; animation: trail-animation ease-out .3s;
} }
@keyframes cleared-line-animation { @keyframes cleared-line-animation {
from { from {
background-color: #ceffff66; background-color: white;
filter: saturate(50%) brightness(300%); filter: saturate(50%) brightness(300%);
box-shadow: -200px 0 5px white, 200px 0 5px white; box-shadow: 0 0 0 #adb5bd, 0 0 0 #adb5bd;
}
60% {
box-shadow: -60px 0 2px #adb5bd66, 60px 0 2px #adb5bd66;
} }
to { to {
background-color: transparent; background-color: transparent;
box-shadow: -100px 0 5px transparent, 100px 0 5px transparent;
} }
} }

View File

@@ -78,6 +78,7 @@ tr.matrix td:not(.mino) {
.disabled.mino { .disabled.mino {
opacity: 60%; opacity: 60%;
position: relative;
} }
.disabled.mino:before { .disabled.mino:before {
@@ -92,8 +93,3 @@ tr.matrix td:not(.mino) {
border-color: white; border-color: white;
} }
} }
.locked.mino {
animation: locked-animation;
animation-duration: 0.2s;
}

View File

@@ -146,14 +146,3 @@ td#timeCell {
filter: brightness(50%) contrast(80%); filter: brightness(50%) contrast(80%);
opacity: 70%; opacity: 70%;
} }
@keyframes locked-animation {
from {
filter: saturate(50%) brightness(400%);
}
}
.locked.mino {
animation: locked-animation;
animation-duration: 0.2s;
}

View File

@@ -79,7 +79,7 @@
text-shadow: -2px -2px #808302, -2px 2px #808302, 2px -2px #808302, 2px 2px #808302; text-shadow: -2px -2px #808302, -2px 2px #808302, 2px -2px #808302, 2px 2px #808302;
} }
td { .minoes-table td {
border: 0 !important; border: 0 !important;
} }
@@ -118,7 +118,7 @@ td {
@keyframes blinker { @keyframes blinker {
35% { 35% {
opacity: 0; opacity: 50%;
} }
} }

View File

@@ -12,7 +12,9 @@ body {
#141418 65%, #141418 65%,
#0f0f12 74%, #0f0f12 74%,
#0a0c0d 100%); #0a0c0d 100%);
background-repeat: round; background-repeat: space;
background-position: center;
background-size: cover;
} }
#sceneDiv { #sceneDiv {
@@ -61,14 +63,20 @@ body {
border: none; border: none;
} }
.card,
.card-header {
text-shadow:
calc(-0.3px * var(--rY)) calc(0.4px * var(--rX)) 5px #0008;
}
#holdTable .mino { #holdTable .mino {
--row: 10; --row: 7;
--column: -5; --column: -5;
} }
#nextTable .mino { #nextTable .mino {
--row: 15; --row: 15;
--column: 20; --column: 15;
} }
.minoes-table th, .minoes-table th,
@@ -95,13 +103,11 @@ body {
tr.matrix td:not(.mino) { tr.matrix td:not(.mino) {
border: 0; border: 0;
will-change: transform;
transform: translateZ(0);
} }
.minoes-table td { .minoes-table td {
width: var(--cell-side) !important; width: var(--cell-side) !important;
height: var(--cell-side); height: var(--cell-side) !important;
overflow: visible; overflow: visible;
} }
@@ -109,26 +115,22 @@ tr.matrix td:not(.mino) {
.minoes-table .mino::before, .minoes-table .mino::before,
.minoes-table .mino + :not(.mino)::before, .minoes-table .mino + :not(.mino)::before,
.minoes-table .mino::after { .minoes-table .mino::after {
--highlight: hsla(60deg, 100%, 95%, 0.3);
--shadow: hsla(0deg, 0%, 0%, 0.15);
--light-x: calc(-0.5 - var(--rY) / 30 - var(--column) / 10 + 1); --light-x: calc(-0.5 - var(--rY) / 30 - var(--column) / 10 + 1);
--light-y: calc(-0.5 + var(--rX) / 20 - var(--row) / 6 + 4); --light-y: calc(-0.5 + var(--rX) / 20 - var(--row) / 6 + 4);
--light-z: 1; --center-color: hsla(var(--h), var(--s), calc(var(--l) * var(--light) * 1.1), var(--a));
--center-x: calc(35% + var(--light-x) * 10%); --edge-color: hsla(var(--h), var(--s), calc(var(--l) * (var(--light) * 0.9)), var(--a));
--center-y: calc(35% + var(--light-y) * 10%); background: var(--center-color);
--center-color: hsla(var(--h), var(--s), calc(var(--l) * var(--light)), var(--a));
--edge-color: hsla(var(--h), var(--s), calc(var(--l) * (var(--light) * 0.8)), var(--a));
background: radial-gradient(
circle at var(--center-x) var(--center-y),
var(--center-color) 0%,
var(--edge-color) 100%
);
border-radius: 2px; border-radius: 2px;
border: 2px outset var(--center-color);
} }
.minoes-table .mino::before, .minoes-table .mino::before,
.minoes-table .mino + :not(.mino)::before, .minoes-table .mino + :not(.mino)::before,
.minoes-table .mino::after { .minoes-table .mino::after,
td.trail-animation::before,
td.trail-animation::after,
tr.cleared-line-animation td::before,
tr.cleared-line-animation td::after {
content: ''; content: '';
position: absolute; position: absolute;
top: 0; top: 0;
@@ -139,30 +141,42 @@ tr.matrix td:not(.mino) {
} }
/* Front face */ /* Front face */
.minoes-table .mino { .minoes-table .mino,
td.trail-animation {
--light: calc( --light: calc(
1 1
+ (var(--light-y) * 0.3) + (var(--light-y) * 0.3)
+ (var(--light-x) * 0.2) + (var(--light-x) * 0.2)
); );
--center-x: calc(35% + var(--light-x) * 10%);
--center-y: calc(35% + var(--light-y) * 10%);
background: radial-gradient(
circle at var(--center-x) var(--center-y),
var(--center-color) 15%,
var(--edge-color) 100%
);
box-shadow: 0 0 7px hsla(var(--h), var(--s), calc(var(--l) * var(--light) * 1.3), 20%);
} }
/* Left face */ /* Left face */
.minoes-table .mino::before, .minoes-table .mino::before,
td.trail-animation::before,
tr.cleared-line-animation td::before,
.left .minoes-table .mino + .mino::before { .left .minoes-table .mino + .mino::before {
--light: calc( --light: calc(
1.1 1.1
+ (var(--light-x) * -0.2) + (var(--light-x) * -0.2)
+ (var(--light-y) * 0.15) + (var(--light-y) * 0.15)
); );
transform: translateZ(calc(-1 * var(--cell-side))) rotateY(-90deg); transform: translate3d(-1.5px, -1.5px, calc(-1 * var(--cell-side))) rotateY(-90deg);
transform-origin: left; transform-origin: left;
} }
/* Right face */ /* Right face */
.right .minoes-table .mino::before, .right .minoes-table .mino + .mino::before,
.minoes-table .mino + :not(.mino)::before, .minoes-table .mino + :not(.mino)::before,
.right .minoes-table .mino:last-child::before { .right td.trail-animation::before,
.right tr.cleared-line-animation td::before {
--light: calc( --light: calc(
0.85 0.85
+ (var(--light-x) * -0.2) + (var(--light-x) * -0.2)
@@ -171,27 +185,31 @@ tr.matrix td:not(.mino) {
--center-x: calc(65% + var(--light-x) * 10%); --center-x: calc(65% + var(--light-x) * 10%);
--center-y: calc(35% + var(--light-y) * 10%); --center-y: calc(35% + var(--light-y) * 10%);
filter: saturate(0.95); filter: saturate(0.95);
transform: translateZ(calc(-1 * var(--cell-side))) rotateY(-90deg); transform: translate3d(0, 0, calc(-1 * var(--cell-side))) rotateY(-90deg);
transform-origin: left; transform-origin: left;
} }
.right .minoes-table .mino:last-child::before { .right .minoes-table .mino:last-child::before {
transform: translateZ(calc(-1 * var(--cell-side))) rotateY(90deg) !important; transform: translate3d(-1.5px, -1.5px, calc(-1 * var(--cell-side))) rotateY(90deg) !important;
transform-origin: right !important; transform-origin: right !important;
} }
/* Top face */ /* Top face */
.minoes-table .mino::after { .minoes-table .mino::after,
td.trail-animation::after,
tr.cleared-line-animation td::after {
--light: calc( --light: calc(
1.1 1.5
+ (var(--light-y) * -0.3) + (var(--light-y) * 0.2)
); );
transform: translateZ(calc(-1 * var(--cell-side))) rotateX(90deg); transform: translate3d(-1.5px, -1.5px, calc(-1 * var(--cell-side))) rotateX(90deg);
transform-origin: top; transform-origin: top;
} }
/* Bottom face */ /* Bottom face */
.bottom .minoes-table .mino::after { .bottom .minoes-table .mino::after,
.bottom td.trail-animation::after,
.bottom tr.cleared-line-animation td::after {
--light: calc( --light: calc(
1.1 1.1
+ (var(--light-y) * -0.3) + (var(--light-y) * -0.3)
@@ -199,24 +217,22 @@ tr.matrix td:not(.mino) {
--center-x: calc(65% + var(--light-x) * 10%); --center-x: calc(65% + var(--light-x) * 10%);
--center-y: calc(65% + var(--light-y) * 10%); --center-y: calc(65% + var(--light-y) * 10%);
filter: saturate(0.95); filter: saturate(0.95);
transform: translateZ(calc(-1 * var(--cell-side))) rotateX(-90deg); transform: translate3d(-1.5px, -1.5px, calc(-1 * var(--cell-side))) rotateX(-90deg);
transform-origin: bottom; transform-origin: bottom;
} }
.J.mino, .J.mino + :not(.mino) { --h: 210deg; --s: 78%; --l: 52%; --a: 0.85; } .J.mino, .J.mino + :not(.mino) { --h: 210deg; --s: 78%; --l: 52%; --a: 0.75; }
.L.mino, .L.mino + :not(.mino) { --h: 28deg; --s: 85%; --l: 52%; --a: 0.85; } .L.mino, .L.mino + :not(.mino) { --h: 28deg; --s: 85%; --l: 52%; --a: 0.75; }
.O.mino, .O.mino + :not(.mino) { --h: 48deg; --s: 88%; --l: 52%; --a: 0.85; } .O.mino, .O.mino + :not(.mino) { --h: 48deg; --s: 88%; --l: 52%; --a: 0.75; }
.I.mino, .I.mino + :not(.mino) { --h: 200deg; --s: 70%; --l: 52%; --a: 0.85; } .I.mino, .I.mino + :not(.mino) { --h: 200deg; --s: 70%; --l: 52%; --a: 0.75; }
.S.mino, .S.mino + :not(.mino) { --h: 118deg; --s: 45%; --l: 52%; --a: 0.85; } .S.mino, .S.mino + :not(.mino) { --h: 118deg; --s: 45%; --l: 52%; --a: 0.75; }
.T.mino, .T.mino + :not(.mino) { --h: 293deg; --s: 48%; --l: 52%; --a: 0.85; } .T.mino, .T.mino + :not(.mino) { --h: 293deg; --s: 48%; --l: 52%; --a: 0.75; }
.Z.mino, .Z.mino + :not(.mino) { --h: 352deg; --s: 75%; --l: 52%; --a: 0.85; } .Z.mino, .Z.mino + :not(.mino) { --h: 352deg; --s: 75%; --l: 52%; --a: 0.75; }
.ghost.mino, .ghost.mino + :not(.mino) { --h: 0deg; --s: 0%; --l: 55%; --a: 0.40; } .ghost.mino, .ghost.mino + :not(.mino) { --h: 0deg; --s: 0%; --l: 55%; --a: 0.40; }
.locking.mino, .locking.mino + :not(.mino) { --h: 0deg; --s: 0%; --l: 92%; --a: 0.72; } .locking.mino, .locking.mino + :not(.mino) { --h: 0deg; --s: 0%; --l: 92%; --a: 0.72; }
.disabled.mino, .disabled.mino + :not(.mino) { --h: 0deg; --s: 0%; --l: 45%; --a: 0.72; } .disabled.mino, .disabled.mino + :not(.mino) { --h: 0deg; --s: 0%; --l: 45%; --a: 0.72; }
#holdTable .J + :not(.mino), #holdTable .J + :not(.mino),
#holdTable .L + :not(.mino), #holdTable .L + :not(.mino),
#holdTable .S + :not(.mino), #holdTable .S + :not(.mino),
@@ -230,17 +246,51 @@ tr.matrix td:not(.mino) {
transform: translateX(50%); transform: translateX(50%);
} }
@keyframes cleared-line-animation { @keyframes trail-animation {
from { from {
background-color: #ceffff66; background-color: hsla(180, 100%, 100%, 0.1);
box-shadow: -200px 0 5px white, 200px 0 5px white; border-color: hsla(180, 100%, 100%, 0.1);
} }
to { to {
background-color: transparent; background-color: transparent;
border-color: transparent;
} }
} }
td.trail-animation::before,
td.trail-animation::after {
animation: trail-animation ease-out .3s;
}
@keyframes locked-animation {
from {
--h: 0deg; --s: 0%; --l: 100%; --a: 1;
box-shadow: 0 0 10px hsla(180, 100%, 100%, 0.2);
}
}
.locked.mino::before,
.locked.mino::after {
animation: locked-animation;
animation-duration: .2s;
}
@keyframes cleared-line-animation {
from {
background-color: white !important;
box-shadow: 0 0 0 white;
}
to {
background-color: #fff0;
box-shadow: 0 0 100px transparent;
}
}
tr.cleared-line-animation td::before,
tr.cleared-line-animation td::after {
animation: cleared-line-animation ease-out .3s;
}
@keyframes show-level-animation { @keyframes show-level-animation {
from { from {
opacity: 1; opacity: 1;

View File

@@ -36,37 +36,37 @@ body[data-bs-theme="dark"] {
} }
.I { .I {
--color: #00eaf888; --color: #00eaf866;
--border: #00eaf5; --border: #00eaf5;
} }
.J { .J {
--color: #00a9f788; --color: #00a9f766;
--border: #00a9f7; --border: #00a9f7;
} }
.L { .L {
--color: #f9b60088; --color: #f9b60066;
--border: #f9b600; --border: #f9b600;
} }
.O { .O {
--color: #e3e04988; --color: #e3e04966;
--border: #e3e049; --border: #e3e049;
} }
.S { .S {
--color: #7bd59e88; --color: #7bd59e66;
--border: #7bd59e; --border: #7bd59e;
} }
.T { .T {
--color: #d136e288; --color: #d136e266;
--border: #d136e2; --border: #d136e2;
} }
.Z { .Z {
--color: #E67D8688; --color: #E67D8666;
--border: #E67D86; --border: #E67D86;
} }

View File

@@ -60,7 +60,7 @@
<div class="col-4"><input name="pause" id="pauseInput" type="text" class="form-control text-center" value="Échap." onfocus="changeKey(this)" placeholder="Touche ?" title="Modifier la touche" required></div> <div class="col-4"><input name="pause" id="pauseInput" type="text" class="form-control text-center" value="Échap." onfocus="changeKey(this)" placeholder="Touche ?" title="Modifier la touche" required></div>
<label for="pauseInput" title="Pause" class="col-2 col-form-label d-flex align-items-center justify-content-center"><i class="bi bi-pause"></i></label> <label for="pauseInput" title="Pause" class="col-2 col-form-label d-flex align-items-center justify-content-center"><i class="bi bi-pause"></i></label>
</fieldset> </fieldset>
<fieldset id="autorepeatFieldset" class="row g-2 mb-3 align-items-center text-center"><legend class="text-start">Répétition automatique</legend> <fieldset id="autorepeatFieldset" class="row g-2 mb-3 align-items-center text-center"><!--<legend class="text-start">Répétition automatique</legend>-->
<label for="arrInput" class="col-2 col-form-label"><abbr title="Automatic Repeat Rate : période de répétition de l'action">ARR</abbr></label> <label for="arrInput" class="col-2 col-form-label"><abbr title="Automatic Repeat Rate : période de répétition de l'action">ARR</abbr></label>
<div class="col-4"><div class="input-group"><input name="arr" id="arrInput" type="number" class="form-control text-center" value="50" min="2" max="200" step="1"><div class="input-group-text">ms</div></div></div> <div class="col-4"><div class="input-group"><input name="arr" id="arrInput" type="number" class="form-control text-center" value="50" min="2" max="200" step="1"><div class="input-group-text">ms</div></div></div>
<div class="col-4"><div class="input-group"><input name="das" id="dasInput" type="number" class="form-control text-center" value="300" min="100" max="500" step="5"><div class="input-group-text">ms</div></div></div> <div class="col-4"><div class="input-group"><input name="das" id="dasInput" type="number" class="form-control text-center" value="300" min="100" max="500" step="5"><div class="input-group-text">ms</div></div></div>
@@ -77,8 +77,15 @@
<option value="css/opera.css">Opéra</option> <option value="css/opera.css">Opéra</option>
<option value="css/stereo.css">Stéréo</option> <option value="css/stereo.css">Stéréo</option>
</select></div> </select></div>
<div class="col-4 d-flex align-items-baseline"><input name="sfxVolumeRange" id="sfxVolumeRange" class="form-range" type="range" min="0" max="1" step="any" value="0.7"></div> <div class="col-4">
<div class="form-check form-switch text-start">
<input id="fullscreenCheckbox" type="checkbox" role="switch" class="form-check-input" tabindex="0">
<label for="fullscreenCheckbox" class="form-check-label">Plein écran</label>
</div>
</div>
<div class="col-2"></div>
<label for="sfxVolumeRange" class="col-2 col-form-label">Volume</label> <label for="sfxVolumeRange" class="col-2 col-form-label">Volume</label>
<div class="col-4 d-flex align-items-baseline"><input name="sfxVolumeRange" id="sfxVolumeRange" class="form-range" type="range" min="0" max="1" step="any" value="0.7"></div>
</fieldset> </fieldset>
<fieldset class="row g-2 mb-3 align-items-center text-center"><legend class="text-start">Partie</legend> <fieldset class="row g-2 mb-3 align-items-center text-center"><legend class="text-start">Partie</legend>
<label for="levelInput" class="col-2 col-form-label text-center">Niveau</label> <label for="levelInput" class="col-2 col-form-label text-center">Niveau</label>
@@ -186,21 +193,21 @@
</div> </div>
<div class="modal fade" id="statsModal" tabindex="-1"> <div class="modal fade" id="statsModal" data-bs-backdrop="static" tabindex="-1">
<div class="modal-dialog modal-dialog-centered"> <div class="modal-dialog modal-dialog-centered">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h2 class="modal-title w-100 text-center">Fin</h2> <h2 class="modal-title w-100 text-center">Fin</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button> <!-- <button type="button" class="btn-close" data-bs-dismiss="modal"></button> -->
</div> </div>
<div class="modal-body p-0"> <div class="modal-body p-0">
<table class="table mb-0"> <table class="table mb-0">
<tr><th>Score</th> <td id="statsModalScoreCell"></td> <th>Quatuors</th> <td id="statsModalNbQuatuors"></td> </tr> <tr><th>Score</th> <td id="statsModalScoreCell"></td> <th>Quatuors</th> <td id="statsModalNbQuatuors"></td> </tr>
<tr><th>Meilleur score</th><td id="statsModalHighScoreCell"></td> <th>Pirouettes</th> <td id="statsModalNbTSpin"></td></td> </tr> <tr><th>Meilleur score</th><td id="statsModalHighScoreCell"></td> <th>Pirouettes</th> <td id="statsModalNbTSpin"></td></td> </tr>
<tr><th>Temps</th> <td id="statsModalTimeCell"></td> <th>Lignes par minute</th> <td id="statsModaltotalClearedLinesPM"></td></tr> <tr><th>Temps</th> <td id="statsModalTimeCell"></td> <th>Plus long combo</th> <td id="statsModalMaxCombo"></td> </tr>
<tr><th>Niveau</th> <td id="statsModalLevelCell"></td> <th>Plus long combo</th> <td id="statsModalMaxCombo"></td> </tr> <tr><th>Niveau</th> <td id="statsModalLevelCell"></td> <th>Plus long bout à bout</th><td id="statsModalMaxB2B"></td> </tr>
<tr><th>Lignes</th> <td id="statsModaltotalClearedLines"></td><th>Plus long bout à bout</th><td id="statsModalMaxB2B"></td> </tr> <tr><th>Lignes</th> <td id="statsModaltotalClearedLines"></td><th>Lignes par minute</th> <td id="statsModaltotalClearedLinesPM"></td></tr>
</table> </table>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">

View File

@@ -13,9 +13,29 @@ window.onload = function(event) {
selectedStyleSheet.href = stylesheetSelect.value selectedStyleSheet.href = stylesheetSelect.value
favicon = document.querySelector("link[rel~='icon']") favicon = document.querySelector("link[rel~='icon']")
fullscreenCheckbox.onchange = function() {
if (this.checked) {
document.documentElement.requestFullscreen()
} else {
document.exitFullscreen()
}
}
restart() restart()
} }
document.onfullscreenchange = function() {
if (document.fullscreenElement) {
fullscreenCheckbox.checked = true
} else {
fullscreenCheckbox.checked = false
if (playing) pauseSettings()
}
}
document.onfullscreenerror = function() {
fullscreenCheckbox.checked = false
}
function restart() { function restart() {
stats.modal.hide() stats.modal.hide()
holdQueue.init() holdQueue.init()
@@ -123,7 +143,9 @@ let playerActions = {
scheduler.clearTimeout(lockDown) scheduler.clearTimeout(lockDown)
playSound(hardDropSound) playSound(hardDropSound)
while (matrix.piece.move(TRANSLATION.DOWN, ROTATION.NONE, true)) stats.score += 2 while (matrix.piece.move(TRANSLATION.DOWN, ROTATION.NONE, true)) stats.score += 2
matrixCard.classList.add("hard-dropped-table-animation") matrixCard.classList.remove("hard-dropped-table-animation")
matrixCard.offsetHeight;
matrixCard.classList.add("hard-dropped-table-animation") // restart animation
lockDown() lockDown()
return true return true
}, },
@@ -280,7 +302,7 @@ sceneDiv.onmousemove = function(event) {
if (mousedown) { if (mousedown) {
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
rX = (rX0 - event.clientY + clientY0) % 360 rX = (rX0 - 0.5 * (event.clientY - clientY0)) % 360
screenRow.style.setProperty("--rX", rX) screenRow.style.setProperty("--rX", rX)
if (rX >= 0) { if (rX >= 0) {
screenRow.classList.remove("top") screenRow.classList.remove("top")
@@ -289,7 +311,7 @@ sceneDiv.onmousemove = function(event) {
screenRow.classList.add("top") screenRow.classList.add("top")
screenRow.classList.remove("bottom") screenRow.classList.remove("bottom")
} }
rY = (rY0 + event.clientX - clientX0) % 360 rY = (rY0 + 0.5 * (event.clientX - clientX0)) % 360
screenRow.style.setProperty("--rY", rY) screenRow.style.setProperty("--rY", rY)
if (rY <= 0) { if (rY <= 0) {
screenRow.classList.remove("left") screenRow.classList.remove("left")
@@ -309,6 +331,6 @@ sceneDiv.onwheel = function(event) {
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
let tZ = parseInt(getComputedStyle(screenRow).getPropertyValue("--tZ")) let tZ = parseInt(getComputedStyle(screenRow).getPropertyValue("--tZ"))
tZ += event.deltaY tZ -= event.deltaY
screenRow.style.setProperty("--tZ", tZ + "px") screenRow.style.setProperty("--tZ", tZ + "px")
} }

View File

@@ -251,8 +251,12 @@ class Matrix extends MinoesTable {
if (piece.locked) className += " locking" if (piece.locked) className += " locking"
if (piece==this.piece && actionsQueue.length) className += " moving" if (piece==this.piece && actionsQueue.length) className += " moving"
super.drawPiece(piece, className) super.drawPiece(piece, className)
matrix.table.style.setProperty('--piece-column', this.piece.center.x) this.table.style.setProperty('--piece-column', this.piece.center.x)
matrix.table.style.setProperty('--piece-row', this.piece.center.y) this.table.style.setProperty('--piece-row', this.piece.center.y)
}
clearPiece(piece=this.piece, className="") {
super.drawPiece(piece, className)
} }
redraw() { redraw() {
@@ -328,7 +332,7 @@ class Tetromino {
let success = this.canMove(translation, rotation) let success = this.canMove(translation, rotation)
if (success) { if (success) {
scheduler.clearTimeout(lockDown) scheduler.clearTimeout(lockDown)
matrix.drawPiece(this, translation == TRANSLATION.DOWN? "trail-animation" : "") matrix.clearPiece(this, hardDropped? "trail-animation" : "")
this.center = success.center this.center = success.center
if (rotation) this.facing = success.facing if (rotation) this.facing = success.facing
this.lastRotation = rotation this.lastRotation = rotation

View File

@@ -21,6 +21,7 @@ const KEY_NAMES = new Proxy({
} }
}) })
class Settings { class Settings {
constructor() { constructor() {
this.form = settingsForm this.form = settingsForm