// mode : terrain de vie, proximité, superposition.... // profondeur : atlas, carte let modeAmount = 0, curentMode = 1, prevMode, currentProfondeur = "atlas", colors = { bg: { h: 29, s: 48, l: 48 } }; document.querySelectorAll('.mode').forEach(function(node, index) { modeAmount++; node.addEventListener('click', function() { document.querySelectorAll('.active').forEach(function(el) { el.classList.remove('active'); if (currentProfondeur == "carte") { el.classList.add('collapsed'); } }); node.classList.toggle('active'); prevMode = curentMode; curentMode = index + 1; if (curentMode != prevMode) { changeColors(curentMode - prevMode); } }) }); function toggleProfondeur(el) { if (el.classList.contains("selected")) { return; } else { for (let sibling of el.parentNode.children) { sibling.classList.remove('selected'); } } el.classList.add("selected"); if(el.innerHTML == "L'atlas") { currentProfondeur = "atlas"; document.querySelectorAll('.mode').forEach(function(node) { if(node.classList.contains("collapsed")) { node.classList.remove("collapsed"); } }); } else { currentProfondeur = "carte"; document.querySelectorAll('.mode').forEach(function(node) { if(!node.classList.contains("active")) { node.classList.add("collapsed"); } }); } } // onclick sur les flèches du menu function toggleMode(direction) { let modes = []; let currentIndex; document.querySelectorAll('.mode').forEach(function(node, index) { modes.push(node); if (node.classList.contains("active")) { currentIndex = index; node.classList.remove("active"); if (currentProfondeur == "carte") { node.classList.add("collapsed"); } } }); if (direction == "next" && currentIndex + 2 <= modeAmount) { modes[currentIndex + 1].classList.add('active'); curentMode = curentMode + 1; changeColors(1); } else if (direction == "prev" && currentIndex - 1 >= 0) { modes[currentIndex - 1].classList.add('active'); curentMode = curentMode - 1; changeColors(-1); } else if (direction == "next" && currentIndex + 1 == modeAmount) { modes[0].classList.add('active'); curentMode = 1; changeColors(-modeAmount + 1); } else if (direction == "prev" && currentIndex == 0) { modes[modeAmount - 1].classList.add('active'); curentMode = modeAmount; changeColors(modeAmount - 1); } } function changeColors(diffAmount) { let prevPaletteIndex = (prevMode + (prevMode - 1)); let baseColors = []; baseColors.push(colorPalette[prevPaletteIndex - 1]); baseColors.push(colorPalette[prevPaletteIndex]); baseColors.push(colorPalette[prevPaletteIndex + 1] ? colorPalette[prevPaletteIndex + 1] : colorPalette[0]); let paletteIndex = (curentMode + (curentMode - 1)); let targetColors = []; targetColors.push(colorPalette[paletteIndex - 1]); targetColors.push(colorPalette[paletteIndex]); targetColors.push(colorPalette[paletteIndex + 1 ] ? colorPalette[paletteIndex + 1] : colorPalette[0]); function hexToRgba(color) { let colorRgba = { r : parseInt(color.substr(0, 2), 16), g : parseInt(color.substr(2, 2), 16), b : parseInt(color.substr(4, 2), 16), a : parseInt(color.substr(6, 2), 16) } return colorRgba; } function rgbaToHex(color) { let colorHexa = { r : color.r.toString(16).length != 2 ? 0 + color.r.toString(16) : color.r.toString(16), g : color.g.toString(16).length != 2 ? 0 + color.g.toString(16) : color.g.toString(16), b : color.b.toString(16).length != 2 ? 0 + color.b.toString(16) : color.b.toString(16), a : color.a.toString(16).length != 2 ? 0 + color.a.toString(16) : color.a.toString(16) } return colorHexa.r + colorHexa.g + colorHexa.b + colorHexa.a; } let steps = 10, // vitesse de la transition currentFrame = 0; function animate() { currentFrame++; // à chaque frame on vide currentColors // puis pusher trois couleurs hex de transition // lorsque le nombre de steps est atteint envoyer les couleurs def // et ne pas réanimer currentColors = []; for (i = 0; i < baseColors.length; i++) { if (currentFrame == steps) { currentColors.push(targetColors[i]) } else { currentColors.push(getTransitionColor(baseColors[i], targetColors[i], currentFrame)); } } if (steps == 0) transitionLaunched++; if (currentFrame != steps) { window.requestAnimationFrame(() => animate()); } else { currentFrame = 0; } } animate() function getTransitionColor(baseColor, targetColor, currentFrame) { console.log(baseColor, targetColor, currentFrame) let rgbaBase = hexToRgba(baseColor), rgbaTarget = hexToRgba(targetColor), diff = { r : (rgbaBase.r - rgbaTarget.r) * -1, g : (rgbaBase.g - rgbaTarget.g) * -1, b : (rgbaBase.b - rgbaTarget.b) * -1, a : (rgbaBase.a - rgbaTarget.a) * -1 }, transitionColor = { r : Math.floor(rgbaBase.r + (diff.r / steps) * currentFrame), g : Math.floor(rgbaBase.g + (diff.g / steps) * currentFrame), b : Math.floor(rgbaBase.b + (diff.b / steps) * currentFrame), a : Math.floor(rgbaBase.a + (diff.a / steps) * currentFrame) }; transitionColor = rgbaToHex(transitionColor); return transitionColor; } } // COULEURS DE FOND // basé sur https://codepen.io/ThreePixDroid/pen/MWeomWp // ajouter un grain fixe : cf // https://codepen.io/zadvorsky/pen/PwyoMm let colorPalette = [ "ff6a0399", "c9c4ffff", "0796908c", "e6ffc4ff", "e105054d", "aaffa2ff", "18b8e64d", "ffc4f9ff", "9692074d", "ffe7c4ff", "0629ad4d", "fffdbaff" ] let currentColors = []; currentColors.push( colorPalette[0], colorPalette[1], colorPalette[2], ); class GradientAnimation { constructor() { this.cnv = document.querySelector('canvas'); this.ctx = this.cnv.getContext('2d'); // réglages du fond this.radius = 1800; this.speed = 0.001; (window.onresize = () => { this.setCanvasSize(); this.createCircles(); })(); this.drawAnimation(); } setCanvasSize() { this.w = this.cnv.width = innerWidth * devicePixelRatio; this.h = this.cnv.height = innerHeight * devicePixelRatio; this.ctx.scale(devicePixelRatio, devicePixelRatio); } createCircles() { this.circles = []; // positionnement des cercles directement ici this.circles.push(new Circle(this.w, this.h, this.radius, 30, 30, 0)); this.circles.push(new Circle(this.w, this.h, this.radius, window.innerWidth / 2, window.innerHeight, 1)); this.circles.push(new Circle(this.w, this.h, this.radius, window.innerWidth - 30, 30, 2)); } drawCircles() { this.circles.forEach(circle => circle.draw(this.ctx, this.speed)); } drawBackground() { this.ctx.fillStyle = "#aaaaaa"; this.ctx.fillRect(0, 0, this.w, this.h); } drawAnimation() { this.drawBackground(); this.drawCircles(); window.requestAnimationFrame(() => this.drawAnimation()); } } class Circle { constructor(w, h, radius, posX, posY, index) { this.x = posX; this.y = posY; this.angle = Math.random() * Math.PI * 2; this.radius = radius; this.index = index; this.firstColor = "#" + currentColors[index]; this.secondColor = "#ffffff00"; } draw(ctx, speed) { this.angle += speed; const x = this.x + Math.cos(this.angle) * 200; const y = this.y + Math.sin(this.angle) * 200; const gradient = ctx.createRadialGradient(x, y, 0, x, y, this.radius); gradient.addColorStop(0, "#" + currentColors[this.index]); gradient.addColorStop(1, this.secondColor); ctx.globalCompositionOperation = "multiply"; // ça marche pas ctx.fillStyle = gradient; ctx.beginPath(); ctx.arc(x, y, this.radius, 0, Math.PI * 2); ctx.fill(); } } window.onload = () => { new GradientAnimation(); } /* palette : multiply vers blanc 0 #ff6a03 45% 1 TERRAIN DE VIE 1 #c9c4ff 100% 2 #079690 30% 2 PROXIMITE 3 #e6ffc4 100% 4 #e10505 30% 3 SUPPERPOSITION 5 #aaffa2 100% 6 #18b8e6 30% 4 PUISSANCE 7 #ffc4f9 100% 8 #969207 30% 5 ACTION 9 #ffe7c4 100% 10 #0629ad 30% 6 DOLEANCER 11 #fffdba 100% */ // 1 1, 2 3, 3 5, 4 7, 5 9, 6 11