` ````
input type="range" name="slider" min="-50" max="50" id="slider"
```

` ````
@import compass
html, body, input
height: 100%
width: 100%
body
background: #000
```

` ````
// 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);
///////////////////////////////////////////////
```

999px

As a PRO member, you can drag-and-drop upload files here to use as resources. Images, Libraries, JSON data... anything you want. You can even edit them anytime, like any other code on CodePen.

Loading
..................

Alt
Opt
Find & Replace

Also see: Tab Triggers