aboutsummaryrefslogblamecommitdiffstats
path: root/stylesheets/base/linear-gradient.scss
blob: e63eba8006ae0ea4432dcc95e358bdf3eb0723a2 (plain) (tree)





























































































































































































                                                                                                                                                                                                 
                                                                                                                                                      

 
/// Equivelant of JS parseInt()
/// @author Benji Greig
/// @param {string | number} $value - Value to convert
/// @return unitless {Number}
@function parse-int($n) {
    @return $n/($n * 0+1);
}

/// Convert angle
/// @author Chris Eppstein
/// @param {Number} $value - Value to convert
/// @param {String} $unit - Unit to convert to
/// @return {Number} Converted angle
@function convert-angle($value, $unit) {
    $convertable-units: deg grad turn rad;
    $conversion-factors: 1 (10grad/9deg) (1turn/360deg) (3.1415926rad/180deg);
    @if index($convertable-units, unit($value)) and index($convertable-units, $unit) {
	@return $value
        / nth($conversion-factors, index($convertable-units, unit($value)))
        * nth($conversion-factors, index($convertable-units, $unit));
    }

    @warn "Cannot convert `#{unit($value)}` to `#{$unit}`.";
}

/// Test if `$value` is an angle
/// @param {*} $value - Value to test
/// @return {Bool}
@function is-direction($value) {
    $is-direction: index((to top, to top right, to right top, to right, to bottom right, to right bottom, to bottom, to bottom left, to left bottom, to left, to left top, to top left), $value);
    $is-angle: type-of($value) == 'number' and index('deg' 'grad' 'turn' 'rad', unit($value));

    @return $is-direction or $is-angle;
}

/// Convert a direction to legacy syntax
/// @param {Keyword | Angle} $value - Value to convert
/// @require {function} is-direction
/// @require {function} convert-angle
@function legacy-direction($value) {
    @if is-direction($value) == false {
        @warn "Cannot convert `#{$value}` to legacy syntax because it doesn't seem to be an angle or a direction";
    }

    $conversion-map: (
        to top          : bottom,
        to top right    : bottom left,
        to right top    : left bottom,
        to right        : left,
        to bottom right : top left,
        to right bottom : left top,
        to bottom       : top,
        to bottom left  : top right,
        to left bottom  : right top,
        to left         : right,
        to left top     : right bottom,
        to top left     : bottom right
    );

    @if map-has-key($conversion-map, $value) {
        @return map-get($conversion-map, $value);
    }

    @return $value;//90deg - convert-angle($value, 'deg');
}

/// Convert a degrees to legacy syntax
/// @param {Angle} $value - Value to convert
/// @require {parse-int} parse-int
@function degrees-to-direction($angleIn){

    $angle: parse-int($angleIn);
    $direction: '';

    @if ($angle < 0 or $angle > 360) {
	@warn "Enter a degree between 0 and 360 degrees.";
    }

    @if ($angle >= 0 and $angle <= 11.25) { $direction: to top; }
    @if ($angle > 348.75 and $angle <= 360) { $direction: to top; }
    @if ($angle > 11.25 and $angle <= 33.75) { $direction: to top right; }
    @if ($angle > 33.75 and $angle <= 56.25) { $direction: to right top; }
    @if ($angle > 56.25 and $angle <= 78.75) { $direction: to right top; }
    @if ($angle > 78.75 and $angle <= 101.25) { $direction: to right; }
    @if ($angle > 101.25 and $angle <= 123.75) { $direction: to bottom right; }
    @if ($angle > 123.75 and $angle <= 146.25) { $direction: to right bottom; }
    @if ($angle > 146.25 and $angle <= 168.75) { $direction: to right bottom; }
    @if ($angle > 168.75 and $angle <= 191.25) { $direction: to bottom; }
    @if ($angle > 191.25 and $angle <= 213.75) { $direction: to bottom left; }
    @if ($angle > 213.75 and $angle <= 236.25) { $direction: to left bottom ; }
    @if ($angle > 236.25 and $angle <= 258.75) { $direction: to left bottom ; }
    @if ($angle > 258.75 and $angle <= 281.25) { $direction: to left; }
    @if ($angle > 281.25 and $angle <= 303.75) { $direction: to left top; }
    @if ($angle > 303.75 and $angle <= 326.25) { $direction: to top left; }
    @if ($angle > 326.25 and $angle <= 348.75) { $direction: to top left; }

    @return $direction;
}

/// Convert a direction to either horizontal/vertical (1/0) or flip values (true/false)
/// @param {Angle} $value - Value to convert
/// @require {is-direction} is-direction
/// @require {degrees-to-direction} degrees-to-direction
@function ie-direction($value, $posneg:false) {
    @if is-direction($value) == false {
        @warn "Cannot convert `#{$value}` to legacy syntax because it doesn't seem to be an angle or a direction";
    }

    $conversion-map: (
        to top          : 0,
        to top right    : 0,
        to right top    : 1,
        to right        : 1,
        to bottom right : 1,
        to right bottom : 0,
        to bottom       : 0,
        to bottom left  : 0,
        to left bottom  : 1,
        to left         : 1,
        to left top     : 1,
        to top left     : 0
    );

    $flip-map: (
        to top          : true,
        to top right    : true,
        to right top    : false,
        to right        : false,
        to bottom right : false,
        to right bottom : false,
        to bottom       : false,
        to bottom left  : false,
        to left bottom  : true,
        to left         : true,
        to left top     : true,
        to top left     : false
    );

    //If we want to know just the order to flip the values
    @if $posneg == true and map-has-key($flip-map, $value) {
        @return map-get($flip-map, $value);
    } @else if $posneg == true {
	$converted: degrees-to-direction( convert-angle($value, 'deg') );

	@if map-has-key($flip-map, $converted) {
	    @return map-get($flip-map, $converted);
	}
    }

    //If we want to know the value for IE
    @if map-has-key($conversion-map, $value) {
        @return map-get($conversion-map, $value);
    } @else {
	$converted: degrees-to-direction( convert-angle($value, 'deg') );

	@if map-has-key($conversion-map, $converted) {
	    @return map-get($conversion-map, $converted);
	}
    }
}

/// Mixin printing a linear-gradient
/// as well as a plain color fallback
/// and the older prefixed declarations
/// @access public
/// @param {String | List | Angle} $direction - Linear gradient direction
/// @param {Arglist} $color-stops - List of color-stops composing the gradient
@mixin linear-gradient($direction, $color-stops...) {
    @if is-direction($direction) == false {
	$direction: 180deg;
    }

    //Convert the colour values into IE filter compatible
    $ieStartColor: ie-hex-str( nth(nth($color-stops, 1), 1) );
    $ieEndColor: ie-hex-str( nth(nth($color-stops, -1), 1) );

    @if ie-direction($direction,true) {
	$ieEndColor: ie-hex-str( nth(nth($color-stops, 1), 1) );
	$ieStartColor: ie-hex-str( nth(nth($color-stops, -1), 1) );
    }

    //$ieEndColor: $ieEndColor-step3;
    $ieDirection: ie-direction($direction);

    background: nth(nth($color-stops, 1), 1);
    background: -moz-linear-gradient(legacy-direction($direction), $color-stops);
    background: -webkit-gradient(legacy-direction($direction), $color-stops);
    background: -o-linear-gradient(legacy-direction($direction), $color-stops);
    background: -ms-linear-gradient(legacy-direction($direction), $color-stops);
    background: linear-gradient($direction, $color-stops);
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#{$ieStartColor}', endColorstr='#{$ieEndColor}', GradientType=#{$ieDirection} );

}