From 3e7c9475e51240e5fdfe7165f81e5cd3de1574c2 Mon Sep 17 00:00:00 2001 From: EpicKiwi Date: Sun, 2 Aug 2026 14:36:45 +0200 Subject: [PATCH] =?UTF-8?q?Premi=C3=A8re=20version=20GPU=20des=20effets=20?= =?UTF-8?q?de=20fond?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 5 +- js/cuteTexture.js | 315 +++++++++++++++++++++++++++++++-------- js/main.js | 36 +---- status/closedStyle.css | 17 ++- status/index.fermé.html | 37 +++++ status/index.ouvert.html | 39 +++++ status/openStyle.css | 18 ++- 7 files changed, 363 insertions(+), 104 deletions(-) diff --git a/index.html b/index.html index 122e7ab..848c3dc 100644 --- a/index.html +++ b/index.html @@ -160,10 +160,7 @@ - - - - +
diff --git a/js/cuteTexture.js b/js/cuteTexture.js index 64fb8cd..ed08a51 100644 --- a/js/cuteTexture.js +++ b/js/cuteTexture.js @@ -1,87 +1,274 @@ -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; + 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; + } +` -let scale = 0.7; +const FRAGMENT_SHADER_UTILITIES = ` + highp float noise1(highp vec2 co){ + return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453); + } -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; + // Color spaces from https://github.com/tobspr/GLSL-Color-Spaces/blob/master/ColorSpaces.inc.glsl - for(let x = 0; x 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) + 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 } - ctx.putImageData(img, 0, 0); - - offset ++; - if(offset>1024){ - offset = 0; } } -let time = 0 +/** + * @param {WebGLRenderingContext} ctx + */ +function initMainShader(ctx, oldShader=null){ + const vertexShader = ctx.createShader(ctx.VERTEX_SHADER) + ctx.shaderSource(vertexShader, DEFAULT_VERTEX_SHADER) + ctx.compileShader(vertexShader) -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; + 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 + } - for(let y = 0; y= 0){ + error = `Ligne ${lineNumeWithoutUtils}: ${error}` } } - ctx.putImageData(img, 0, 0); + + 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 + } + + if(oldShader){ + ctx.deleteProgram(oldShader.program) + ctx.deleteShader(oldShader.vertexShader) + ctx.deleteShader(oldShader.fragmentShader) + ctx.deleteBuffer(oldShader.vertexIndexBuffer) + } + + 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, + fragmentShaderElement: fragmentShaderCodeElement, + aVertexIndex: ctx.getAttribLocation(shaderProgram, "aVertexIndex"), + uRandom: ctx.getUniformLocation(shaderProgram, "uRandom"), + uCanvasSize: ctx.getUniformLocation(shaderProgram, "uCanvasSize"), + uTime: ctx.getUniformLocation(shaderProgram, "uTime"), + vertexIndexBuffer, + } } -export function scanlinesAnimation(){ - scanlines(); - requestAnimationFrame(scanlinesAnimation); -} +/** + * @param {HTMLCanvasElement} target + * @param {*} mainShader + */ +function renderCuteTexture(target, mainShader, initTime){ + let ctx = target.getContext("webgl") -export function noiseAnimation(){ - analogLikeNoise(); - requestAnimationFrame(noiseAnimation); -} + 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) -export function loadCanvas(){ - let textureVideo = document.querySelectorAll('main > #texture'); + 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) - for (let video of textureVideo){ - video.style.visibility = 'collapse'; - } + ctx.useProgram(mainShader.program) + if(mainShader.uRandom){ + ctx.uniform4f( + mainShader.uRandom, + Math.random(), + Math.random(), + Math.random(), + Math.random() + ) + } - let textureCanvas = document.querySelector('main > canvas'); - textureCanvas.style.visibility = 'visible'; + if(mainShader.uCanvasSize){ + ctx.uniform2f( + mainShader.uCanvasSize, + target.width, + target.height + ) + } - //console.log(textureCanvas); - - //console.log(textureVideo) -} + if(mainShader.uTime){ + ctx.uniform1f( + mainShader.uTime, + (Date.now() - initTime)/1000 + ) + } + + ctx.drawArrays(ctx.TRIANGLE_STRIP, 0, 3); +} \ No newline at end of file diff --git a/js/main.js b/js/main.js index 619a194..fbd0dd0 100644 --- a/js/main.js +++ b/js/main.js @@ -1,41 +1,9 @@ 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' - - - - +import { initCuteTexture } 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); - +initCuteTexture() // ======================================== events & statut d'ouverture loadEvents(); diff --git a/status/closedStyle.css b/status/closedStyle.css index 431c6dc..af8858d 100644 --- a/status/closedStyle.css +++ b/status/closedStyle.css @@ -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{ diff --git a/status/index.fermé.html b/status/index.fermé.html index 0952296..3c171e8 100644 --- a/status/index.fermé.html +++ b/status/index.fermé.html @@ -10,11 +10,48 @@ Le LOL est Fermé ... +

Le LOL est actuellement

fermé ...

+ + + + diff --git a/status/index.ouvert.html b/status/index.ouvert.html index c58dd41..5b6cfbc 100644 --- a/status/index.ouvert.html +++ b/status/index.ouvert.html @@ -11,11 +11,50 @@ Le LOL est Ouvert +

Le LOL est actuellement

ouvert !

+ + + + diff --git a/status/openStyle.css b/status/openStyle.css index 5ee8fcd..99dd0f3 100644 --- a/status/openStyle.css +++ b/status/openStyle.css @@ -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{