104 lines
3 KiB
SCSS
104 lines
3 KiB
SCSS
@function pow($number, $exp) {
|
|
$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 fact($number) {
|
|
$value: 1;
|
|
@if $number > 0 {
|
|
@for $i from 1 through $number {
|
|
$value: $value * $i;
|
|
}
|
|
}
|
|
@return $value;
|
|
}
|
|
|
|
@function pi() {
|
|
@return 3.14159265359;
|
|
}
|
|
|
|
@function rad($angle) {
|
|
$unit: unit($angle);
|
|
$unitless: $angle / ($angle * 0 + 1);
|
|
// If the angle has 'deg' as unit, convert to radians.
|
|
@if $unit == deg {
|
|
$unitless: $unitless / 180 * pi();
|
|
}
|
|
@return $unitless;
|
|
}
|
|
|
|
@function sin($angle) {
|
|
$sin: 0;
|
|
$angle: rad($angle);
|
|
// Iterate a bunch of times.
|
|
@for $i from 0 through 10 {
|
|
$sin: $sin + pow(-1, $i) * pow($angle, (2 * $i + 1)) / fact(2 * $i + 1);
|
|
}
|
|
@return $sin;
|
|
}
|
|
|
|
@function cos($angle) {
|
|
$cos: 0;
|
|
$angle: rad($angle);
|
|
// Iterate a bunch of times.
|
|
@for $i from 0 through 10 {
|
|
$cos: $cos + pow(-1, $i) * pow($angle, 2 * $i) / fact(2 * $i);
|
|
}
|
|
@return $cos;
|
|
}
|
|
|
|
@function tan($angle) {
|
|
@return sin($angle) / cos($angle);
|
|
}
|
|
|
|
/**
|
|
* on-circle takes a radius, position on a circle, number of possible positions and returns top and left properties
|
|
*
|
|
* $radius {Number} radius of the circle in pixels
|
|
* $ordinalPosition {Number} the position of the item on the circle, counting from 1 (North) through N
|
|
* $positions {Number} the number of positions on the circle
|
|
* $originX {Number} optional X origin point for the circle, defaults to the radius
|
|
* $originY {Number} optional Y origin point for the circle, defaults to the radius
|
|
* $offsetX {Number} optional X offset for the item, you might use 1/2 of the width of an item, default is 0
|
|
* $offsetY {Number} optional Y offset for the item, you might use 1/2 of the height of an item, default is 0
|
|
*/
|
|
@mixin on-circle ($ordinalPosition, $positions, $radius: 90%, $originX: 0, $originY: 0, $offsetX: 0, $offsetY: 0) {
|
|
|
|
/*
|
|
Determine the angle for the position:
|
|
Multiply the adjusted zero-based index of the position by the degrees-per-position (360 degrees divided by the
|
|
number of positions) and subtract 90 degrees (adjusting to begin at North)
|
|
*/
|
|
$positionAngleDegrees: ($ordinalPosition - 1)*360/$positions - 90;
|
|
|
|
/*
|
|
Convert the angle to radians:
|
|
Multiply the angle by pi and then divide by 180 degrees.
|
|
|
|
NOTE: This step is necessary because of a bug in handling of the degrees unit when doing iterations, AFAICT
|
|
*/
|
|
$positionAngleRadians: $positionAngleDegrees * pi() / 180;
|
|
|
|
/*
|
|
Apply the parametric equation of the circle,
|
|
http://en.wikipedia.org/wiki/Circle#Equations
|
|
via:
|
|
http://stackoverflow.com/questions/839899/how-do-i-calculate-a-point-on-a-circles-circumference
|
|
|
|
x = [origin x] + (r * cos angle)
|
|
y = [origin y] + (r * sin angle)
|
|
*/
|
|
top: #{$originY + $offsetY + $radius * sin($positionAngleRadians)}px;
|
|
left: #{$originX + $offsetX + $radius * cos($positionAngleRadians)}px;
|
|
}
|