背景色に対して読みやすい文字色を選択するfunction

https://katashin.info/2018/12/18/247

by bc_rikko

HTML

<span class="item black">test</span>
<span class="item silver">test</span>
<span class="item gray">test</span>
<span class="item white">test</span>
<span class="item maroon">test</span>
<span class="item red">test</span>
<span class="item purple">test</span>
<span class="item fuchsia">test</span>
<span class="item green">test</span>
<span class="item lime">test</span>
<span class="item olive">test</span>
<span class="item yellow">test</span>
<span class="item navy">test</span>
<span class="item blue">test</span>
<span class="item teal">test</span>
<span class="item aqua">test</span>

SCSS

// https://github.com/terkel/mathsass
$LN2:   0.6931471805599453;
$SQRT2: 1.4142135623730951;

@function frexp ($x) {
    $exp: 0;
    @if $x < 0 {
        $x: $x * -1;
    }
    @if $x < 0.5 {
        @while $x < 0.5 {
            $x: $x * 2;
            $exp: $exp - 1;
        }
    } @else if $x >= 1 {
        @while $x >= 1 {
            $x: $x / 2;
            $exp: $exp + 1;
        }
    }
    @return $x, $exp;
}

@function ldexp ($x, $exp) {
    $b: if($exp >= 0, 2, 1 / 2);
    @if $exp < 0 {
        $exp: $exp * -1;
    }
    @while $exp > 0 {
        @if $exp % 2 == 1 {
            $x: $x * $b;
        }
        $b: $b * $b;
        $exp: floor($exp * 0.5);
    }
    @return $x;
}

@function log ($x, $b: null) {
    @if $b != null {
        @return log($x) / log($b);
    }

    @if $x <= 0 {
        @return 0 / 0;
    }
    $k: nth(frexp($x / $SQRT2), 2);
    $x: $x / ldexp(1, $k);

    @return $LN2 * $k + _log($x);
}

// a good aproximation for $x close to 1
@function _log ($x) {
    $x: ($x - 1) / ($x + 1);
    $x2: $x * $x;
    $i: 1;
    $s: $x;
    $sp: null;
    @while $sp != $s {
        $x: $x * $x2;
        $i: $i + 2;
        $sp: $s;
        $s: $s + $x / $i;
    }
    @return 2 * $s;
}

@function pow ($base, $exp) {
    @if $exp == floor($exp) {
        $r: 1;
        $s: 0;
        @if $exp < 0 {
            $exp: $exp * -1;
            $s: 1;
        }
        @while $exp > 0 {
            @if $exp % 2 == 1 {
                $r: $r * $base;
            }
            $exp: floor($exp * 0.5);
            $base: $base * $base;
        }
        @return if($s != 0, 1 / $r, $r);
    } @else if $base == 0 and $exp > 0 {
        @return 0;
    } @else {
        $expint: floor($exp);
        $r1: pow($base, $expint);
        $r2: _exp(log($base) * ($exp - $expint));
        @return $r1 * $r2;
    }
}

// A good approximation for $x close to 0.
@function _exp ($x) {
    $ret: 0;
    $i: 1;
    @for $n from 0 to 24 {
        $ret: $ret + $i;
       ...