Skip to content

Commit b8ad2df

Browse files
committed
i
1 parent 57dcac7 commit b8ad2df

11 files changed

Lines changed: 288 additions & 162 deletions

File tree

dist/bundle-1e00a.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/bundle-650e6.js

Lines changed: 0 additions & 2 deletions
This file was deleted.

dist/index.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

src/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,6 +1506,7 @@ <h4>Profitability Has Never Excused Criminality: A Message To Facebook, Google,
15061506
<td style="text-align:right; width:20%; padding-right:2.5%; padding-top:.6em;"><a class="no-bg" title="Home" href="/"><img class="img-footer img-opaq" decoding="async" alt="Home" src="/img/yinyang.png"></a></td></tr></table></footer>
15071507

15081508
<script src="/js/welcome-overlay.js"></script>
1509+
<script src="/js/noise.js"></script>
15091510
<script src="/js/utils.js"></script>
15101511
<script src="/js/screensaver.js"></script>
15111512
<script src="/yt/youtube-embed.js"></script>

src/js/background.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ function createBgLayerState(element) {
9999
};
100100
}
101101

102+
// Cache the last gradient string to avoid unnecessary DOM writes
103+
let lastGradient1 = '';
104+
let lastGradient2 = '';
105+
102106
function setGradient(element, state) {
103107
const { currentLayer } = getShiftLayerInfo(element);
104108
const width = element.offsetWidth || element.clientWidth;
@@ -120,7 +124,16 @@ function setGradient(element, state) {
120124
);
121125
}
122126

