-
-
Save stereokai/7666bfe93929b14c2dced148c79e0e97 to your computer and use it in GitHub Desktop.
//----------------------------------*\ | |
// TRIGONOMETRY FUNCTIONS | |
//----------------------------------*/ | |
// # Trigonometry in CSS | |
// | |
// - Through Taylor/Maclaurin polynomial representation: http://people.math.sc.edu/girardi/m142/handouts/10sTaylorPolySeries.pdf | |
// - Useful if you don't want to use JS. | |
// - With CSS Variables. | |
// - `calc()` can't do power (x ^ y) so I used multiplication instead. | |
// `--angle` is in radians! Convert from degrees using `α * π / 180` (or `α * 0.01745329251`) :) | |
// Sine function representation | |
.sin { | |
--sin-term1: var(--angle); | |
--sin-term2: calc((var(--angle) * var(--angle) * var(--angle)) / 6); | |
--sin-term3: calc((var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle)) / 120); | |
--sin-term4: calc((var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle)) / 5040); | |
--sin-term5: calc((var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle)) / 362880); | |
--sin: calc(var(--sin-term1) - var(--sin-term2) + var(--sin-term3) - var(--sin-term4) + var(--sin-term5)); | |
} | |
// Cosine function representation | |
.cos { | |
--cos-term1: 1; | |
--cos-term2: calc((var(--angle) * var(--angle)) / 2); | |
--cos-term3: calc((var(--angle) * var(--angle) * var(--angle) * var(--angle)) / 24); | |
--cos-term4: calc((var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle)) / 720); | |
--cos-term5: calc((var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle)) / 40320); | |
--cos: calc(var(--cos-term1) - var(--cos-term2) + var(--cos-term3) - var(--cos-term4) + var(--cos-term5)); | |
} | |
// Tangent function representation | |
.tan { | |
--tan-term1: var(--angle); | |
--tan-term2: calc((1/3) * var(--angle) * var(--angle) * var(--angle)); | |
--tan-term3: calc((2 / 15) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle)); | |
--tan-term4: calc((17/315) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle) * var(--angle)); | |
--tan: calc(var(--tan-term1) + var(--tan-term2) + var(--tan-term3) + var(--tan-term4)); | |
} |
You will have to modify these formulas to α = sin ^ -1 * (sideA / sideB)
(or the equivalents of tan and cos, depending on which sides you have - see here)
FYI @stereokai I’m using you SIN calculation to draw some charts with CSS :)
Here is some demo page (in French for now) → https://ffoodd.github.io/chaarts/pie-charts.html
You're credited both in source code and in details, below first chart.
Thanks a lot for this!
@ffoodd that looks amazing! What a great job! I love your implementation :)
@stereokai this is incredible and made my day!!!!
Awesome snippet!
I've needed a bigger range (with 4 terms this formula works best between -2pi and 2pi), so I made this generator: https://codepen.io/Alynva/full/gOgWqQm
I found that using the Taylor Series, you can go up to 86 terms for calculating the sine and 87 for the cosine, covering a range of -10pi to 10pi. This limit is due to JavaScript casting the numbers to Infinity
@Alynva that's pretty dope! Well done!
Woo, you can do wonders with this
This works great! Thanks!
This looks interesting but trig is a little over my head. Can this be used to calculate the distance between the top of the container when using transform: skew(3deg);
?
If we know the angle is 3 degrees, and the distance is 100vw, can this snippet help me figure out the gap it in the screenshot? Thanks :)
This looks interesting but trig is a little over my head. Can this be used to calculate the distance between the top of the container when using
transform: skew(3deg);
?If we know the angle is 3 degrees, and the distance is 100vw, can this snippet help me figure out the gap it in the screenshot? Thanks :)
Sure @JiveDig ! Here it is: https://codepen.io/Alynva/pen/ZEvQmPv
If you want to use it in different elements (nav height and hero background transform), calculate the variables in the parent and apply them in the children properties.
@Alynva Wow super cool! Thanks so much for the example, it helped tremendously. I also just remembered I can do transform-origin: top left;
then I only need to manage the overlap at the bottom. I very much appreciate your help. Thanks again!
@JiveDig yes, if you just need the offset in the same element, transform-origin
can do the job easily. Just in other contexts where you change multiple elements that you actually need to calculate it
For sure. I'll definitely need it. Super powerful stuff :)
Playing with Alynva's codepen examples, but can't quite figure out what I need. Please check this out:
The Opposite side has a fixed height of 104 px, Adjacent side is 100% or 100vw of the browser window, the tip of the angle x needs to stay fixed to the right side and therefore I need to calculate the angle x.
IE, a browser window width of 960px will calc to TAN x = O/A = 104/960 = 0,108333, tan^-1 of 0,108333 = 6.182930°
@r3dvorak that might not work, because every value has the unit measurement with it, and the calc
doesn't quite work when you mix then expecting the result be in one unit. You probably will get some result if you doesn't use units (and consequently fixed values), then in the last step you can "cast" the unit by multiplying the value by 1[unit]
, like calc(1px * 100)
.
Here is my attempt to do what you want: https://codepen.io/Alynva/pen/gOjXJyW
But for values greater than 1 (in rad)(45º), the approximation of the arctan gets worse. I don't know if I coded the original generator right to get the arctan approximation, as far I tested, with more terms it gets worse (???). If you spot something wrong in the code I can fix it: https://codepen.io/Alynva/pen/gOgWqQm I read some books and thats exactlly what should happen, with that formula:
So, I think that the code is correct.
Thanks! I'll check that out.
The 100vw was just for demonstration purposes - it will be given in px, taken from the browser window width at that moment. Maybe easier to see what I mean here: https://www.franzk.net
Resize the window - of course, this site just mimics the behavior I want, using a partially white PNG sliver bg and a lot of media queries to adjust the modules below ;). It would be cool to adjust the angle of the whole header and the modules below the header dynamically.
Besides the jumping when resizing the window, the biggest problem is that my header is a rectangle, and so there are parts on the right, underneath it, that are visible but not clickable.
Hi,
how can I use this, if I don't have an angle but only the length of side a and side b ?
(the original PDF is not available any longer)
Thanks,
Richard