Skip to content

Instantly share code, notes, and snippets.

@rileyjshaw
Last active December 25, 2015 16:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rileyjshaw/7004697 to your computer and use it in GitHub Desktop.
Save rileyjshaw/7004697 to your computer and use it in GitHub Desktop.
A Pen by Riley Shaw.
input type="range" name="slider" min="-50" max="50" id="slider"
// Intended behavior (outlined by a friend):
// Slider that lets us go from pink (left) to green (right) through black (middle). We decided on rgb(200,0,100) for the left, moving towards rgb(90,0,45) at the center... but at the center he needed it to *actually* display black. Similarily, he needed the right side to act like it started at rgb(0, 90, 45) at the center and move to rgb(0, 200, 100) on the far right.
// ...still with me? If that description lost you, just play around with the demo before moving on and you'll get it.
// This came up at a weekly hack night, so I decided to make it hacky. Here's the breakdown.
// Build time:
// 15m: mathy things, double-checking returns from && and ||
// 10m: cancel operations and calculations to make it slim, general tidying, type it out
// 1h: explain to my friend (new to js) what the hell is going on here...
// 40m: comment the code like crazy
///////////////////// CODE /////////////////////
// Block comment at bottom contains bare code //
////////////////////////////////////////////////
// Caching this so that we don't have to get it every time the slider changes
//var bs = document.body.style;
// Whenever the slider is changed, run an anonymous function to update the body's bg color
//document.getElementById('slider').addEventListener('change', function () {
// Why is the slider value (see HTML) bounded between -50 and 50? Well, remember that we wanted our "MAX" red and green color values to be 200, and the "MIN"s to be 100. That means that for each, the range is 200 - 100 = 100. We bounded the slider to 50 because it is half of the range (100)... we'll get in to why we halved it soon.
// Grab the slider's value
// val = parseInt(this.value);
// Store the absolute value so that we only need to calculate it once
// aval = Math.abs(val);
// Now for some math trickery. Imagine a value 'x'. If 'x' is positive, the absolute value of x, minus x, will equal 0. That is to say, |x| - x = 0 when x is +ve. Similarly, |x| - x = 2x when x is -ve.
// This allows us to store the distance from the center into r IF the slider's value is left of the center mark. Otherwise, a 0 is stored into r.
// r = aval - val;
// Exact same principle for green, just flipped so that a positive value leads to 2x. You can figure this one out :)
// g = aval + val;
// Notice that above, we store either 0 or 2x. 2x represents *twice* the value selected on the slider. Re-read line 23. We halved the range of 100 to 50 because we knew that this value would end up being doubled in a few steps, resulting in the correct amount!
// This next line is where the magic truly happens. Right now we have an r value which is the slider value if we're on the red half, or 0 if we're on the green half. We have a similar g value. We're going to start by taking a look at the function, and then work our way from the inside out.
// (r += r && 100) || (g += g && 100);
// Starting with 'r && 100':
// 0 evaluates to false in Javascript, and an && requires both the left- and right-hand sides to be true. Logical expressions are evaluated from left to right, so if r == 0, Javascript already knows that, regardless of the right side, the expression will evaluate to false. Because of this, it skips the right side and returns the left side (0).
// On the other hand, if r !== 0, it evaluates to true. Javascript must then check the right side of the expression, since it affects the statement's truthiness. Since the right side is evaluated, its value (100) will be returned.
// Let's zoom out to r += r && 100:
// We know that r && 90 returns 0 if r == 0 and 100 otherwise. Essentially, we're saying:
// if(r !== 0)
// r += 100
// This means that if it's 0, it will stay 0. BUT, if it has a value, the +100 will increase the (undesired) 0 to 100 range to the (desired) 100 to 200 range discussed.
// Let's look at our magic line again:
// (r += r && 100) || (g += g && 100);
// We know what the left side of the || does; the right side does the same thing.
// The || has an opposite effect to the &&. || needs only one side to be true to return true; since we evaluate from left to right, if the left side returns anything other than 0 (in other words, if r has a value), we skip over the right side. We can do this because we already know that if red has a value, green must be 0. The || is included so that we avoid the unnecessary calculation of g = 0 + 0 when red has a value.
// Finally, we set the body's background-color to use r and g
// bs.backgroundColor = 'rgb(' + r + ',' + g + ',' + (r+g)/2 + ')';
//}, false);
// And we made it!!! Please comment if anything requires clarification, if you have suggestions on how my code can be improved (or made even grosser), or if you just want to chat.
// Until next time,
// rileyjshaw.com
/* Bare code: */ //////////////////////////////////
var bs = document.body.style;
document.getElementById('slider').addEventListener('change', function () {
val = parseInt(this.value);
aval = Math.abs(val);
(r = aval - val) ? r += 90 : 0;
(g = aval + val) ? g += 90 : 0;
bs.backgroundColor = 'rgb(' + r + ',' + g + ',' + (r+g)/2 + ')';
}, false);
///////////////////////////////////////////////
@import "compass"
html, body, input
height: 100%
width: 100%
body
background: #000

Worst Practices (thoroughly commented)

Some Javascript that I threw together for a friend to 1) solve his problem, 2) explain some hacky JS tricks, and 3) attempt to show him that they aren't always great to use since they obfuscate your code.

There's actually some cool stuff going on in here, so I've commented it thoroughly. Please let me know if anything requires clarification, if you have suggestions on how my code can be improved (or made even grosser), or if you just want to chat!

A Pen by Riley Shaw on CodePen.

License.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment