Skip to main content
Code Review

Return to Answer

replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

I suggest to get a random permutation of [0, 1, 2] by introducing a simple but unbiased shuffle shuffle function.

I suggest to get a random permutation of [0, 1, 2] by introducing a simple but unbiased shuffle function.

I suggest to get a random permutation of [0, 1, 2] by introducing a simple but unbiased shuffle function.

Support for older browsers
Source Link
le_m
  • 1.9k
  • 10
  • 15

Please tell me about everything I could do better, but especially how to calculate notand not hardcorehardcode the randomly shifted second array [...].

If you wish to support older browsers, remove the CSS variables and use

gradient.style.background = 
 "linear-gradient(90deg, rgb(" + from + "), rgb(" + to + "))";

Please tell me about everything I could do better, but especially how to calculate not not hardcore the randomly shifted second array [...].

Please tell me about everything I could do better, but especially how to calculate and not hardcode the randomly shifted second array [...].

If you wish to support older browsers, remove the CSS variables and use

gradient.style.background = 
 "linear-gradient(90deg, rgb(" + from + "), rgb(" + to + "))";
Source Link
le_m
  • 1.9k
  • 10
  • 15

Please tell me about everything I could do better, but especially how to calculate not not hardcore the randomly shifted second array [...].

I suggest to get a random permutation of [0, 1, 2] by introducing a simple but unbiased shuffle function.

A circular shift of that random permutation can then be found by mapping index i to index (i + shift) % length:

// Return two shifted colors with min, max and random component:
function randomGradientColors(min, max) {
 let permutation = shuffle([0, 1, 2]);
 let shift = random(1, 2);
 return [
 permutation.map(i => [min, max, random(min, max)][i]),
 permutation.map(i => [min, max, random(min, max)][(i + shift) % 3])
 ];
}

Since you asked for everything that you could do better, I would like to suggest using a CSS background gradient instead of a canvas element. If compatibility is not a concern, you can even leverage fancy CSS variables:

.gradient {
 background: linear-gradient(90deg, var(--from, black), var(--to, black));
}

Your markup then would provide the min and max color components via data attributes:

<div class="gradient" data-min="70" data-max="185"></div>

And your script would simply query all .gradient elements and compute their CSS from and to variables from the provided data attributes:

let gradients = document.querySelectorAll(".gradient");
for (let gradient of gradients) {
 let [from, to] = randomGradientColors(
 gradient.dataset.min,
 gradient.dataset.max
 );
 gradient.style.setProperty("--start", "rgb(" + from + ")");
 gradient.style.setProperty("--to", "rgb(" + to + ")");
}

This approach is pretty flexible and allows you to adapt the styling to your needs without touching the script.

Here is the complete code:

// Return random integer within interval [min, max]:
function random(min, max) {
 return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Shuffle array in-place:
function shuffle(array) {
 for (let i = array.length - 1; i > 0; i--) {
 let j = Math.floor(Math.random() * (i + 1));
 [array[i], array[j]] = [array[j], array[i]];
 }
 return array;
}
// Return two shifted colors with min, max and random component:
function randomGradientColors(min, max) {
 let permutation = shuffle([0, 1, 2]);
 let shift = random(1, 2);
 return [
 permutation.map(i => [min, max, random(min, max)][i]),
 permutation.map(i => [min, max, random(min, max)][(i + shift) % 3])
 ];
}
// Compute CSS 'from' and 'to' variables for all gradients:
let gradients = document.querySelectorAll(".gradient");
for (let gradient of gradients) {
 let [from, to] = randomGradientColors(
 gradient.dataset.min,
 gradient.dataset.max
 );
 gradient.style.setProperty("--from", "rgb(" + from + ")");
 gradient.style.setProperty("--to", "rgb(" + to + ")");
}
html {
 background-color: #1d1f21;
}
.gradient {
 display: inline-block;
 width: 500px;
 height: 180px;
 background: linear-gradient(90deg, var(--from, black), var(--to, black));
}
.container {
 text-align: center;
}
.textbox {
 text-align: center;
 color: white;
 font-family: monospace;
}
<div class="container">
 <div class="gradient" data-min="70" data-max="185"></div>
</div>
<div class="textbox">Reload to get a different header gradient.</div>

default

AltStyle によって変換されたページ (->オリジナル) /