From f0f84513f8efe533b6ee670a6f1a0c074387b2ec Mon Sep 17 00:00:00 2001 From: Volpeon Date: Wed, 13 Aug 2025 12:01:46 +0200 Subject: Make use of SASS modules --- src/_gradients.scss | 791 ++++++++++++++++++++++++++-------------------------- 1 file changed, 393 insertions(+), 398 deletions(-) (limited to 'src/_gradients.scss') diff --git a/src/_gradients.scss b/src/_gradients.scss index 6575482..345a9f1 100644 --- a/src/_gradients.scss +++ b/src/_gradients.scss @@ -15,8 +15,11 @@ /// @access public //// +@use 'sass:color'; +@use 'sass:list'; @use 'sass:math'; @use 'sass:meta'; +@use 'sass:string'; @use './functions'; @use './easing'; @@ -135,144 +138,136 @@ $easing-gradient-steps: 10 !default; /// } /// @function easing-gradient($type, $dir, $stop, $stops...) { - $pos-template: null; - $stops: functions.list-prepend($stops, $stop); - - $last-positioned-stop: 1; - $generated-stops: (); - - // - // Generate gradient - // - - @for $i from 1 through length($stops) { - $stop: nth($stops, $i); - - @if $i == 1 { - @if not easing-gradient-is-color-stop($stop) { - @error 'The first color stop argument must be a color stop.'; - } - - @if type-of($stop) == color { - // - // The first color stop is unpositioned. The default position for the first - // color stop is 0, which is explicitly added for easier calculations. - // - - $stop: $stop 0; - $stops: set-nth($stops, $i, $stop); - } - - $generated-stops: append($generated-stops, functions.str-implode($stop, ' ')); - } @else if easing-gradient-is-positioned-color-stop($stop) or ($i == length($stops)) { - @if not easing-gradient-is-color-stop($stop) { - @error 'The last color stop argument must be a color stop.'; - } - - // - // Either the current stops list item is a positioned color stop, or the end of - // the stops list has been reached. - // - - @if (type-of($stop) == color) and ($i == length($stops)) { - // - // The current stop is an unpositioned color stop, which means this is the end - // of the stops list. The default position for the last color stop is 100%, which - // is explicitly added for easier calculations. - // - - $stop: $stop 100%; - $stops: set-nth($stops, $i, $stop); - } - - // - // Now the current color stop is guaranteed to be a positioned color stop. - // - - @if $i > $last-positioned-stop + 1 { - // - // There is at least one stops list item (unpositioned color stop or easing function) - // between the last positioned color stop and the current stops list item. Interpolate - // the positions of all stops list items that are color stops. - // - - $interpolated-stops: easing-gradient-interpolate-stop-positions( - nth($stops, $last-positioned-stop), - functions.list-slice($stops, $last-positioned-stop + 1, $i - 1), - $stop - ); - - $new-stops: join( - functions.list-slice($stops, 1, $last-positioned-stop), - $interpolated-stops - ); - $new-stops: join( - $new-stops, - functions.list-slice($stops, $i) - ); - $stops: $new-stops; - } - - // - // Now all color stops between this one and the last positioned one have - // interpolated positions. - // Next task is to perform an easing transition between all color stops that - // have an easing function specified. The rest can be left alone since the - // browser will automatically apply a linear transition between them. - // - - $j: $last-positioned-stop + 1; - @while $j <= $i { - $easing: null; - $prev-stop: nth($stops, $j - 1); - $next-stop: nth($stops, $j); - - @if not easing-gradient-is-color-stop($next-stop) { - $j: $j + 1; - - $easing: $next-stop; - $next-stop: nth($stops, $j); - - @if not easing-gradient-is-color-stop($next-stop) { - @error 'There can be at most one interpolation hint between to color stops.'; - } - } - - @if $easing != null { - @if type-of($easing) == number { - @error 'Midpoint shifts are not supported.'; - } - - $easing-func: null; - $easing-args: (); - - @if type-of($easing) == list { - $easing-args: functions.list-slice($easing, 2); - $easing: nth($easing, 1); - } - - $generated-stops: join( - $generated-stops, - easing-gradient-ease-stops($prev-stop, $next-stop, $easing, $easing-args) - ); - } @else { - $generated-stops: append($generated-stops, functions.str-implode($next-stop, ' ')); - } - - $j: $j + 1; - } - - $last-positioned-stop: $i; - } - } - - @if $type == 'linear' { - @return linear-gradient($dir, unquote(functions.str-implode($generated-stops, ', '))); - } @else if $type == 'radial' { - @return radial-gradient($dir, unquote(functions.str-implode($generated-stops, ', '))); - } @else { - @error 'Invalid gradient type: #{inspect($type)}.'; - } + $pos-template: null; + $stops: functions.list-prepend($stops, $stop); + + $last-positioned-stop: 1; + $generated-stops: (); + + // + // Generate gradient + // + + @for $i from 1 through list.length($stops) { + $stop: list.nth($stops, $i); + + @if $i == 1 { + @if not easing-gradient-is-color-stop($stop) { + @error 'The first color stop argument must be a color stop.'; + } + + @if meta.type-of($stop) == color { + // + // The first color stop is unpositioned. The default position for the first + // color stop is 0, which is explicitly added for easier calculations. + // + + $stop: $stop 0; + $stops: list.set-nth($stops, $i, $stop); + } + + $generated-stops: list.append($generated-stops, functions.str-implode($stop, ' ')); + } @else if easing-gradient-is-positioned-color-stop($stop) or ($i == list.length($stops)) { + @if not easing-gradient-is-color-stop($stop) { + @error 'The last color stop argument must be a color stop.'; + } + + // + // Either the current stops list item is a positioned color stop, or the end of + // the stops list has been reached. + // + + @if (meta.type-of($stop) == color) and ($i == list.length($stops)) { + // + // The current stop is an unpositioned color stop, which means this is the end + // of the stops list. The default position for the last color stop is 100%, which + // is explicitly added for easier calculations. + // + + $stop: $stop 100%; + $stops: list.set-nth($stops, $i, $stop); + } + + // + // Now the current color stop is guaranteed to be a positioned color stop. + // + + @if $i > $last-positioned-stop + 1 { + // + // There is at least one stops list item (unpositioned color stop or easing function) + // between the last positioned color stop and the current stops list item. Interpolate + // the positions of all stops list items that are color stops. + // + + $interpolated-stops: easing-gradient-interpolate-stop-positions(list.nth($stops, $last-positioned-stop), + functions.list-slice($stops, $last-positioned-stop + 1, $i - 1), + $stop); + + $new-stops: list.join(functions.list-slice($stops, 1, $last-positioned-stop), + $interpolated-stops); + $new-stops: list.join($new-stops, + functions.list-slice($stops, $i)); + $stops: $new-stops; + } + + // + // Now all color stops between this one and the last positioned one have + // interpolated positions. + // Next task is to perform an easing transition between all color stops that + // have an easing function specified. The rest can be left alone since the + // browser will automatically apply a linear transition between them. + // + + $j: $last-positioned-stop + 1; + @while $j <= $i { + $easing: null; + $prev-stop: list.nth($stops, $j - 1); + $next-stop: list.nth($stops, $j); + + @if not easing-gradient-is-color-stop($next-stop) { + $j: $j + 1; + + $easing: $next-stop; + $next-stop: list.nth($stops, $j); + + @if not easing-gradient-is-color-stop($next-stop) { + @error 'There can be at most one interpolation hint between to color stops.'; + } + } + + @if $easing != null { + @if meta.type-of($easing) == number { + @error 'Midpoint shifts are not supported.'; + } + + $easing-func: null; + $easing-args: (); + + @if meta.type-of($easing) == list { + $easing-args: functions.list-slice($easing, 2); + $easing: list.nth($easing, 1); + } + + $generated-stops: list.join($generated-stops, + easing-gradient-ease-stops($prev-stop, $next-stop, $easing, $easing-args)); + } @else { + $generated-stops: list.append($generated-stops, functions.str-implode($next-stop, ' ')); + } + + $j: $j + 1; + } + + $last-positioned-stop: $i; + } + } + + @if $type == 'linear' { + @return linear-gradient($dir, string.unquote(functions.str-implode($generated-stops, ', '))); + } @else if $type == 'radial' { + @return radial-gradient($dir, string.unquote(functions.str-implode($generated-stops, ', '))); + } @else { + @error 'Invalid gradient type: #{inspect($type)}.'; + } } /// @@ -281,7 +276,7 @@ $easing-gradient-steps: 10 !default; /// @see {function} easing-gradient /// @function easing-linear-gradient($dir, $stop, $stops...) { - @return easing-gradient('linear', $dir, $stop, $stops...); + @return easing-gradient('linear', $dir, $stop, $stops...); } /// @@ -290,7 +285,7 @@ $easing-gradient-steps: 10 !default; /// @see {function} easing-gradient /// @function easing-radial-gradient($dir, $stop, $stops...) { - @return easing-gradient('radial', $dir, $stop, $stops...); + @return easing-gradient('radial', $dir, $stop, $stops...); } /// @@ -299,24 +294,24 @@ $easing-gradient-steps: 10 !default; /// @access private /// @function easing-gradient-ease-stops($prev-stop, $next-stop, $easing, $easing-args: ()) { - @if $easing == 'steps' { - $steps: null; - $jump: null; - - @if length($easing-args) > 1 { - $steps: nth($easing-args, 1); - $jump: nth($easing-args, 2); - } @else { - $steps: nth($easing-args, 1); - $jump: jump-end; - } - - @return easing-gradient-steps-stops($prev-stop, $next-stop, $steps, $jump); - } @else { - $easing-func: get-function($easing, $module: easing); - - @return easing-gradient-bezier-stops($prev-stop, $next-stop, $easing-func, $easing-args); - } + @if $easing == 'steps' { + $steps: null; + $jump: null; + + @if list.length($easing-args) > 1 { + $steps: list.nth($easing-args, 1); + $jump: list.nth($easing-args, 2); + } @else { + $steps: list.nth($easing-args, 1); + $jump: jump-end; + } + + @return easing-gradient-steps-stops($prev-stop, $next-stop, $steps, $jump); + } @else { + $easing-func: meta.get-function($easing, $module: easing); + + @return easing-gradient-bezier-stops($prev-stop, $next-stop, $easing-func, $easing-args); + } } /// @@ -325,74 +320,74 @@ $easing-gradient-steps: 10 !default; /// @access private /// @function easing-gradient-bezier-stops($prev-stop, $next-stop, $easing-func, $easing-args: ()) { - $prev-stop-color: nth($prev-stop, 1); - $prev-stop-pos: nth($prev-stop, 2); - $next-stop-color: nth($next-stop, 1); - $next-stop-pos: nth($next-stop, 2); - - $stops: (); - - @if ((type-of($prev-stop-pos) == number) and (type-of($next-stop-pos) == number) and (unit($prev-stop-pos) == unit($next-stop-pos))) or ($prev-stop-pos == 0) or ($next-stop-pos == 0) { - // - // The transition color stop positions can be statically calculated. - // - - $distance: $next-stop-pos - $prev-stop-pos; - - @for $i from 1 through $easing-gradient-steps { - $perc: math.div($i, $easing-gradient-steps); - - $color: null; - $pos: $prev-stop-pos + $perc * $distance; - @if $perc == 1 { - $color: $next-stop-color; - } @else { - $color: mix($next-stop-color, $prev-stop-color, call($easing-func, append($easing-args, $perc)...) * 100%); - } - - $stops: append($stops, $color + ' ' + $pos); - } - } @else { - // - // The transition color stop positions have to be dynamically calculated with the calc() function. - // - - @if type-of($prev-stop-pos) != number { - // must be calc() - @if type-of($prev-stop-pos) != calculation { - @error 'Invalid color stop position: #{inspect($prev-stop-pos)}'; - } - - $prev-stop-pos: meta.calc-args($prev-stop-pos); - } - - @if type-of($next-stop-pos) != number { - // must be calc() - @if type-of($next-stop-pos) != calculation { - @error 'Invalid color stop position: #{inspect($next-stop-pos)}'; - } - - $next-stop-pos: meta.calc-args($next-stop-pos); - } - - @for $i from 1 through $easing-gradient-steps { - $perc: math.div($i, $easing-gradient-steps); - - $color: null; - $pos: null; - @if $perc == 1 { - $color: $next-stop-color; - $pos: calc(#{$next-stop-pos}); - } @else { - $color: mix($next-stop-color, $prev-stop-color, call($easing-func, append($easing-args, $perc)...) * 100%); - $pos: calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$perc}); - } - - $stops: append($stops, $color + ' ' + $pos); - } - } - - @return $stops; + $prev-stop-color: list.nth($prev-stop, 1); + $prev-stop-pos: list.nth($prev-stop, 2); + $next-stop-color: list.nth($next-stop, 1); + $next-stop-pos: list.nth($next-stop, 2); + + $stops: (); + + @if ((meta.type-of($prev-stop-pos) == number) and (meta.type-of($next-stop-pos) == number) and (math.unit($prev-stop-pos) == math.unit($next-stop-pos))) or ($prev-stop-pos == 0) or ($next-stop-pos == 0) { + // + // The transition color stop positions can be statically calculated. + // + + $distance: $next-stop-pos - $prev-stop-pos; + + @for $i from 1 through $easing-gradient-steps { + $perc: math.div($i, $easing-gradient-steps); + + $color: null; + $pos: $prev-stop-pos + $perc * $distance; + @if $perc == 1 { + $color: $next-stop-color; + } @else { + $color: color.mix($next-stop-color, $prev-stop-color, meta.call($easing-func, list.append($easing-args, $perc)...) * 100%); + } + + $stops: list.append($stops, $color + ' ' + $pos); + } + } @else { + // + // The transition color stop positions have to be dynamically calculated with the calc() function. + // + + @if meta.type-of($prev-stop-pos) != number { + // must be calc() + @if meta.type-of($prev-stop-pos) != calculation { + @error 'Invalid color stop position: #{inspect($prev-stop-pos)}'; + } + + $prev-stop-pos: meta.calc-args($prev-stop-pos); + } + + @if meta.type-of($next-stop-pos) != number { + // must be calc() + @if meta.type-of($next-stop-pos) != calculation { + @error 'Invalid color stop position: #{inspect($next-stop-pos)}'; + } + + $next-stop-pos: meta.calc-args($next-stop-pos); + } + + @for $i from 1 through $easing-gradient-steps { + $perc: math.div($i, $easing-gradient-steps); + + $color: null; + $pos: null; + @if $perc == 1 { + $color: $next-stop-color; + $pos: calc(#{$next-stop-pos}); + } @else { + $color: color.mix($next-stop-color, $prev-stop-color, meta.call($easing-func, list.append($easing-args, $perc)...) * 100%); + $pos: calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$perc}); + } + + $stops: list.append($stops, $color + ' ' + $pos); + } + } + + @return $stops; } /// @@ -401,110 +396,110 @@ $easing-gradient-steps: 10 !default; /// @access private /// @function easing-gradient-steps-stops($prev-stop, $next-stop, $steps, $jump: jump-end) { - $prev-stop-color: nth($prev-stop, 1); - $prev-stop-pos: nth($prev-stop, 2); - $next-stop-color: nth($next-stop, 1); - $next-stop-pos: nth($next-stop, 2); - - $stops: (); - - @if ((type-of($prev-stop-pos) == number) and (type-of($next-stop-pos) == number) and (unit($prev-stop-pos) == unit($next-stop-pos))) or ($prev-stop-pos == 0) or ($next-stop-pos == 0) { - // - // The transition color stop positions can be statically calculated. - // - - $distance: $next-stop-pos - $prev-stop-pos; - - @for $i from 1 through $steps { - $x1: math.div($i - 1, $steps); - $x2: math.div($i, $steps); - $y: null; - - @if $jump == jump-start { - $y: math.div($i, $steps); - } @else if $jump == jump-end { - $y: math.div($i - 1, $steps); - } @else if $jump == jump-both { - $y: math.div($i, $steps + 1); - } @else if $jump == jump-none { - $y: math.div($i - 1, $steps - 1); - } @else { - @error 'Invalid $jump: #{inspect($jump)}'; - } - - $color: null; - $pos1: if($x1 == 0, $prev-stop-pos, $prev-stop-pos + $x1 * $distance); - $pos2: if($x2 == 1, $next-stop-pos, $prev-stop-pos + $x2 * $distance); - - @if $y == 0 { - $color: $prev-stop-color; - } @else if $y == 1 { - $color: $next-stop-color; - } @else { - $color: mix($next-stop-color, $prev-stop-color, $y * 100%); - } - - $stops: append($stops, $color + ' ' + $pos1); - $stops: append($stops, $color + ' ' + $pos2); - } - } @else { - // - // The transition color stop positions have to be dynamically calculated with the calc() function. - // - - @if type-of($prev-stop-pos) != number { - // must be calc() - @if type-of($prev-stop-pos) != calculation { - @error 'Invalid color stop position: #{inspect($prev-stop-pos)}'; - } - - $prev-stop-pos: meta.calc-args($prev-stop-pos); - } - - @if type-of($next-stop-pos) != number { - // must be calc() - @if type-of($next-stop-pos) != calculation { - @error 'Invalid color stop position: #{inspect($next-stop-pos)}'; - } - - $next-stop-pos: meta.calc-args($next-stop-pos); - } - - @for $i from 1 through $steps { - $x1: math.div($i - 1, $steps); - $x2: math.div($i, $steps); - $y: null; - - @if $jump == jump-start { - $y: math.div($i, $steps); - } @else if $jump == jump-end { - $y: math.div($i - 1, $steps); - } @else if $jump == jump-both { - $y: math.div($i, $steps + 1); - } @else if $jump == jump-none { - $y: math.div($i - 1, $steps - 1); - } @else { - @error 'Invalid $jump: #{inspect($jump)}'; - } - - $color: null; - $pos1: if($x1 == 0, $prev-stop-pos, calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$x1})); - $pos2: if($x2 == 1, $next-stop-pos, calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$x2})); - - @if $y == 0 { - $color: $prev-stop-color; - } @else if $y == 1 { - $color: $next-stop-color; - } @else { - $color: mix($next-stop-color, $prev-stop-color, $y * 100%); - } - - $stops: append($stops, $color + ' ' + $pos1); - $stops: append($stops, $color + ' ' + $pos2); - } - } - - @return $stops; + $prev-stop-color: list.nth($prev-stop, 1); + $prev-stop-pos: list.nth($prev-stop, 2); + $next-stop-color: list.nth($next-stop, 1); + $next-stop-pos: list.nth($next-stop, 2); + + $stops: (); + + @if ((meta.type-of($prev-stop-pos) == number) and (meta.type-of($next-stop-pos) == number) and (math.unit($prev-stop-pos) == math.unit($next-stop-pos))) or ($prev-stop-pos == 0) or ($next-stop-pos == 0) { + // + // The transition color stop positions can be statically calculated. + // + + $distance: $next-stop-pos - $prev-stop-pos; + + @for $i from 1 through $steps { + $xx1: math.div($i - 1, $steps); + $xx2: math.div($i, $steps); + $y: null; + + @if $jump == jump-start { + $y: math.div($i, $steps); + } @else if $jump == jump-end { + $y: math.div($i - 1, $steps); + } @else if $jump == jump-both { + $y: math.div($i, $steps + 1); + } @else if $jump == jump-none { + $y: math.div($i - 1, $steps - 1); + } @else { + @error 'Invalid $jump: #{inspect($jump)}'; + } + + $color: null; + $pos1: if($xx1 == 0, $prev-stop-pos, $prev-stop-pos + $xx1 * $distance); + $pos2: if($xx2 == 1, $next-stop-pos, $prev-stop-pos + $xx2 * $distance); + + @if $y == 0 { + $color: $prev-stop-color; + } @else if $y == 1 { + $color: $next-stop-color; + } @else { + $color: color.mix($next-stop-color, $prev-stop-color, $y * 100%); + } + + $stops: list.append($stops, $color + ' ' + $pos1); + $stops: list.append($stops, $color + ' ' + $pos2); + } + } @else { + // + // The transition color stop positions have to be dynamically calculated with the calc() function. + // + + @if meta.type-of($prev-stop-pos) != number { + // must be calc() + @if meta.type-of($prev-stop-pos) != calculation { + @error 'Invalid color stop position: #{inspect($prev-stop-pos)}'; + } + + $prev-stop-pos: meta.calc-args($prev-stop-pos); + } + + @if meta.type-of($next-stop-pos) != number { + // must be calc() + @if meta.type-of($next-stop-pos) != calculation { + @error 'Invalid color stop position: #{inspect($next-stop-pos)}'; + } + + $next-stop-pos: meta.calc-args($next-stop-pos); + } + + @for $i from 1 through $steps { + $xx1: math.div($i - 1, $steps); + $xx2: math.div($i, $steps); + $y: null; + + @if $jump == jump-start { + $y: math.div($i, $steps); + } @else if $jump == jump-end { + $y: math.div($i - 1, $steps); + } @else if $jump == jump-both { + $y: math.div($i, $steps + 1); + } @else if $jump == jump-none { + $y: math.div($i - 1, $steps - 1); + } @else { + @error 'Invalid $jump: #{inspect($jump)}'; + } + + $color: null; + $pos1: if($xx1 == 0, $prev-stop-pos, calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$xx1})); + $pos2: if($xx2 == 1, $next-stop-pos, calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$xx2})); + + @if $y == 0 { + $color: $prev-stop-color; + } @else if $y == 1 { + $color: $next-stop-color; + } @else { + $color: color.mix($next-stop-color, $prev-stop-color, $y * 100%); + } + + $stops: list.append($stops, $color + ' ' + $pos1); + $stops: list.append($stops, $color + ' ' + $pos2); + } + } + + @return $stops; } /// @@ -513,72 +508,72 @@ $easing-gradient-steps: 10 !default; /// @access private /// @function easing-gradient-interpolate-stop-positions($prev-stop, $stops, $next-stop) { - $prev-stop-pos: nth($prev-stop, 2); - $next-stop-pos: nth($next-stop, 2); - - $stops-num: 0; - @for $i from 1 through length($stops) { - $stop: nth($stops, $i); - @if easing-gradient-is-color-stop($stop) { - $stops-num: $stops-num + 1; - } - } - - $i: 1; - $cur-stop-num: 1; - - @if ((type-of($prev-stop-pos) == number) and (type-of($next-stop-pos) == number) and (unit($prev-stop-pos) == unit($next-stop-pos))) or ($prev-stop-pos == 0) or ($next-stop-pos == 0) { - // - // The color stop positions can be statically calculated. - // - - $distance: $next-stop-pos - $prev-stop-pos; - - @for $i from 1 through length($stops) { - $stop: nth($stops, $i); - @if easing-gradient-is-color-stop($stop) { - $pos: $prev-stop-pos + math.div($distance, $stops-num + 1) * $cur-stop-num; - $stops: set-nth($stops, $i, $stop $pos); - - $cur-stop-num: $cur-stop-num + 1; - } - } - } @else { - // - // The color stop positions have to be dynamically calculated with the calc() function. - // - - @if type-of($prev-stop-pos) != number { - // must be calc() - @if type-of($prev-stop-pos) != calculation { - @error 'Invalid color stop position: #{inspect($prev-stop-pos)}'; - } - - $prev-stop-pos: meta.calc-args($prev-stop-pos); - } - - @if type-of($next-stop-pos) != number { - // must be calc() - @if type-of($next-stop-pos) != calculation { - @error 'Invalid color stop position: #{inspect($next-stop-pos)}'; - } - - $next-stop-pos: meta.calc-args($next-stop-pos); - } - - @for $i from 1 through length($stops) { - $stop: nth($stops, $i); - @if easing-gradient-is-color-stop($stop) { - $perc: math.div($cur-stop-num, $stops-num + 1); - $pos: calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$perc}); - $stops: set-nth($stops, $i, $stop $pos); - - $cur-stop-num: $cur-stop-num + 1; - } - } - } - - @return $stops; + $prev-stop-pos: list.nth($prev-stop, 2); + $next-stop-pos: list.nth($next-stop, 2); + + $stops-num: 0; + @for $i from 1 through list.length($stops) { + $stop: list.nth($stops, $i); + @if easing-gradient-is-color-stop($stop) { + $stops-num: $stops-num + 1; + } + } + + $i: 1; + $cur-stop-num: 1; + + @if ((meta.type-of($prev-stop-pos) == number) and (meta.type-of($next-stop-pos) == number) and (math.unit($prev-stop-pos) == math.unit($next-stop-pos))) or ($prev-stop-pos == 0) or ($next-stop-pos == 0) { + // + // The color stop positions can be statically calculated. + // + + $distance: $next-stop-pos - $prev-stop-pos; + + @for $i from 1 through list.length($stops) { + $stop: list.nth($stops, $i); + @if easing-gradient-is-color-stop($stop) { + $pos: $prev-stop-pos + math.div($distance, $stops-num + 1) * $cur-stop-num; + $stops: list.set-nth($stops, $i, $stop $pos); + + $cur-stop-num: $cur-stop-num + 1; + } + } + } @else { + // + // The color stop positions have to be dynamically calculated with the calc() function. + // + + @if meta.type-of($prev-stop-pos) != number { + // must be calc() + @if meta.type-of($prev-stop-pos) != calculation { + @error 'Invalid color stop position: #{inspect($prev-stop-pos)}'; + } + + $prev-stop-pos: meta.calc-args($prev-stop-pos); + } + + @if meta.type-of($next-stop-pos) != number { + // must be calc() + @if meta.type-of($next-stop-pos) != calculation { + @error 'Invalid color stop position: #{inspect($next-stop-pos)}'; + } + + $next-stop-pos: meta.calc-args($next-stop-pos); + } + + @for $i from 1 through list.length($stops) { + $stop: list.nth($stops, $i); + @if easing-gradient-is-color-stop($stop) { + $perc: math.div($cur-stop-num, $stops-num + 1); + $pos: calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$perc}); + $stops: list.set-nth($stops, $i, $stop $pos); + + $cur-stop-num: $cur-stop-num + 1; + } + } + } + + @return $stops; } /// @@ -587,7 +582,7 @@ $easing-gradient-steps: 10 !default; /// @access private /// @function easing-gradient-is-color-stop($input) { - @return (type-of($input) == color) or easing-gradient-is-positioned-color-stop($input); + @return (meta.type-of($input) == color) or easing-gradient-is-positioned-color-stop($input); } /// @@ -596,5 +591,5 @@ $easing-gradient-steps: 10 !default; /// @access private /// @function easing-gradient-is-positioned-color-stop($input) { - @return (type-of($input) == list) and (type-of(nth($input, 1)) == color); + @return (meta.type-of($input) == list) and (meta.type-of(list.nth($input, 1)) == color); } -- cgit v1.2.3-70-g09d2