Files
thit/thit.js
2026-01-20 11:43:00 +01:00

387 lines
10 KiB
JavaScript

let scrollId = Math.floor(Date.now()/1000/60/60);
let scrollPerLoop = 2000;
let mtx = 0.5;
let mty = 0.5;
let mta = 205.0/360.0;
let mtr = 1.0;
let maxScale = 16;
let sensScale = 0.4;
let sensTouch = 100;
let alpha = 10;
let nDecimals = 4;
let touchTip = true;
let sDegree = 3;
let lValue = 0.5;
let r = 0.45;
let sw = r/2;
let sensMouv = 0.1;
let clientX;
let clientY;
let nLayers = 10;
const thit = document.getElementById("thit");
const stringToConvert = thit.innerText;
const myLogo = document.getElementById("myLogo");
const pathGroup = document.getElementById("pathGroup");
const maskGroup = document.getElementById("maskGroup");
const gradientsGroup = document.getElementById("gradients");
const tips = document.getElementById("tips");
const easeOut = document.getElementById("easeOut");
const easeOutValue = document.getElementById("easeOutValue");
const light = document.getElementById("light");
const lightValue = document.getElementById("lightValue");
function ready(fn) {
if (document.readyState !== 'loading') {
fn();
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}
function easeInNone(x) {
return x;
}
function easeOutNone(x) {
return x;
}
function easeInQuad(x) {
return x * x;
}
function easeInCubic(x) {
return x * x * x;
}
function easeOutSine(x) {
return Math.sin((x * Math.PI) / 2);
}
function easeInSpline(x,d) {
return Math.pow(x, d);
}
function easeOutSpline(x,d) {
return 1 - Math.pow(1 - x, d);
}
function easeInCirc(x) {
return 1 - Math.sqrt(1 - Math.pow(x, 2));
}
function easeOutCirc(x) {
return Math.sqrt(1 - Math.pow(x - 1, 2));
}
function easeOutExpo(x) {
return x === 1 ? 1 : 1 - Math.pow(2, -10 * x);
}
function easeInOutCirc(x) {
return x < 0.5
? (1 - Math.sqrt(1 - Math.pow(2 * x, 2))) / 2
: (Math.sqrt(1 - Math.pow(-2 * x + 2, 2)) + 1) / 2;
}
function easeInSine(x) {
return 1 - Math.cos((x * Math.PI) / 2);
}
function easeOutCubic(x) {
return 1 - Math.pow(1 - x, 3);
}
function easeInOutQuad(x) {
return x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2;
}
function easeInOutSine(x) {
return -(Math.cos(Math.PI * x) - 1) / 2;
}
function easeInOutCubic(x) {
return x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2;
}
function triangleWave(x, amplitude, period, offset) {
let normalized = ((x+period/2) * (2 / period)) % 2;
let wave = Math.abs(normalized - 1);
return (wave * amplitude) + offset;
}
function dpathO() {
let d = `M ${(r).toFixed(nDecimals)} 0 V ${(r).toFixed(nDecimals)} A ${r.toFixed(nDecimals)} ${r.toFixed(nDecimals)} 0 0 1 ${(-r).toFixed(nDecimals)} ${(r).toFixed(nDecimals)} V ${(-r).toFixed(nDecimals)} A ${r.toFixed(nDecimals)} ${r.toFixed(nDecimals)} 0 0 1 ${(r).toFixed(nDecimals)} ${(-r).toFixed(nDecimals)} Z`;
return d;
}
function dpathM() {
let d = 'M -100 100 L 100 -100';
return d;
}
function drawLayer(i) {
let si = (scrollId%scrollPerLoop)/(scrollPerLoop-1);
let scale = (nLayers - i - si)/nLayers;
let rate = triangleWave((nLayers - i - si)/(nLayers-1),1,1,0.0);
if (i == 0) {
rate = 0;
}
// increase = easeInSine(increase);
// rate = easeInOutSine(rate);
let myLayer = document.getElementById(`layer${i}`);
let myGrad = document.getElementById(`grad${i}`);
myGrad.innerHTML = `<stop offset="0.1" stop-color="black" /><stop offset="${0.5-0.3*scale}" stop-color="${hslToHex(205.0/360.0,1,lValue*rate)}" /><stop offset="${0.5+0.3*scale}" stop-color="${hslToHex(205.0/360.0,1,lValue*rate)}" /><stop offset="0.9" stop-color="black" />`;
// myGrad.setAttribute('gradientTransform', ` translate (0.5 0.5) scale(${scale}) translate (-0.5 -0.5)`);
let o = document.getElementById(`o${i}`);
let mo = document.getElementById(`mo${i}`);
o.setAttribute('transform', `scale(${scale})`);
mo.setAttribute('transform', `scale(${scale})`);
myLayer.setAttribute('fill', `url(#grad${i})`);
}
function svgChar(i,c) {
let mySvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
// mySvg.setAttribute('width','128px');
// mySvg.setAttribute('height','128px');
mySvg.setAttribute('viewBox','-0.5 -0.5 1 1');
mySvg.setAttribute('version','1.1');
mySvg.setAttribute('id',`svg${i}`);
mySvg.setAttribute('xmlns','http://www.w3.org/2000/svg');
mySvg.setAttribute('xmlns:svg','http://www.w3.org/2000/svg');
mySvg.setAttribute('height','100px');
mySvg.setAttribute('width','100px');
let myChar = document.createElementNS('http://www.w3.org/2000/svg', 'text');
myChar.setAttribute('x','0');
myChar.setAttribute('y','0');
myChar.setAttribute('fill','none');
myChar.setAttribute('id',`text${i}`);
myChar.setAttribute('text-anchor','middle');
myChar.setAttribute('dominant-baseline','middle');
let myText = document.createTextNode(c);
myChar.appendChild(myText);
mySvg.appendChild(myChar);
thit.appendChild(mySvg);
}
function doThit() {
console.log(stringToConvert);
thit.innerHTML = '';
for (let i = 0; i < stringToConvert.length; i++) {
svgChar(i,stringToConvert.charAt(i));
}
}
function doThas() {
for (let i = 0; i < stringToConvert.length; i++) {
cutOutChar(i);
}
}
function cutOutChar(i) {
let mySvg = document.getElementById(`svg${i}`);
let myChar = document.getElementById(`text${i}`);
let myBBox = myChar.getBBox();
let myRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
myRect.setAttribute('x',-1);
myRect.setAttribute('y',-1);
myRect.setAttribute('width',2);
myRect.setAttribute('height',2);
// myRect.setAttribute('x',myBBox.x);
// myRect.setAttribute('y',myBBox.y);
// myRect.setAttribute('width',myBBox.width);
// myRect.setAttribute('height',myBBox.height);
myRect.setAttribute('fill','#404040');
let myRect2 = myRect.cloneNode();
myRect.setAttribute('mask',`url(#mask${i})`);
myRect2.setAttribute('fill','white');
let myMask = document.createElementNS('http://www.w3.org/2000/svg', 'mask');
myMask.setAttribute('id',`mask${i}`);
myMask.setAttribute('mask-type','luminance');
mySvg.innerHTML = '';
myChar.setAttribute('fill','black');
let myOutline = myChar.cloneNode(true);
myOutline.setAttribute('fill','none');
myOutline.setAttribute('stroke','black');
myOutline.setAttribute('stroke-width','0.005');
let myGroup = document.createElementNS('http://www.w3.org/2000/svg', 'g');
myMask.appendChild(myRect2);
myMask.appendChild(myChar);
myGroup.appendChild(myMask);
myGroup.appendChild(myRect);
myGroup.appendChild(myOutline);
for (let j = nLayers-1; j > 0; j--) {
let couleur = (j+1)/nLayers*1/5;
let ratio = 1-(j)/nLayers;
let myClone = myGroup.cloneNode(true);
myClone.firstChild.setAttribute('id',`mask${i}_${j}`);
myClone.childNodes[1].setAttribute('mask',`url(#mask${i}_${j})`);
myClone.childNodes[1].setAttribute('fill',`${hslToHex(couleur,1,0.5)}`);
myClone.setAttribute('transform',`translate(0 ${-(j+1)*0.0035}) scale(${ratio})`);
mySvg.appendChild(myClone);
}
mySvg.appendChild(myGroup);
}
function addLayers() {
for (let i = 0; i < nLayers; i++) {
let e = document.createElement("linearGradient");
e.setAttribute('id', `grad${i}`);
e.setAttribute('x1','0');
e.setAttribute('y1', '0');
e.setAttribute('x2', '1');
e.setAttribute('y2', '0');
// let e = document.createElement("radialGradient");
// e.setAttribute('cx', '50%');
// e.setAttribute('id', `grad${i}`);
// e.setAttribute('cy','50%');
// e.setAttribute('r', '50%');
// e.setAttribute('fx', '50%');
// e.setAttribute('fy', '50%');
gradientsGroup.appendChild(e);
}
for (let i = nLayers - 1; i >= 0; i--) {
let g = document.createElement("g");
g.setAttribute('id', `group${i}`);
g.setAttribute('shape-rendering','geometricPrecision')
let r = document.createElement("rect");
r.setAttribute('id', `rect${i}`);
r.setAttribute('x',-1);
r.setAttribute('y',-1);
r.setAttribute('width',2);
r.setAttribute('height',2);
r.setAttribute('fill',"white");
let o = document.createElement("path");
o.setAttribute('id', `o${i}`);
o.setAttribute('d',dpathO());
o.setAttribute('fill',"black");
let mo = document.createElement("path");
mo.setAttribute('id', `mo${i}`);
mo.setAttribute('d',dpathM());
mo.setAttribute('stroke',"black");
mo.setAttribute('stroke-width',`${sw}`);
// e.setAttribute('mask', `url(#mask${i})`);
let m = document.createElement("mask");
m.setAttribute('id', `mask${i}`);
m.appendChild(r);
m.appendChild(o);
m.appendChild(mo);
g.appendChild(m);
let l = document.createElement("rect");
l.setAttribute('id', `layer${i}`);
l.setAttribute('x',-1);
l.setAttribute('y',-1);
l.setAttribute('width',2);
l.setAttribute('height',2);
l.setAttribute('mask',`url(#mask${i})`);
g.appendChild(l);
myLogo.appendChild(g);
}
myLogo.innerHTML += '';
redrawLayers();
}
function redrawLayers() {
mta = Math.atan2(-0.5+mty,-0.5+mtx)/(2*Math.PI)+0.5;
mtr = Math.min(2* Math.sqrt(Math.pow(-0.5+mty,2)+Math.pow(-0.5+mtx,2)),1);
for (let i = 0; i < nLayers; i++) {
drawLayer(i);
}
}
function componentToHex(c) {
var hex = c.toString(16);
return hex.length == 1 ? "0" + hex : hex;
}
function rgbToHex(r, g, b) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
function rgbaToHex(r, g, b, a) {
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b) + componentToHex(a);
}
function hslToHex(h, s, l) {
var r, g, b;
if (s == 0) {
r = g = b = 0; // achromatic
} else {
function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = Math.round(hue2rgb(p, q, h + 1/3) * 255);
g = Math.round(hue2rgb(p, q, h) * 255);
b = Math.round(hue2rgb(p, q, h - 1/3) * 255);
}
return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}
document.addEventListener("wheel", (e) => {
// e.preventDefault();
scrollId += e.deltaY;
if (scrollId <= 0){
scrollId = 0;
console.log("You reached 1ᵉʳ janvier 1970")
}
// redrawLayers();
});
document.addEventListener("scroll", (e) => {
// e.preventDefault();
scrollId += e.deltaY;
if (scrollId <= 0){
scrollId = 0;
console.log("You reached 1ᵉʳ janvier 1970")
}
// redrawLayers();
});
ready(doThit());
doThas()
function letFlow() {
scrollId += 50;
// redrawLayers();
}
setInterval(letFlow, 60);