You are here

public static function SassScriptFunctions::mix in Sassy 7

Same name and namespace in other branches
  1. 7.3 phpsass/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: * @param SassColour The second colour * @param float Percentage of the first colour to use * @return new SassColour The mixed colour * @throws SassScriptFunctionException If $colour1 or $colour2 is * not a colour

File

phamlp/sass/script/SassScriptFunctions.php, line 473

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);
}