Skip to content
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

Full support of non-integer exponents in all sass variations #113

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
*.lock

stylesheets/modular-scale.zip

node_modules
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,8 @@
"bugs": {
"url": "https://github.com/modularscale/modularscale-sass/issues"
},
"homepage": "https://github.com/modularscale/modularscale-sass"
"homepage": "https://github.com/modularscale/modularscale-sass",
"dependencies": {
"eyeglass-math": "^1.0.1"
}
}
81 changes: 81 additions & 0 deletions stylesheets/modular-scale/_pow-polyfill.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//
// By drtimofey, script based on script by davidkpiano, see these links:
// https://github.com/thoughtbot/bitters/issues/167
// https://github.com/thoughtbot/bourbon/issues/717
// https://gist.github.com/davidkpiano/ad6e6771df050ff3727f
//

@function math-pow-polyfill($number, $exp) {
@if (round($exp) != $exp) {
@return math-exp($exp * math-ln($number));
}

// Traditional method for integers
$value: 1;

@if $exp > 0 {
@for $i from 1 through $exp {
$value: $value * $number;
}
}
@else if $exp < 0 {
@for $i from 1 through -$exp {
$value: $value / $number;
}
}

@return $value;
}

@function math-factorial($value) {
@if $value == 0 {
@return 1;
}

$result: 1;

@for $index from 1 through $value {
$result: $result * $index;
}

@return $result;
}

@function math-summation($iteratee, $input, $initial: 0, $limit: 100) {
$sum: 0;

@for $index from $initial to $limit {
$sum: $sum + call($iteratee, $input, $index);
}

@return $sum;
}

@function math-exp-maclaurin($x, $n) {
$result: math-pow-polyfill($x, $n) / math-factorial($n);
@return $result;
}
@function math-exp($value) {
$result: math-summation(math-exp-maclaurin, $value, 0, 100);
@return $result;
}

@function math-ln-maclaurin($x, $n) {
$result: (math-pow-polyfill(-1, $n + 1) / $n) * (math-pow-polyfill($x - 1, $n));
@return $result;
}

@function math-ln($value) {
$ten-exp: 1;
$ln-ten: 2.30258509;

@while ($value > math-pow-polyfill(10, $ten-exp)) {
$ten-exp: $ten-exp + 1;
}

$value: $value / math-pow-polyfill(10, $ten-exp);

$result: math-summation(math-ln-maclaurin, $value, 1, 100);

@return $result + $ten-exp * $ln-ten;
}
54 changes: 17 additions & 37 deletions stylesheets/modular-scale/_pow.scss
Original file line number Diff line number Diff line change
@@ -1,40 +1,20 @@
// If a native exponent function doesnt exist
// this one is needed.
@function ms-pow($Base, $Exponent) {

// Find and remove unit.
// Avoids messyness with unit calculations
$Unit: $Base * 0 + 1;
$Base: $Base/$Unit;
// pow with non-integer exponents
// feature detection + polyfill

// This function doesnt support non-interger exponents.
// Warn the user about why this is breaking.
@if round($Exponent) != $Exponent {
@warn "Unfortunately, you need Compass to use non-integer exponents";
}
// indirectly checks for eyeglass-math math-pow() existence
@function pow-nonint-ok() {
// using some well-known input/output
$test: math-pow(9, 0.5);
// => 3 when pow works correctly with non-integer exponents
@return ($test == 3);
}
$pow-nonint-ok: pow-nonint-ok(); // cache result to improve performance

// Set up the loop, priming the return with the base.
$Return: $Base;

// If the number is positive, multiply it.
@if $Exponent > 0 {
// Basic feedback loop as exponents
// are recursivley multiplied numbers.
@for $i from 1 to $Exponent {
$Return: $Return * $Base;
}
}

// If the number is 0 or negitive
// divide instead of multiply.
@else {
// Libsass doesnt allow negitive values in loops
@for $i from (-1 + 1) to (abs($Exponent) + 1) {
$Return: $Return / $Base;
}
@import '_pow-polyfill';
@function ms-pow($Base, $Exponent) {
@if($pow-nonint-ok == false) {
@return math-pow-polyfill($Base, $Exponent); // use polyfill pow
} @else {
@return math-pow($Base, $Exponent); // use eyeglass-math pow
}

// Return is now compounded redy to be returned.
// Add the unit back onto the number.
@return $Return * $Unit;
}
}