123-
element.style.backgroundImage = gradients.join(', ');
127+
const gradientString = gradients.join(', ');
128+
129+
// Only update background if different to reduce style recalcs
130+
if ((element.id === 'shift-layer1' && gradientString !== lastGradient1) ||
131+
(element.id === 'shift-layer2' && gradientString !== lastGradient2)) {
132+
element.style.backgroundImage = gradientString;
133+
if (element.id === 'shift-layer1') lastGradient1 = gradientString;
134+
else lastGradient2 = gradientString;
135+
}
136+
124137
element.style.filter = `
125138
opacity(${state.currentOpacity}%)
126139
contrast(${state.currentContrast}%)
@@ -135,6 +148,7 @@ function updateLayerState(state, element, deltaTime) {
135148
state.transitionProgress = Math.min(1, state.transitionProgress + deltaTime / state.transitionDuration);
136149

137150
const t = () => metaRecursiveEaseNoise(state.transitionProgress);
151+
138152
const { currentLayer } = getShiftLayerInfo(element);
139153

140154
const randomFactor = (max) => Math.random() * max;

src/js/color-change.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
const hoverShift = document.querySelectorAll('button, a, .article-nav-bottom, footer');
22
const alwaysShift = document.querySelectorAll('header, #site-title, #toolbar, nav .col a, .article-header, .article-title, .section-nav, footer');
33

4-
function getRandomDegree() {
4+
function getRandomHueRotation() {
55
return Math.random() < 0.5
66
? -45 - Math.floor(Math.random() * 270)
7-
: 46 + Math.floor(Math.random() * 224);
7+
: 45 + Math.floor(Math.random() * 270);
88
}
99

1010
function getRandomInterval() {
@@ -25,8 +25,8 @@ function isElementInViewport(el) {
2525
}
2626

2727
function startShift(element, interval, isHover = false) {
28-
let currentDegree = getRandomDegree();
29-
let targetDegree = currentDegree;
28+
let currentHueRotation = getRandomHueRotation();
29+
let targetHueRotation = currentHueRotation;
3030
let currentSaturation = 100, targetSaturation = 100;
3131
let currentContrast = 100, targetContrast = 100;
3232
let currentBrightness = 100, targetBrightness = 100;
@@ -36,7 +36,7 @@ function startShift(element, interval, isHover = false) {
3636

3737
function updateFilter() {
3838
const filterValue = `
39-
hue-rotate(${currentDegree}deg)
39+
hue-rotate(${currentHueRotation}deg)
4040
saturate(${currentSaturation}%)
4141
contrast(${currentContrast}%)
4242
brightness(${currentBrightness}%)
@@ -52,14 +52,14 @@ function startShift(element, interval, isHover = false) {
5252
lastTime = time;
5353
progress += deltaTime / interval;
5454
if (progress >= 1) {
55-
targetDegree = getRandomDegree();
55+
targetHueRotation = getRandomHueRotation();
5656
targetSaturation = Math.random() * 35 + 90; // 90-125
5757
targetContrast = Math.random() * (isHover ? 90 : 40) + 80;
5858
targetBrightness = Math.random() * (isHover ? 50 : 20) + (isHover ? 85 : 90);
5959
progress = 0;
6060
}
6161
const t = () => metaRecursiveEaseNoise(progress);
62-
currentDegree += Math.round((targetDegree - currentDegree) * t() * Math.random() * 0.07);
62+
currentHueRotation += Math.round((targetHueRotation - currentHueRotation) * t() * Math.random() * 0.07);
6363
currentSaturation += Math.round((targetSaturation - currentSaturation) * t() * Math.random());
6464
currentContrast += Math.round((targetContrast - currentContrast) * t() * Math.random());
6565
currentBrightness += Math.round((targetBrightness - currentBrightness) * t() * Math.random());

src/js/noise.js

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// Simplex noise constants
2+
const F2 = 0.5 * (Math.sqrt(3) - 1);
3+
const G2 = (3 - Math.sqrt(3)) / 6;
4+
const grad3 = [
5+
[1, 1, 0], [-1, 1, 0], [1, -1, 0], [-1, -1, 0],
6+
[1, 0, 1], [-1, 0, 1], [1, 0, -1], [-1, 0, -1],
7+
[0, 1, 1], [0, -1, 1], [0, 1, -1], [0, -1, -1]
8+
];
9+
10+
class SimplexNoise {
11+
constructor(seed = Math.random()) {
12+
this.p = new Uint8Array(256);
13+
for (let i = 0; i < 256; i++) {
14+
this.p[i] = Math.floor(seed * 256);
15+
seed = (seed * 9301 + 49297) % 233280 / 233280;
16+
}
17+
this.perm = new Uint8Array(512);
18+
for (let i = 0; i < 512; i++) {
19+
this.perm[i] = this.p[i & 255];
20+
}
21+
}
22+
23+
dot(g, x, y) {
24+
return g[0] * x + g[1] * y;
25+
}
26+
27+
noise(xin, yin) {
28+
xin = Math.round(xin * 1000) / 1000;
29+
yin = Math.round(yin * 1000) / 1000;
30+
let n0, n1, n2;
31+
let s = (xin + yin) * F2;
32+
let i = Math.floor(xin + s);
33+
let j = Math.floor(yin + s);
34+
let t = (i + j) * G2;
35+
let X0 = i - t;
36+
let Y0 = j - t;
37+
let x0 = xin - X0;
38+
let y0 = yin - Y0;
39+
let i1, j1;
40+
if (x0 > y0) {
41+
i1 = 1; j1 = 0;
42+
} else {
43+
i1 = 0; j1 = 1;
44+
}
45+
let x1 = x0 - i1 + G2;
46+
let y1 = y0 - j1 + G2;
47+
let x2 = x0 - 1 + 2 * G2;
48+
let y2 = y0 - 1 + 2 * G2;
49+
let ii = i & 255;
50+
let jj = j & 255;
51+
let perm = this.perm;
52+
let gi0 = perm[ii + perm[jj]] % 12;
53+
let gi1 = perm[ii + i1 + perm[jj + j1]] % 12;
54+
let gi2 = perm[ii + 1 + perm[jj + 1]] % 12;
55+
let t0 = 0.5 - x0 * x0 - y0 * y0;
56+
n0 = (t0 < 0) ? 0 : (t0 * t0) ** 2 * this.dot(grad3[gi0], x0, y0);
57+
let t1 = 0.5 - x1 * x1 - y1 * y1;
58+
n1 = (t1 < 0) ? 0 : (t1 * t1) ** 2 * this.dot(grad3[gi1], x1, y1);
59+
let t2 = 0.5 - x2 * x2 - y2 * y2;
60+
n2 = (t2 < 0) ? 0 : (t2 * t2) ** 2 * this.dot(grad3[gi2], x2, y2);
61+
return 70 * (n0 + n1 + n2);
62+
}
63+
}
64+
65+
// Perlin noise implementation
66+
const permutation = [...Array(256)].map(() => Math.floor(Math.random() * 256));
67+
const p = [...permutation, ...permutation];
68+
69+
function fade(t) {
70+
return t * t * t * (t * (t * 6 - 15) + 10);
71+
}
72+
73+
function lerp(t, a, b) {
74+
return a + t * (b - a);
75+
}
76+
77+
function grad(hash, x) {
78+
const h = hash & 15;
79+
const grad = 1 + (h & 7);
80+
return (h & 8 ? -grad : grad) * x;
81+
}
82+
83+
function perlinNoise(x) {
84+
const X = Math.floor(x) & 255;
85+
x -= Math.floor(x);
86+
const u = fade(x);
87+
return lerp(u, grad(p[X], x), grad(p[X+1], x-1));
88+
}
89+
90+
// FBM (Fractional Brownian Motion) - wraps SimplexNoise for multi-octave complexity
91+
function fbm(simplexInstance, x, y, octaves = 4, persistence = 0.5, lacunarity = 2) {
92+
let value = 0;
93+
let amplitude = 1;
94+
let frequency = 1;
95+
let maxValue = 0;
96+
97+
for (let i = 0; i < octaves; i++) {
98+
value += amplitude * simplexInstance.noise(x * frequency, y * frequency);
99+
maxValue += amplitude;
100+
amplitude *= persistence;
101+
frequency *= lacunarity;
102+
}
103+
104+
return value / maxValue;
105+
}
106+
107+
// Turbulence - chaotic swirling effect using absolute values of noise
108+
function turbulence(simplexInstance, x, y, octaves = 4) {
109+
let value = 0;
110+
let amplitude = 1;
111+
let freqX = x;
112+
let freqY = y;
113+
114+
for (let i = 0; i < octaves; i++) {
115+
value += amplitude * Math.abs(simplexInstance.noise(freqX, freqY));
116+
freqX *= 2;
117+
freqY *= 2;
118+
amplitude *= 0.5;
119+
}
120+
121+
return value;
122+
}
123+
124+
// Worley Noise (Cellular Noise) - creates organic cellular patterns
125+
function worley(x, y, cellCount = 4) {
126+
const cellX = Math.floor(x * cellCount);
127+
const cellY = Math.floor(y * cellCount);
128+
const fracX = x * cellCount - cellX;
129+
const fracY = y * cellCount - cellY;
130+
131+
let minDist = Infinity;
132+
133+
for (let dx = -1; dx <= 1; dx++) {
134+
for (let dy = -1; dy <= 1; dy++) {
135+
const nx = cellX + dx;
136+
const ny = cellY + dy;
137+
138+
// Pseudo-random point in cell using hash function
139+
const hashX = Math.sin(nx * 73.156 + ny * 94.673) * 43758.5453;
140+
const hashY = Math.sin(nx * 45.164 + ny * 94.673) * 43758.5453;
141+
142+
const px = (hashX - Math.floor(hashX)) + dx - fracX;
143+
const py = (hashY - Math.floor(hashY)) + dy - fracY;
144+
145+
const dist = Math.sqrt(px * px + py * py);
146+
if (dist < minDist) minDist = dist;
147+
}
148+
}
149+
150+
return Math.min(1, minDist);
151+
}

0 commit comments

Comments
 (0)