You are here

public static function SassScriptFunctions::mix in Sassy 7.3

Same name and namespace in other branches
  1. 7 phamlp/sass/script/SassScriptFunctions.php \SassScriptFunctions::mix()

Mixes two colours together. Takes the average of each of the RGB components, optionally weighted by the given percentage. The opacity of the colours is also considered when weighting the components. The weight specifies the amount of the first colour that should be included in the returned colour. The default, 50%, means that half the first colour and half the second colour should be used. 25% means that a quarter of the first colour and three quarters of the second colour should be used. For example: mix(#f00, #00f) => #7f007f mix(#f00, #00f, 25%) => #3f00bf mix(rgba(255, 0, 0, 0.5), #00f) => rgba(63, 0, 191, 0.75)

Parameters

SassColour The first colour:

SassColour The second colour:

float Percentage of the first colour to use:

Return value

new SassColour The mixed colour

Throws

SassScriptFunctionException If $colour1 or $colour2 is not a colour

File

phpsass/script/SassScriptFunctions.php, line 480

Class

SassScriptFunctions
SassScript functions class. A collection of functions for use in SassSCript. @package PHamlP @subpackage Sass.script

Code

public static function mix($colour1, $colour2, $weight = null) {
  if (is_null($weight)) {
    $weight = new SassNumber('50%');
  }
  SassLiteral::assertType($colour1, 'SassColour');
  SassLiteral::assertType($colour2, 'SassColour');
  SassLiteral::assertType($weight, 'SassNumber');
  SassLiteral::assertInRange($weight, 0, 100, '%');

  /*
   * This algorithm factors in both the user-provided weight
   * and the difference between the alpha values of the two colours
   * to decide how to perform the weighted average of the two RGB values.
   *
   * It works by first normalizing both parameters to be within [-1, 1],
   * where 1 indicates "only use colour1", -1 indicates "only use colour 0",
   * and all values in between indicated a proportionately weighted average.
   *
   * Once we have the normalized variables w and a,
   * we apply the formula (w + a)/(1 + w*a)
   * to get the combined weight (in [-1, 1]) of colour1.
   * This formula has two especially nice properties:
   *
   * * When either w or a are -1 or 1, the combined weight is also that number
   *  (cases where w * a == -1 are undefined, and handled as a special case).
   *
   * * When a is 0, the combined weight is w, and vice versa
   *
   * Finally, the weight of colour1 is renormalized to be within [0, 1]
   * and the weight of colour2 is given by 1 minus the weight of colour1.
   */
  $p = $weight->value / 100;
  $w = $p * 2 - 1;
  $a = $colour1->alpha - $colour2->alpha;
  $w1 = (($w * $a == -1 ? $w : ($w + $a) / (1 + $w * $a)) + 1) / 2;
  $w2 = 1 - $w1;
  $rgb1 = $colour1
    ->rgb();
  $rgb2 = $colour2
    ->rgb();
  $rgba = array();
  foreach ($rgb1 as $key => $value) {
    $rgba[$key] = $value * $w1 + $rgb2[$key] * $w2;
  }

  // foreach
  $rgba[] = $colour1->alpha * $p + $colour2->alpha * (1 - $p);
  return new SassColour($rgba);
}