Compare commits

..
6 Commits
Author SHA1 Message Date
epickiwi dc2f0013b0 Ajout du shader d'ouverture sur la page d'accueil 2026-08-02 15:31:56 +02:00
epickiwi 36d9ac4230 Ajout de la vidéo 2026-08-02 15:31:56 +02:00
epickiwi 3e7c9475e5 Première version GPU des effets de fond 2026-08-02 15:31:55 +02:00
epickiwi 9f67c28bc0 Ajout du script du lien symbolique 2026-08-02 15:31:55 +02:00
epickiwi 0170db486c Centrage du plan 2026-08-02 15:31:53 +02:00
epickiwi 94907c178e Ajout d'instructions de dev 2026-08-02 15:31:11 +02:00
13 changed files with 644 additions and 158 deletions
+1
View File
@@ -0,0 +1 @@
status/index.html
+2 -4
View File
@@ -160,10 +160,8 @@
</article>
</section>
</section>
<video id="texture" autoplay muted loop src="./assets/video/close.webm" class="closedBackground"></video>
<video id="texture" autoplay muted loop src="./assets/video/open.webm" class="openBackground"></video>
<video id="background" autoplay muted loop src="./assets/video/background.webm" class="openBackground"></video>
<canvas></canvas>
<video data-cute-texture-video class="cute-texture-video" src="/assets/video/background.webm" autoplay muted loop ></video>
<canvas class="cute-texture"></canvas>
</main>
<section class="floatingWindow" id="posterWindow">
+334 -73
View File
@@ -1,87 +1,348 @@
const target = document.querySelector('canvas');
const DEFAULT_VERTEX_SHADER = `
attribute float aVertexIndex;
varying highp vec2 vTextureCoord;
const ctx = target.getContext('2d');
// This vertex shader produces the following, when drawn using indices 0..3:
//
// 1 | 0-----x.....2
// 0 | | s | . ´
// -1 | x_____x´
// -2 | : .´
// -3 | 1´
// +---------------
// -1 0 1 2 3
//
// The axes are clip-space x and y. The region marked s is the visible region.
// The digits in the corners of the right-angled triangle are the vertex
// indices.
//
// The top-left has UV 0,0, the bottom-left has 0,2, and the top-right has 2,0.
// This means that the UV gets interpolated to 1,1 at the bottom-right corner
// of the clip-space rectangle that is at 1,-1 in clip space.
export let lolState = false;
let scale = 0.7;
function analogLikeNoise(){
let tH = target.height;
let tW = target.width;
//console.log('window dimensions :', tH, tW)
const img = ctx.createImageData(tW, tH);
let offset = 0;
let index = 0;
let brightness = 0;
for(let x = 0; x<tW; x++){
const sx = x * scale + offset
for(let y = 0; y<tH; y++){
let lum = Math.random()*161
//img.data[index++] = lum*150/255;
index++
img.data[index++] = lum;
img.data[index++] = lum;
img.data[index++] = 255;
void main() {
vec2 uv = vec2(floor(aVertexIndex / 2.0), floor(mod(aVertexIndex, 2.0))) * 2.0;
gl_Position = vec4(uv * vec2(2.0, -2.0) + vec2(-1.0, 1.0), 0.0, 1.0);
vTextureCoord = uv;
}
}
ctx.putImageData(img, 0, 0);
`
offset ++;
if(offset>1024){
offset = 0;
const FRAGMENT_SHADER_UTILITIES = `
highp float noise1(highp vec2 co){
return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);
}
// Color spaces from https://github.com/tobspr/GLSL-Color-Spaces/blob/master/ColorSpaces.inc.glsl
const highp float HCV_EPSILON = 1e-10;
const highp float HSL_EPSILON = 1e-10;
highp vec3 hue_to_rgb(highp float hue)
{
highp float R = abs(hue * 6.0 - 3.0) - 1.0;
highp float G = 2.0 - abs(hue * 6.0 - 2.0);
highp float B = 2.0 - abs(hue * 6.0 - 4.0);
return clamp(vec3(R,G,B), vec3(0), vec3(1));
}
// Converts from HSL to linear RGB
highp vec3 hsl_to_rgb(highp vec3 hsl)
{
highp vec3 rgb = hue_to_rgb(hsl.x);
highp float C = (1.0 - abs(2.0 * hsl.z - 1.0)) * hsl.y;
return (rgb - 0.5) * C + hsl.z;
}
// Converts a value from linear RGB to HCV (Hue, Chroma, Value)
highp vec3 rgb_to_hcv(highp vec3 rgb)
{
// Based on work by Sam Hocevar and Emil Persson
highp vec4 P = (rgb.g < rgb.b) ? vec4(rgb.bg, -1.0, 2.0/3.0) : vec4(rgb.gb, 0.0, -1.0/3.0);
highp vec4 Q = (rgb.r < P.x) ? vec4(P.xyw, rgb.r) : vec4(rgb.r, P.yzx);
highp float C = Q.x - min(Q.w, Q.y);
highp float H = abs((Q.w - Q.y) / (6.0 * C + HCV_EPSILON) + Q.z);
return vec3(H, C, Q.x);
}
// Converts from linear rgb to HSL
highp vec3 rgb_to_hsl(highp vec3 rgb)
{
highp vec3 HCV = rgb_to_hcv(rgb);
highp float L = HCV.z - HCV.y * 0.5;
highp float S = HCV.y / (1.0 - abs(L * 2.0 - 1.0) + HSL_EPSILON);
return vec3(HCV.x, S, L);
}
highp vec4 hue_rotate(highp vec4 rgb_input, highp float amount) {
highp vec3 hsl = rgb_to_hsl(rgb_input.xyz);
hsl.x = mod(hsl.x+amount,1.0);
return vec4(hsl_to_rgb(hsl), rgb_input.w);
}
highp vec4 grayscale(highp vec4 rgb_input, highp float amount) {
highp vec3 hsl = rgb_to_hsl(rgb_input.xyz);
hsl.y = 1.0 - amount;
return vec4(hsl_to_rgb(hsl), rgb_input.w);
}
`
const FRAGMENT_SHADER_UTILITIES_N_LINES = FRAGMENT_SHADER_UTILITIES.split(/\n/g).length
const DEFAULT_FRAGMENT_SHADER = `
// Some random values computed for each frame
uniform highp vec4 uRandom;
// Size (in logical pixel) of current CuteTexture canvas
uniform lowp vec2 uCanvasSize;
// Number of seconds since canvas was initialized
uniform lowp float uTime;
// Current frame of first video with [data-cute-texture-video] attribute
uniform sampler2D uVideo;
// Size (in pixels) of current video frame in uVideo
uniform lowp vec2 uVideoSize;
// Coordinates of current pixel being computed from [0,0] (top left) to [1,1] (bottom right)
varying highp vec2 vTextureCoord;
void main() {
gl_FragColor = vec4(vTextureCoord.x, vTextureCoord.y, 0.0, 1.0);
}
`
/**
* Initialise un canvas d'arrière plan "CuteTexture" avec les options données
*/
export function initCuteTexture(options){
let shaderSourceOption = options?.shaderSource;
/** @type {HTMLCanvasElement} */
const targetCanvas = document.querySelector("canvas[data-cute-texture]") || document.querySelector("canvas.cute-texture") || document.querySelector("canvas");
if(!targetCanvas)
throw new Error(`Aucun élément <canvas> trouvé sur la page`)
{
let computedStyle = getComputedStyle(targetCanvas)
let elementWidth = parseFloat(computedStyle.width)
let elementHeight = parseFloat(computedStyle.height)
targetCanvas.width = elementWidth
targetCanvas.height = elementHeight
}
const ctx = targetCanvas.getContext("webgl");
if(ctx == null)
throw new Error("WebGL n'ext pas supporté sur votre machine")
let mainShader = initMainShader(ctx, {
shaderSource: shaderSourceOption
})
console.log("Shader CuteTexture initialisé", mainShader)
const initTime = Date.now()
function startRender(){
renderCuteTexture(targetCanvas, mainShader, initTime)
requestAnimationFrame(startRender)
}
startRender()
return {
target: targetCanvas,
initTime,
resize: function(width, height) {
targetCanvas.width = width
targetCanvas.height = height
}
}
}
let time = 0
/**
* @param {WebGLRenderingContext} ctx
*/
function initMainShader(ctx, options){
let fragmentShaderCode = options?.shaderSource;
function scanlines(){
time += 0.05;
let tH = target.height;
let tW = target.width;
//console.log('window dimensions :', tH, tW)
const img = ctx.createImageData(tW, tH);
let index = 0;
const vertexShader = ctx.createShader(ctx.VERTEX_SHADER)
ctx.shaderSource(vertexShader, DEFAULT_VERTEX_SHADER)
ctx.compileShader(vertexShader)
for(let y = 0; y<tH; y++){
for(let x = 0; x<tW; x++){
let lum = (Math.sin(y*2 - time*3.1415) * 44) + 161;
//img.data[index++] = lum;
index++;
img.data[index++] = lum;
//img.data[index++] = lum + Math.random()*32;
index++
img.data[index++] = 255;
}
}
ctx.putImageData(img, 0, 0);
}
export function scanlinesAnimation(){
scanlines();
requestAnimationFrame(scanlinesAnimation);
}
export function noiseAnimation(){
analogLikeNoise();
requestAnimationFrame(noiseAnimation);
}
export function loadCanvas(){
let textureVideo = document.querySelectorAll('main > #texture');
for (let video of textureVideo){
video.style.visibility = 'collapse';
if (!ctx.getShaderParameter(vertexShader, ctx.COMPILE_STATUS)) {
throw new Error(`Le vertex shader n'a pas pu être compilé: ${ctx.getShaderInfoLog(vertexShader)}`)
ctx.deleteShader(vertexShader)
return null
}
let textureCanvas = document.querySelector('main > canvas');
textureCanvas.style.visibility = 'visible';
if(!fragmentShaderCode){
fragmentShaderCode = getDocumentShaderSource(document);
}
//console.log(textureCanvas);
if(!fragmentShaderCode){
fragmentShaderCode = DEFAULT_FRAGMENT_SHADER
}
//console.log(textureVideo)
const fragmentShader = ctx.createShader(ctx.FRAGMENT_SHADER)
ctx.shaderSource(fragmentShader, FRAGMENT_SHADER_UTILITIES+fragmentShaderCode)
ctx.compileShader(fragmentShader)
if (!ctx.getShaderParameter(fragmentShader, ctx.COMPILE_STATUS)) {
let error = ctx.getShaderInfoLog(fragmentShader)
let errorLine = error.match(/\d+:(\d+):/)
if(errorLine) {
let lineNum = parseInt(errorLine[1])
let lineNumeWithoutUtils = lineNum-FRAGMENT_SHADER_UTILITIES_N_LINES;
if(lineNumeWithoutUtils >= 0){
error = `Ligne ${lineNumeWithoutUtils}: ${error}`
}
}
ctx.deleteShader(fragmentShader)
throw new Error(`Le fragment shader n'a pas pu être compilé: ${error}`)
}
const shaderProgram = ctx.createProgram()
ctx.attachShader(shaderProgram, vertexShader)
ctx.attachShader(shaderProgram, fragmentShader)
ctx.linkProgram(shaderProgram)
if (!ctx.getProgramParameter(shaderProgram, ctx.LINK_STATUS)) {
throw new Error(`Le shader n'a pas pu être linké: ${ctx.getProgramInfoLog(shaderProgram)}`)
ctx.deleteShader(vertexShader)
ctx.deleteShader(fragmentShader)
ctx.deleteProgram(shaderProgram)
return null
}
let videoElement, videoTexture = null;
if(ctx.getUniformLocation(shaderProgram, "uVideo") != null){
videoElement = document.querySelector("video[data-cute-texture-video]") || document.querySelector("video");
if(!videoElement){
console.warn("Aucune vidéo avec l'attribut [data-cute-texture-video] n'a été trouvé sur la page");
} else {
videoTexture = ctx.createTexture();
ctx.bindTexture(ctx.TEXTURE_2D, videoTexture)
ctx.texImage2D(
ctx.TEXTURE_2D,
0,
ctx.RGBA,
1, 1,
0,
ctx.RGBA,
ctx.UNSIGNED_BYTE,
new Uint8Array([0, 0, 0, 255])
)
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE);
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE);
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR);
}
}
const vertexIndexBuffer = ctx.createBuffer()
ctx.bindBuffer(ctx.ARRAY_BUFFER, vertexIndexBuffer)
ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array([0, 1, 2]), ctx.STATIC_DRAW)
return {
program: shaderProgram,
vertexShader,
fragmentShader,
videoElement,
videoTexture,
aVertexIndex: ctx.getAttribLocation(shaderProgram, "aVertexIndex"),
uRandom: ctx.getUniformLocation(shaderProgram, "uRandom"),
uCanvasSize: ctx.getUniformLocation(shaderProgram, "uCanvasSize"),
uTime: ctx.getUniformLocation(shaderProgram, "uTime"),
uVideo: ctx.getUniformLocation(shaderProgram, "uVideo"),
uVideoSize: ctx.getUniformLocation(shaderProgram, "uVideoSize"),
vertexIndexBuffer,
}
}
/**
* @param {HTMLCanvasElement} target
* @param {*} mainShader
*/
function renderCuteTexture(target, mainShader, initTime){
let ctx = target.getContext("webgl")
ctx.clearColor(0, 0, 0, 0)
ctx.clearDepth(1.0)
ctx.enable(ctx.DEPTH_TEST)
ctx.depthFunc(ctx.LEQUAL)
ctx.clear(ctx.COLOR_BUFFER_BIT)
ctx.bindBuffer(ctx.ARRAY_BUFFER, mainShader.vertexIndexBuffer)
ctx.vertexAttribPointer(
mainShader.aVertexIndex, // location
1, // pull out 1 value per iteration
ctx.FLOAT, // the data in the buffer is 32bit floats
false, // don't normalize
0, // how many bytes to get from one set of values to the next
0 // how many bytes inside the buffer to start from
)
ctx.enableVertexAttribArray(mainShader.aVertexIndex)
ctx.useProgram(mainShader.program)
if(mainShader.uRandom){
ctx.uniform4f(
mainShader.uRandom,
Math.random(),
Math.random(),
Math.random(),
Math.random()
)
}
if(mainShader.uCanvasSize){
ctx.uniform2f(
mainShader.uCanvasSize,
target.width,
target.height
)
}
if(mainShader.uTime){
ctx.uniform1f(
mainShader.uTime,
(Date.now() - initTime)/1000
)
}
if(mainShader.uVideo){
ctx.activeTexture(ctx.TEXTURE0);
ctx.bindTexture(ctx.TEXTURE_2D, mainShader.videoTexture);
ctx.uniform1i(
mainShader.uVideo,
0
)
}
if(mainShader.uVideo && mainShader.videoElement && mainShader.videoTexture){
ctx.activeTexture(ctx.TEXTURE0);
ctx.bindTexture(ctx.TEXTURE_2D, mainShader.videoTexture);
ctx.texImage2D(
ctx.TEXTURE_2D,
0,
ctx.RGBA,
ctx.RGBA,
ctx.UNSIGNED_BYTE,
mainShader.videoElement,
);
ctx.uniform1i(
mainShader.uVideo,
0
)
}
if(mainShader.uVideoSize && mainShader.videoElement) {
ctx.uniform2f(
mainShader.uVideoSize,
mainShader.videoElement.videoWidth,
mainShader.videoElement.videoHeight
)
}
ctx.drawArrays(ctx.TRIANGLE_STRIP, 0, 3);
}
export function getDocumentShaderSource(doc=document){
return doc.querySelector(`script[type="x-shader/glsl+fragment"]`)?.innerHTML
}
+11 -37
View File
@@ -1,45 +1,19 @@
import { loadEvents } from './events.js'
import { loadStatus } from './status.js'
import { scanlinesAnimation } from './cuteTexture.js'
import { noiseAnimation } from './cuteTexture.js'
import { loadCanvas } from './cuteTexture.js'
// =================================== background texture
loadCanvas();
let backgroundVideo = document.querySelector('main > #background');
let proxyTarget = {};
let proxyHandler = {
};
export let statusProxy = new Proxy(proxyTarget, {
set(obj, prop, value){
if(prop === 'lolStatus'){
if (value){
backgroundVideo.style.visibility = 'visible';
scanlinesAnimation();
return true
} else {
backgroundVideo.style.visibility = 'collapse';
noiseAnimation();
return true
}
}
}
})
statusProxy.lolStatus = false;
//console.log(proxyTarget.lolStatus);
import { initCuteTexture } from './cuteTexture.js'
// ======================================== events & statut d'ouverture
loadEvents();
loadStatus();
loadStatus()
.then((status) => {
console.log("Status actuel du LOL", status);
let cuteTexture = initCuteTexture({
shaderSource: status.shaderSource
});
cuteTexture.target.style.visibility = "visible"
});
// ======================================== floating event window
+7 -9
View File
@@ -1,11 +1,13 @@
import { statusProxy } from './main.js'
import { getDocumentShaderSource } from './cuteTexture.js';
export async function loadStatus(){
let res = await fetch('/status/index.ouvert.html');
let res = await fetch('/status/index.html');
let html_text = await res.text()
let html = new DOMParser().parseFromString(html_text, "text/html");
let shaderSource = getDocumentShaderSource(html);
let target = document.querySelector('#statuSection');
let hiddenBtn = target.querySelector('a');
@@ -15,13 +17,7 @@ export async function loadStatus(){
let status = html.querySelector('#lolStatus');
console.log('current status:', status.innerText);
if (status.innerText.includes('ouvert')){
statusProxy.lolStatus = true;
}else{
statusProxy.lolStatus = false;
}
let isOpen = status.innerText.includes('ouvert');
let icon = html.querySelector('link[rel="icon"]');
let style = html.querySelectorAll('link[rel="stylesheet"]')[0];
@@ -31,4 +27,6 @@ export async function loadStatus(){
document.head.append(style);
target.appendChild(status);
return { open: isOpen, shaderSource };
}
+36
View File
@@ -28,3 +28,39 @@ Ce document sert à échanger et partager des idées et trucs à faire pour cont
* [ ] désactiver la video pour les personnes qui veulent pas d'effets visuels
* [ ] réglages padding section statut
# Démarrer un serveur de developpement
```
python3 -m http.server
```
Et ensuite, le site est disponible sur http://localhost:8000/
## Tester sur son tel
Il faut démarrer le serveur avec la commande suivante:
```
python3 -m http.server -b 0.0.0.0
```
Ensuite il faut obtenir l'adresse IP de son ordinateur
```
ip a
```
Dans notre cas c'est `10.0.0.165` (voir l'exemple ci-dessous).
```
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether c4:9d:ed:15:78:cc brd ff:ff:ff:ff:ff:ff
inet 10.0.0.165/24 brd 10.0.0.255 scope global dynamic noprefixroute mlan0
valid_lft 5204sec preferred_lft 5204sec
```
Sur son tel, on peut alors acceder a http://10.0.0.165:8000/.
Si cela ne fonctionne pas, c'est peut être que le pare feu interdit la connexion depuis un autre ordinateur sur le port 8000.
+16 -1
View File
@@ -4,13 +4,28 @@
}
/*======================= Page Statut LOL fermé ===*/
#lolIsClosed{
#lolIsClosed {
position: relative;
top: 0;
left: 0;
margin: 0;
width: 100vw;
height: 100vh;
background-color: var(--main-color);
#closedContainer {
padding: 15px;
box-sizing: border-box;
}
.cute-texture {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: -1;
}
}
#closedContainer{
+38
View File
@@ -10,11 +10,49 @@
<title>Le LOL est Fermé ...</title>
</head>
<body id="lolIsClosed">
<canvas data-cute-texture class="cute-texture"></canvas>
<main id="closedContainer">
<section>
<p>Le LOL est actuellement</p>
<h3 id="lolStatus">fermé ...</h3>
</section>
</main>
<script type="x-shader/glsl+fragment">
// Some random values computed for each frame
uniform highp vec4 uRandom;
// Size (in logical pixel) of current CuteTexture canvas
uniform highp vec2 uCanvasSize;
// Coordinates of current pixel being computed from [0,0] (top left) to [1,1] (bottom right)
varying highp vec2 vTextureCoord;
void main() {
highp float pixelSize = 50.0;
highp vec2 coords = floor((uCanvasSize.xy * vTextureCoord.xy) / pixelSize);
highp float lum = (noise1(uRandom.yz+coords) * 0.631372549);
lowp float opacity = 0.5;
highp vec4 baseColor = vec4(
0.0,
lum,
lum,
1.0
);
highp vec4 rotatedColor = hue_rotate(baseColor, 13.12);
gl_FragColor = vec4(
rotatedColor.x*opacity,
rotatedColor.y*opacity,
rotatedColor.z*opacity,
1.0
);
}
</script>
<script type="module">
import {initCuteTexture} from "../js/cuteTexture.js"
initCuteTexture()
</script>
</body>
</html>
-20
View File
@@ -1,20 +0,0 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/svg" href="/assets/favicon_open.svg" />
<style>
:root {
--back-color: #00FF44;
--main-color: #000000;
}
</style>
<title>Le LOL est Ouvert</title>
</head>
<body>
<main>
<p id="statusText">Ouvert !</p>
</main>
</body>
</html>
+49
View File
@@ -11,11 +11,60 @@
<title>Le LOL est Ouvert</title>
</head>
<body id="lolIsOpen">
<video data-cute-texture-video class="cute-texture-video" src="/assets/video/background.webm" autoplay muted loop ></video>
<canvas data-cute-texture class="cute-texture"></canvas>
<main id="openContainer">
<section>
<p>Le LOL est actuellement</p>
<h3 id="lolStatus">ouvert !</h3>
</section>
</main>
<script type="x-shader/glsl+fragment">
// Some random values computed for each frame
uniform highp vec4 uRandom;
// Size (in logical pixel) of current CuteTexture canvas
uniform highp vec2 uCanvasSize;
// Number of seconds since canvas was initialized
uniform lowp float uTime;
// Current frame of first video with [data-cute-texture-video] attribute
uniform sampler2D uVideo;
// Coordinates of current pixel being computed from [0,0] (top left) to [1,1] (bottom right)
varying highp vec2 vTextureCoord;
void main() {
highp float waveSize = 10.0;
highp vec2 coords = (uCanvasSize.xy * vTextureCoord.xy) / waveSize;
highp float lum = abs(sin(coords.y-uTime)) + 0.631372549;
lowp float opacity = 0.5;
gl_FragColor = vec4(
0.0,
lum,
0.0,
1.0
);
gl_FragColor = hue_rotate(gl_FragColor, 13.12);
gl_FragColor = vec4(
gl_FragColor.rgb * opacity,
1.0
);
highp vec2 videoCoords = (vTextureCoord.xy / 1.5) + vec2(0, 0.25);
highp vec4 videoPix = clamp(( grayscale(texture2D(uVideo, videoCoords), 1.0) * 2.0 ), vec4(0), vec4(1));
videoPix *= 0.777;
gl_FragColor = abs( videoPix - gl_FragColor );
gl_FragColor.a = 1.0;
}
</script>
<script type="module">
import {initCuteTexture} from "../js/cuteTexture.js"
initCuteTexture()
</script>
</body>
</html>
+17 -1
View File
@@ -29,13 +29,29 @@
}
/*======================= Page Statut LOL ouvert ===*/
#lolIsOpen{
#lolIsOpen {
position: relative;
top: 0;
left: 0;
margin: 0;
width: 100vw;
height: 100vh;
background-color: var(--main-color);
#openContainer {
padding: 15px;
box-sizing: border-box;
}
.cute-texture, .cute-texture-video {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: -1;
}
}
#openContainer{
+23
View File
@@ -0,0 +1,23 @@
#!/bin/bash
if [ "$#" = "0" ]; then
echo "Usage set-status.sh [new-status]"
echo ""
echo "[new-status] can be \"opened\" or \"closed\""
echo ""
exit 1
fi
#SPACE_JSON=/var/www/html/spaceapi/space.json
if [ "$1" = "opened" ]; then
ln -sf "index.ouvert.html" "$(dirname $0)/index.html"
#jq "setpath([\"state\", \"open\"]; true) | setpath([\"state\", \"lastchange\"]; $(date +%s))" < $SPACE_JSON > $SPACE_JSON.new &&
#mv -f $SPACE_JSON.new $SPACE_JSON
fi
if [ "$1" = "closed" ]; then
ln -sf "index.fermé.html" "$(dirname $0)/index.html"
#jq "setpath([\"state\", \"open\"]; false) | setpath([\"state\", \"lastchange\"]; $(date +%s))" < $SPACE_JSON > $SPACE_JSON.new &&
#mv -f $SPACE_JSON.new $SPACE_JSON
fi
+111 -14
View File
@@ -104,12 +104,7 @@ video{
width: auto;
position: absolute;
inset: 0;
z-index: -30;
}
.closedBackground{
opacity: .5;
mix-blend-mode: exclusion;
z-index: -32;
}
.openBackground{
@@ -217,9 +212,14 @@ main{
color: var(--back-color);
justify-self: end;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
#planContainer{
width: 100%;
height: 100%;
height: max-content;
margin-left: 13.12px;
margin-top: 0;
}
@@ -369,9 +369,110 @@ main{
padding-left: 16.1px;
padding-right: 33px;
.iconBtnStyle{
width: 33px;
summary {
padding-left: 33px;
padding-top: 7.77px;
height:50px;
position: relative;
z-index: 0;
list-style-type: none;
.title{
position: relative;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
width: 77%;
box-sizing: border-box;
height: 16.1px;
padding-top: 3.33px;
padding-left: 33px;
margin-bottom: 13.12px;
font-family: 'velvelyne';
font-weight: bold;
font-size: 16.1px;
p{
margin: 0;
}
h4{
margin: 0;
font-family: 'velvelyne';
font-weight: bold;
font-size: 16.1px;
}
}
.resume{
font-family: 'velvelyne';
font-weight: bold;
font-size: 13.12px;
text-transform: none;
padding-left: 33px;
width: 90%;
height: 33px;
border-radius: 16.1px;
border-style: solid;
border-width: thin;
border-color: var(--main-color);
box-sizing: border-box;
}
}
.description{
margin-left: 44px;
margin-bottom: 33px;
height: auto;
width: 95%;
overflow-y: scroll;
background-color: var(--back-color);
border-radius: 16.1px;
border-style: solid;
border-width: thin;
border-color: var(--main-color);
margin-top: 44px;
padding: 13.12px;
padding-right: 33px;
box-sizing: border-box;
font-size: 13.12px;
font-family: 'velvelyne';
font-weight: bold;
text-transform: none;
}
}
details:hover{
}
details[open]{
height: auto;
border-color: var(--back-color);
color: var(--back-color);
background-color: var(--main-color);
summary .resume{
border-color: var(--back-color);
}
::marker{
color: var(--main-color);
}
.description{
color: var(--main-color);
}
}
}
}
@@ -399,9 +500,5 @@ canvas{
width: auto;
position: absolute;
inset: 0;
z-index: -32;
opacity: .5;
filter: hue-rotate(13.12deg);
mix-blend-mode: multiply;
z-index: -30;
}