Skip to content

Instantly share code, notes, and snippets.

@dSalieri
Last active November 19, 2022 12:42
Show Gist options
  • Select an option

  • Save dSalieri/489c49ba25323b871b2f78d3388ac5a1 to your computer and use it in GitHub Desktop.

Select an option

Save dSalieri/489c49ba25323b871b2f78d3388ac5a1 to your computer and use it in GitHub Desktop.
There is used generator's principles, excellent example of it
function* generatorColors(options) {
options = Object.assign(
{
order: ["r", "g", "b"],
borders: {
r: [0, 255],
g: [0, 255],
b: [0, 255],
},
initials: {
r: 255,
g: 0,
b: 0,
},
step: 1,
},
options
);
let {borders, initials, step} = options;
let {colors, order} = options.order.reduce((acc, val) => {
if(borders[val] != null) {
acc.order.push(val);
acc.colors[val] = rangeValue(borders[val][0], borders[val][1], initials[val]);
}
return acc;
}, {colors: {}, order: []});
let pointer = 0;
let dir = 1;
let rest = 0;
let timeToChangePointer = false;
while (true) {
if (rest === 0) {
colors[order[pointer]] = colors[order[pointer]] + step * dir;
} else {
colors[order[pointer]] = colors[order[pointer]] + Math.abs(rest) * dir;
}
if (colors[order[pointer]] > borders[order[pointer]][1]) {
if (rest === 0) {
rest = colors[order[pointer]] - borders[order[pointer]][1];
}
colors[order[pointer]] = borders[order[pointer]][1];
timeToChangePointer = true;
}
if (colors[order[pointer]] < borders[order[pointer]][0]) {
if (rest === 0) {
rest = colors[order[pointer]] - borders[order[pointer]][0];
}
colors[order[pointer]] = borders[order[pointer]][0];
timeToChangePointer = true;
}
if (timeToChangePointer) {
dir = dir === 1 ? -1 : 1;
if (dir === -1) {
pointer = displace(0, order.length - 1, pointer, 1, "backward");
}
if (dir === 1) {
pointer = displace(0, order.length - 1, pointer, 2, "forward");
}
timeToChangePointer = false;
continue;
}
rest = 0;
yield colors;
}
function displace(start, end, current, stepSize, direction) {
if (start === end) return start;
direction = direction || "forward";
stepSize = stepSize || 1;
current = rangeValue(start, end, current);
if (direction === "forward") {
return (current + stepSize) % (end - start + 1);
}
if (direction === "backward") {
let temp = (current - stepSize) % (end - start + 1);
return stepSize > current ? end - Math.abs(temp + 1) : temp;
}
}
function rangeValue(start, end, value) {
if (start <= value && end >= value) return value;
if (start > value || value == null) return start;
if (end < value) return end;
}
}
/// example 1
let colors = generatorColors();
setInterval(() => {
let {r, g, b} = colors.next().value;
document.body.style.backgroundColor = `rgb(${r},${g},${b})`;
}, 16.7);
/// example 2
let colors = generatorColors({
order: ["g"],
borders: {
g: [50, 150],
},
step: 1,
});
setInterval(() => {
let { g } = colors.next().value;
document.body.style.backgroundColor = `rgb(${0},${g},${255})`;
}, 16.7);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment