cssAudio - Activefile-genericCSS - ActiveGeneric - ActiveHTML - ActiveImage - ActiveJS - ActiveSVG - ActiveText - Activefile-genericVideo - ActiveLovehtmlicon-new-collectionicon-personicon-teamlog-outoctocatpop-outspinnerstartv

Pen Settings

CSS Base

Vendor Prefixing

Add External CSS

These stylesheets will be added in this order and before the code you write in the CSS editor. You can also add another Pen here, and it will pull the CSS from it. Try typing "font" or "ribbon" below.

Quick-add: + add another resource

Add External JavaScript

These scripts will run in this order and before the code in the JavaScript editor. You can also link to another Pen here, and it will run the JavaScript from it. Also try typing the name of any popular library.

Quick-add: + add another resource

Code Indentation

     

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

            
              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
Loading ..................

Console