Content-Length: 261174 | pFad | http://github.com/modularscale/modularscale-sass/issues/89

D7 Decimal powers and memoization · Issue #89 · modularscale/modularscale-sass · GitHub
Skip to content

Decimal powers and memoization #89

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jakob-e opened this issue Feb 23, 2015 · 4 comments
Closed

Decimal powers and memoization #89

jakob-e opened this issue Feb 23, 2015 · 4 comments
Labels
Milestone

Comments

@jakob-e
Copy link

jakob-e commented Feb 23, 2015

Would it be possible to implement decimal powers to produce scales like these:
http://spencermortensen.com/articles/typographic-scale/

Maybe this could be done by switching to mathsass and perhaps considering memoization to speed things up a bit.

Tests:
memoization disabled
memoization enabled

Thanks and keep up the good work 👍

@scottkellum
Copy link
Member

I’ve done a bit of testing with this a while back and performance is just bad, even in libsass. I may re-visit but until we get native pow() in Sass I’m not convinced this is ready for production. Note that it works fine if you install via Compass because Compass has an actual pow() function that I detect for and rout through.

At the moment, I’d rather push on Sass to include this much needed feature than to implement a sub-optimal work-around that may cause peoples projects to hang.

@scottkellum scottkellum added this to the 3.0 milestone Aug 30, 2015
@scottkellum
Copy link
Member

Pushing this off to 3.1 or only enabling via external lib. Complexities of this feature are getting in the way of other important 3.0 work.

@scottkellum scottkellum modified the milestone: 3.0 Oct 17, 2015
@scottkellum
Copy link
Member

Yup, you’ll be able to add this functionality easily in the next version by including a lib like mathsass, but not out of the box.

@jakob-e
Copy link
Author

jakob-e commented Oct 21, 2018

...three years later ;-)

If this is still on for a future version I found a super fast° pow function:
https://github.com/xi/sass-planifolia/edit/master/sass/math.scss

° fast of course is relative and depends on compiler. My tests on LibSass (CodeKit)
handles 10,000 calculations in about 3 seconds.

If you want to limit the implementation to only include pow here is a stripped down version:

$☠️--math-steps: 32 !default; 
@function pow($x, $exponent, $steps: $☠️--math-steps) {
    $exp1: round($exponent);                
    $exp2: $exponent - $exp1;               
    $pow1: ☠️--pow-int($x, $exp1);          
    @if $exp2 == 0 { @return $pow1; }       
    @else if $x == 0 and $exponent > 0 { @return 0; }   
    @else {
        $y: ☠️--log($x, $steps) * $exp2;
        $pow2: ☠️--exp-taylor-0($y, $steps);
        @return $pow1 * $pow2;
    }
}

//  private helper functions
@function ☠️--log($x, $steps: $☠️--math-steps) {
    $log10: 2.302585092994046; 
    $approx: ☠️--log10-approx($x);
    // $y is in range [1, 10]
    $y: $x / ☠️--pow-int(10, $approx);
    @return $approx * $log10 + ☠️--log-taylor-1($y, $steps);
}

@function ☠️--pow-int($base, $exponent) {
    @if $exponent < 0 { @return 1 / ☠️--pow-int($base, -$exponent); } 
    @else if $exponent == 0 { @return 1; } 
    @else if $exponent == 1 { @return $base; } 
    @else {
        $exp: floor($exponent / 2);
        $pow: ☠️--pow-int($base, $exp);
        @if $exp * 2 == $exponent { @return $pow * $pow; } 
        @else { @return $pow * $pow * $base; }
    }
}
@function ☠️--log10-approx($x) {
    @if $x <= 0 { @error 'cannot calculate log of #{$x}'; } 
    // choose the smaller option (-1) because it yields better results in log().
    @else if $x >= 1 { @return str-length(inspect(round($x))) - 1; } 
    @else { @return -1 * str-length(inspect(round(1 / $x))); }
}
@function ☠️--exp-taylor-0($x, $steps) {
    $item: 1;
    $result: 1;
    @for $i from 1 to $steps {
        $item: $item * $x / $i;
        $result: $result + $item;
    }
    @return $result;
}
@function ☠️--log-taylor-1($x, $steps) {
    $z: ($x - 1) / ($x + 1);
    $power: $z;
    $result: $z;
    @for $i from 1 to $steps {
        $power: $power * $z * $z;
        $result: $result + $power / (2 * $i + 1);
    }
    @return 2 * $result;
}

Example (based on http://spencermortensen.com/articles/typographic-scale/)

golden-scale {
    $r: 1.61803398874989484820; // ratio: phi
    $n: 2;                      // notes: number of notes 
    @for $i from -5 through 5 {
        scale-#{$i+5}: pow($r, $i/$n);
    }
}

Output:

golden-scale {
  scale-0: 0.300283106;
  scale-1: 0.3819660113;
  scale-2: 0.4858682718;
  scale-3: 0.6180339887;
  scale-4: 0.7861513778;
  scale-5: 1;
  scale-6: 1.2720196495;
  scale-7: 1.6180339887;
  scale-8: 2.0581710273;
  scale-9: 2.6180339887;
  scale-10: 3.3301906768;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/modularscale/modularscale-sass/issues/89

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy