├── .babelrc
├── .gitignore
├── .travis.yml
├── CODE_OF_CONDUCT.md
├── LICENSE.md
├── README.md
├── docs
├── assets
│ ├── anchor.js
│ ├── bass-addons.css
│ ├── bass.css
│ ├── fonts
│ │ ├── EOT
│ │ │ ├── SourceCodePro-Bold.eot
│ │ │ └── SourceCodePro-Regular.eot
│ │ ├── LICENSE.txt
│ │ ├── OTF
│ │ │ ├── SourceCodePro-Bold.otf
│ │ │ └── SourceCodePro-Regular.otf
│ │ ├── TTF
│ │ │ ├── SourceCodePro-Bold.ttf
│ │ │ └── SourceCodePro-Regular.ttf
│ │ ├── WOFF
│ │ │ ├── OTF
│ │ │ │ ├── SourceCodePro-Bold.otf.woff
│ │ │ │ └── SourceCodePro-Regular.otf.woff
│ │ │ └── TTF
│ │ │ │ ├── SourceCodePro-Bold.ttf.woff
│ │ │ │ └── SourceCodePro-Regular.ttf.woff
│ │ ├── WOFF2
│ │ │ ├── OTF
│ │ │ │ ├── SourceCodePro-Bold.otf.woff2
│ │ │ │ └── SourceCodePro-Regular.otf.woff2
│ │ │ └── TTF
│ │ │ │ ├── SourceCodePro-Bold.ttf.woff2
│ │ │ │ └── SourceCodePro-Regular.ttf.woff2
│ │ └── source-code-pro.css
│ ├── github.css
│ ├── site.js
│ └── style.css
└── index.html
├── media
├── header.png
├── logo.ai
├── logo.png
└── logo@2x.png
├── package.json
├── rollup.config.js
├── src
├── almost-identity.js
├── average.js
├── clamp-01.js
├── clamp.js
├── closest-power-of-two.js
├── cubic-pulse.js
├── deg-to-rad.js
├── delta-angle-deg.js
├── delta-angle-rad.js
├── delta-time.js
├── diagonal.js
├── difference.js
├── distance.js
├── dot-product.js
├── exp-step.js
├── fract.js
├── fuzzy-ceil.js
├── fuzzy-equal.js
├── fuzzy-floor.js
├── fuzzy-greater-than.js
├── fuzzy-less-than.js
├── gamma-to-linear-space.js
├── gcd.js
├── impulse.js
├── inverse-lerp.js
├── is-even.js
├── is-odd.js
├── is-power-of-two.js
├── lerp-angle-deg.js
├── lerp-angle-rad.js
├── lerp-unclamped.js
├── lerp.js
├── linear-to-gamma-space.js
├── map.js
├── math-toolbox.js
├── max-add.js
├── min-sub.js
├── mod.js
├── next-power-of-two.js
├── normalize.js
├── parabola.js
├── percent-01.js
├── power-curve.js
├── rad-to-deg.js
├── random-float.js
├── random-int.js
├── random-sign.js
├── smooth-max.js
├── smooth-min.js
├── smooth-step.js
├── step.js
├── within.js
└── wrap.js
└── test
├── almost-identity.test.js
├── average.test.js
├── clamp-01.test.js
├── clamp.test.js
├── closest-power-of-two.test.js
├── cubic-pulse.test.js
├── deg-to-rad.test.js
├── delta-angle-deg.test.js
├── delta-angle-rad.test.js
├── delta-time.test.js
├── diagonal.test.js
├── difference.test.js
├── distance.test.js
├── dot-product.test.js
├── exp-step.test.js
├── fract.test.js
├── fuzzy-ceil.test.js
├── fuzzy-equal.test.js
├── fuzzy-floor.test.js
├── fuzzy-greater-than.test.js
├── fuzzy-less-than.test.js
├── gamma-to-linear-space.test.js
├── gcd.test.js
├── impulse.test.js
├── inverse-lerp.test.js
├── is-even.test.js
├── is-odd.test.js
├── is-power-of-two.test.js
├── lerp-angle-deg.test.js
├── lerp-angle-rad.test.js
├── lerp-unclamped.test.js
├── lerp.test.js
├── linear-to-gamma-space.test.js
├── map.test.js
├── max-add.test.js
├── min-sub.test.js
├── mod.test.js
├── next-power-of-two.test.js
├── normalize.test.js
├── parabola.test.js
├── percent-01.test.js
├── power-curve.test.js
├── rad-to-deg.test.js
├── random-float.test.js
├── random-int.test.js
├── random-sign.test.js
├── smooth-max.test.js
├── smooth-min.test.js
├── smooth-step.test.js
├── step.test.js
├── within.test.js
└── wrap.test.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | presets: [["es2015", { modules: false }]],
3 | "plugins": ["external-helpers"],
4 | "env": {
5 | "test": {
6 | presets: ["es2015"]
7 | }
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | *.swap
3 | *.swp
4 | /node_modules
5 | coverage
6 | npm-debug.log
7 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | cache:
3 | directories:
4 | - node_modules
5 | notifications:
6 | email: false
7 | node_js:
8 | - '6'
9 | before_script:
10 | - npm prune
11 | script:
12 | - npm test -- -i
13 | after_success:
14 | - npm run semantic-release
15 | - npm run coveralls
16 | branches:
17 | except:
18 | - /^v\d+\.\d+\.\d+$/
19 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | Using welcoming and inclusive language
12 | Being respectful of differing viewpoints and experiences
13 | Gracefully accepting constructive criticism
14 | Focusing on what is best for the community
15 | Showing empathy towards other community members
16 | Examples of unacceptable behavior by participants include:
17 |
18 | The use of sexualized language or imagery and unwelcome sexual attention or advances
19 | Trolling, insulting/derogatory comments, and personal or political attacks
20 | Public or private harassment
21 | Publishing others' private information, such as a physical or electronic address, without explicit permission
22 | Other conduct which could reasonably be considered inappropriate in a professional setting
23 | Our Responsibilities
24 |
25 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
26 |
27 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
28 |
29 | ## Scope
30 |
31 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
32 |
33 | ## Enforcement
34 |
35 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project author. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
36 |
37 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
38 |
39 | ## Attribution
40 |
41 | This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at http://contributor-covenant.org/version/1/4.
42 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Terkel
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [](https://github.com/terkelg/math-toolbox)
2 |
3 | > Lightweight and modular collection of JS math functions
4 |
5 | [](http://standardjs.com/)
6 | [](https://travis-ci.org/terkelg/math-toolbox)
7 | [](https://coveralls.io/github/terkelg/math-toolbox?branch=master)
8 | [](https://david-dm.org/terkelg/math-toolbox?type=dev)
9 | [](https://github.com/semantic-release/semantic-release)
10 | [](https://www.npmjs.com/package/math-toolbox)
11 |
12 |
13 | ## Documentation
14 |
15 | ### Full documentation and list of available modules: ###
16 |
17 | **https://terkelg.github.io/math-toolbox/**
18 |
19 | ---
20 |
21 | ## Install
22 |
23 | ### Node
24 | Install ```math-toolbox``` from NPM
25 | ```
26 | $ npm install math-toolbox --save
27 | ```
28 |
29 |
30 | ## Usage
31 | You can import individual modules
32 | ```js
33 | import { clamp, map } from 'math-toolbox'
34 | ```
35 |
36 | or the entire package
37 | ```js
38 | import * as MT from 'math-toolbox'
39 | ```
40 |
41 |
42 | ### Browser
43 | To use in browser, grab the ```math-toolbox.umd.min.js``` file and add it to your page, or use the CDN:
44 | ```
45 | https://unpkg.com/math-toolbox/dist/math-toolbox.umd.min.js
46 | ```
47 |
48 | ## Plans
49 | See GitHub Wiki:
50 | https://github.com/terkelg/math-toolbox/wiki
51 |
52 |
53 | ## Build
54 | First clone the project from github:
55 | ```
56 | git clone git://github.com/terkelg/math-toolbox.git
57 | cd math-toolbox
58 | ```
59 |
60 | Install the project dependencies:
61 | ```
62 | $ npm install
63 | ```
64 |
65 | Then, the project can be build by executing the build script via NPM:
66 | ```
67 | $ npm run build
68 | ```
69 |
70 | Build and uglify with:
71 | ```
72 | $ npm run build:uglify
73 | ```
74 |
75 |
76 | ## Test
77 | [Jest](https://github.com/facebook/jest) is used for unit testing. Test with:
78 | ```
79 | $ npm test
80 | ```
81 |
82 | To watch for changes and test use:
83 |
84 | ```
85 | $ npm test:watch
86 | ```
87 |
88 | Get code coverage with
89 | ```
90 | $ npm test:coverage
91 | ```
92 |
93 | ## License
94 | *MIT @ Terkel Gjervig*
95 |
--------------------------------------------------------------------------------
/docs/assets/anchor.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * AnchorJS - v1.2.1 - 2015-07-02
3 | * https://github.com/bryanbraun/anchorjs
4 | * Copyright (c) 2015 Bryan Braun; Licensed MIT
5 | */
6 |
7 | function AnchorJS(options) {
8 | 'use strict';
9 |
10 | this.options = options || {};
11 |
12 | this._applyRemainingDefaultOptions = function(opts) {
13 | this.options.icon = this.options.hasOwnProperty('icon') ? opts.icon : '\ue9cb'; // Accepts characters (and also URLs?), like '#', '¶', '❡', or '§'.
14 | this.options.visible = this.options.hasOwnProperty('visible') ? opts.visible : 'hover'; // Also accepts 'always'
15 | this.options.placement = this.options.hasOwnProperty('placement') ? opts.placement : 'right'; // Also accepts 'left'
16 | this.options.class = this.options.hasOwnProperty('class') ? opts.class : ''; // Accepts any class name.
17 | };
18 |
19 | this._applyRemainingDefaultOptions(options);
20 |
21 | this.add = function(selector) {
22 | var elements,
23 | elsWithIds,
24 | idList,
25 | elementID,
26 | i,
27 | roughText,
28 | tidyText,
29 | index,
30 | count,
31 | newTidyText,
32 | readableID,
33 | anchor;
34 |
35 | this._applyRemainingDefaultOptions(this.options);
36 |
37 | // Provide a sensible default selector, if none is given.
38 | if (!selector) {
39 | selector = 'h1, h2, h3, h4, h5, h6';
40 | } else if (typeof selector !== 'string') {
41 | throw new Error('The selector provided to AnchorJS was invalid.');
42 | }
43 |
44 | elements = document.querySelectorAll(selector);
45 | if (elements.length === 0) {
46 | return false;
47 | }
48 |
49 | this._addBaselineStyles();
50 |
51 | // We produce a list of existing IDs so we don't generate a duplicate.
52 | elsWithIds = document.querySelectorAll('[id]');
53 | idList = [].map.call(elsWithIds, function assign(el) {
54 | return el.id;
55 | });
56 |
57 | for (i = 0; i < elements.length; i++) {
58 |
59 | if (elements[i].hasAttribute('id')) {
60 | elementID = elements[i].getAttribute('id');
61 | } else {
62 | roughText = elements[i].textContent;
63 |
64 | // Refine it so it makes a good ID. Strip out non-safe characters, replace
65 | // spaces with hyphens, truncate to 32 characters, and make toLowerCase.
66 | //
67 | // Example string: // '⚡⚡⚡ Unicode icons are cool--but they definitely don't belong in a URL fragment.'
68 | tidyText = roughText.replace(/[^\w\s-]/gi, '') // ' Unicode icons are cool--but they definitely dont belong in a URL fragment'
69 | .replace(/\s+/g, '-') // '-Unicode-icons-are-cool--but-they-definitely-dont-belong-in-a-URL-fragment'
70 | .replace(/-{2,}/g, '-') // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL-fragment'
71 | .substring(0, 64) // '-Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL'
72 | .replace(/^-+|-+$/gm, '') // 'Unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-URL'
73 | .toLowerCase(); // 'unicode-icons-are-cool-but-they-definitely-dont-belong-in-a-url'
74 |
75 | // Compare our generated ID to existing IDs (and increment it if needed)
76 | // before we add it to the page.
77 | newTidyText = tidyText;
78 | count = 0;
79 | do {
80 | if (index !== undefined) {
81 | newTidyText = tidyText + '-' + count;
82 | }
83 | // .indexOf is supported in IE9+.
84 | index = idList.indexOf(newTidyText);
85 | count += 1;
86 | } while (index !== -1);
87 | index = undefined;
88 | idList.push(newTidyText);
89 |
90 | // Assign it to our element.
91 | // Currently the setAttribute element is only supported in IE9 and above.
92 | elements[i].setAttribute('id', newTidyText);
93 |
94 | elementID = newTidyText;
95 | }
96 |
97 | readableID = elementID.replace(/-/g, ' ');
98 |
99 | // The following code builds the following DOM structure in a more effiecient (albeit opaque) way.
100 | // '';
101 | anchor = document.createElement('a');
102 | anchor.className = 'anchorjs-link ' + this.options.class;
103 | anchor.href = '#' + elementID;
104 | anchor.setAttribute('aria-label', 'Anchor link for: ' + readableID);
105 | anchor.setAttribute('data-anchorjs-icon', this.options.icon);
106 |
107 | if (this.options.visible === 'always') {
108 | anchor.style.opacity = '1';
109 | }
110 |
111 | if (this.options.icon === '\ue9cb') {
112 | anchor.style.fontFamily = 'anchorjs-icons';
113 | anchor.style.fontStyle = 'normal';
114 | anchor.style.fontVariant = 'normal';
115 | anchor.style.fontWeight = 'normal';
116 | anchor.style.lineHeight = 1;
117 | }
118 |
119 | if (this.options.placement === 'left') {
120 | anchor.style.position = 'absolute';
121 | anchor.style.marginLeft = '-1em';
122 | anchor.style.paddingRight = '0.5em';
123 | elements[i].insertBefore(anchor, elements[i].firstChild);
124 | } else { // if the option provided is `right` (or anything else).
125 | anchor.style.paddingLeft = '0.375em';
126 | elements[i].appendChild(anchor);
127 | }
128 | }
129 |
130 | return this;
131 | };
132 |
133 | this.remove = function(selector) {
134 | var domAnchor,
135 | elements = document.querySelectorAll(selector);
136 | for (var i = 0; i < elements.length; i++) {
137 | domAnchor = elements[i].querySelector('.anchorjs-link');
138 | if (domAnchor) {
139 | elements[i].removeChild(domAnchor);
140 | }
141 | }
142 | return this;
143 | };
144 |
145 | this._addBaselineStyles = function() {
146 | // We don't want to add global baseline styles if they've been added before.
147 | if (document.head.querySelector('style.anchorjs') !== null) {
148 | return;
149 | }
150 |
151 | var style = document.createElement('style'),
152 | linkRule =
153 | ' .anchorjs-link {' +
154 | ' opacity: 0;' +
155 | ' text-decoration: none;' +
156 | ' -webkit-font-smoothing: antialiased;' +
157 | ' -moz-osx-font-smoothing: grayscale;' +
158 | ' }',
159 | hoverRule =
160 | ' *:hover > .anchorjs-link,' +
161 | ' .anchorjs-link:focus {' +
162 | ' opacity: 1;' +
163 | ' }',
164 | anchorjsLinkFontFace =
165 | ' @font-face {' +
166 | ' font-family: "anchorjs-icons";' +
167 | ' font-style: normal;' +
168 | ' font-weight: normal;' + // Icon from icomoon; 10px wide & 10px tall; 2 empty below & 4 above
169 | ' src: url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBTUAAAC8AAAAYGNtYXAWi9QdAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5Zgq29TcAAAF4AAABNGhlYWQEZM3pAAACrAAAADZoaGVhBhUDxgAAAuQAAAAkaG10eASAADEAAAMIAAAAFGxvY2EAKACuAAADHAAAAAxtYXhwAAgAVwAAAygAAAAgbmFtZQ5yJ3cAAANIAAAB2nBvc3QAAwAAAAAFJAAAACAAAwJAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpywPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6cv//f//AAAAAAAg6cv//f//AAH/4xY5AAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAACADEARAJTAsAAKwBUAAABIiYnJjQ/AT4BMzIWFxYUDwEGIicmND8BNjQnLgEjIgYPAQYUFxYUBw4BIwciJicmND8BNjIXFhQPAQYUFx4BMzI2PwE2NCcmNDc2MhcWFA8BDgEjARQGDAUtLXoWOR8fORYtLTgKGwoKCjgaGg0gEhIgDXoaGgkJBQwHdR85Fi0tOAobCgoKOBoaDSASEiANehoaCQkKGwotLXoWOR8BMwUFLYEuehYXFxYugC44CQkKGwo4GkoaDQ0NDXoaShoKGwoFBe8XFi6ALjgJCQobCjgaShoNDQ0NehpKGgobCgoKLYEuehYXAAEAAAABAACiToc1Xw889QALBAAAAAAA0XnFFgAAAADRecUWAAAAAAJTAsAAAAAIAAIAAAAAAAAAAQAAA8D/wAAABAAAAAAAAlMAAQAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAACAAAAAoAAMQAAAAAACgAUAB4AmgABAAAABQBVAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEADgAAAAEAAAAAAAIABwCfAAEAAAAAAAMADgBLAAEAAAAAAAQADgC0AAEAAAAAAAUACwAqAAEAAAAAAAYADgB1AAEAAAAAAAoAGgDeAAMAAQQJAAEAHAAOAAMAAQQJAAIADgCmAAMAAQQJAAMAHABZAAMAAQQJAAQAHADCAAMAAQQJAAUAFgA1AAMAAQQJAAYAHACDAAMAAQQJAAoANAD4YW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzUmVndWxhcgBSAGUAZwB1AGwAYQByYW5jaG9yanMtaWNvbnMAYQBuAGMAaABvAHIAagBzAC0AaQBjAG8AbgBzRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==) format("truetype");' +
170 | ' }',
171 | pseudoElContent =
172 | ' [data-anchorjs-icon]::after {' +
173 | ' content: attr(data-anchorjs-icon);' +
174 | ' }',
175 | firstStyleEl;
176 |
177 | style.className = 'anchorjs';
178 | style.appendChild(document.createTextNode('')); // Necessary for Webkit.
179 |
180 | // We place it in the head with the other style tags, if possible, so as to
181 | // not look out of place. We insert before the others so these styles can be
182 | // overridden if necessary.
183 | firstStyleEl = document.head.querySelector('[rel="stylesheet"], style');
184 | if (firstStyleEl === undefined) {
185 | document.head.appendChild(style);
186 | } else {
187 | document.head.insertBefore(style, firstStyleEl);
188 | }
189 |
190 | style.sheet.insertRule(linkRule, style.sheet.cssRules.length);
191 | style.sheet.insertRule(hoverRule, style.sheet.cssRules.length);
192 | style.sheet.insertRule(pseudoElContent, style.sheet.cssRules.length);
193 | style.sheet.insertRule(anchorjsLinkFontFace, style.sheet.cssRules.length);
194 | };
195 | }
196 |
197 | var anchors = new AnchorJS();
198 |
--------------------------------------------------------------------------------
/docs/assets/bass-addons.css:
--------------------------------------------------------------------------------
1 | .input {
2 | font-family: inherit;
3 | display: block;
4 | width: 100%;
5 | height: 2rem;
6 | padding: .5rem;
7 | margin-bottom: 1rem;
8 | border: 1px solid #ccc;
9 | font-size: .875rem;
10 | border-radius: 3px;
11 | box-sizing: border-box;
12 | }
13 |
--------------------------------------------------------------------------------
/docs/assets/bass.css:
--------------------------------------------------------------------------------
1 | /*! Basscss | http://basscss.com | MIT License */
2 |
3 | .h1{ font-size: 2rem }
4 | .h2{ font-size: 1.5rem }
5 | .h3{ font-size: 1.25rem }
6 | .h4{ font-size: 1rem }
7 | .h5{ font-size: .875rem }
8 | .h6{ font-size: .75rem }
9 |
10 | .font-family-inherit{ font-family:inherit }
11 | .font-size-inherit{ font-size:inherit }
12 | .text-decoration-none{ text-decoration:none }
13 |
14 | .bold{ font-weight: bold; font-weight: bold }
15 | .regular{ font-weight:normal }
16 | .italic{ font-style:italic }
17 | .caps{ text-transform:uppercase; letter-spacing: .2em; }
18 |
19 | .left-align{ text-align:left }
20 | .center{ text-align:center }
21 | .right-align{ text-align:right }
22 | .justify{ text-align:justify }
23 |
24 | .nowrap{ white-space:nowrap }
25 | .break-word{ word-wrap:break-word }
26 |
27 | .line-height-1{ line-height: 1 }
28 | .line-height-2{ line-height: 1.125 }
29 | .line-height-3{ line-height: 1.25 }
30 | .line-height-4{ line-height: 1.5 }
31 |
32 | .list-style-none{ list-style:none }
33 | .underline{ text-decoration:underline }
34 |
35 | .truncate{
36 | max-width:100%;
37 | overflow:hidden;
38 | text-overflow:ellipsis;
39 | white-space:nowrap;
40 | }
41 |
42 | .list-reset{
43 | list-style:none;
44 | padding-left:0;
45 | }
46 |
47 | .inline{ display:inline }
48 | .block{ display:block }
49 | .inline-block{ display:inline-block }
50 | .table{ display:table }
51 | .table-cell{ display:table-cell }
52 |
53 | .overflow-hidden{ overflow:hidden }
54 | .overflow-scroll{ overflow:scroll }
55 | .overflow-auto{ overflow:auto }
56 |
57 | .clearfix:before,
58 | .clearfix:after{
59 | content:" ";
60 | display:table
61 | }
62 | .clearfix:after{ clear:both }
63 |
64 | .left{ float:left }
65 | .right{ float:right }
66 |
67 | .fit{ max-width:100% }
68 |
69 | .max-width-1{ max-width: 24rem }
70 | .max-width-2{ max-width: 32rem }
71 | .max-width-3{ max-width: 48rem }
72 | .max-width-4{ max-width: 64rem }
73 |
74 | .border-box{ box-sizing:border-box }
75 |
76 | .align-baseline{ vertical-align:baseline }
77 | .align-top{ vertical-align:top }
78 | .align-middle{ vertical-align:middle }
79 | .align-bottom{ vertical-align:bottom }
80 |
81 | .m0{ margin:0 }
82 | .mt0{ margin-top:0 }
83 | .mr0{ margin-right:0 }
84 | .mb0{ margin-bottom:0 }
85 | .ml0{ margin-left:0 }
86 | .mx0{ margin-left:0; margin-right:0 }
87 | .my0{ margin-top:0; margin-bottom:0 }
88 |
89 | .m1{ margin: .5rem }
90 | .mt1{ margin-top: .5rem }
91 | .mr1{ margin-right: .5rem }
92 | .mb1{ margin-bottom: .5rem }
93 | .ml1{ margin-left: .5rem }
94 | .mx1{ margin-left: .5rem; margin-right: .5rem }
95 | .my1{ margin-top: .5rem; margin-bottom: .5rem }
96 |
97 | .m2{ margin: 1rem }
98 | .mt2{ margin-top: 1rem }
99 | .mr2{ margin-right: 1rem }
100 | .mb2{ margin-bottom: 1rem }
101 | .ml2{ margin-left: 1rem }
102 | .mx2{ margin-left: 1rem; margin-right: 1rem }
103 | .my2{ margin-top: 1rem; margin-bottom: 1rem }
104 |
105 | .m3{ margin: 2rem }
106 | .mt3{ margin-top: 2rem }
107 | .mr3{ margin-right: 2rem }
108 | .mb3{ margin-bottom: 2rem }
109 | .ml3{ margin-left: 2rem }
110 | .mx3{ margin-left: 2rem; margin-right: 2rem }
111 | .my3{ margin-top: 2rem; margin-bottom: 2rem }
112 |
113 | .m4{ margin: 4rem }
114 | .mt4{ margin-top: 4rem }
115 | .mr4{ margin-right: 4rem }
116 | .mb4{ margin-bottom: 4rem }
117 | .ml4{ margin-left: 4rem }
118 | .mx4{ margin-left: 4rem; margin-right: 4rem }
119 | .my4{ margin-top: 4rem; margin-bottom: 4rem }
120 |
121 | .mxn1{ margin-left: -.5rem; margin-right: -.5rem; }
122 | .mxn2{ margin-left: -1rem; margin-right: -1rem; }
123 | .mxn3{ margin-left: -2rem; margin-right: -2rem; }
124 | .mxn4{ margin-left: -4rem; margin-right: -4rem; }
125 |
126 | .ml-auto{ margin-left:auto }
127 | .mr-auto{ margin-right:auto }
128 | .mx-auto{ margin-left:auto; margin-right:auto; }
129 |
130 | .p0{ padding:0 }
131 | .pt0{ padding-top:0 }
132 | .pr0{ padding-right:0 }
133 | .pb0{ padding-bottom:0 }
134 | .pl0{ padding-left:0 }
135 | .px0{ padding-left:0; padding-right:0 }
136 | .py0{ padding-top:0; padding-bottom:0 }
137 |
138 | .p1{ padding: .5rem }
139 | .pt1{ padding-top: .5rem }
140 | .pr1{ padding-right: .5rem }
141 | .pb1{ padding-bottom: .5rem }
142 | .pl1{ padding-left: .5rem }
143 | .py1{ padding-top: .5rem; padding-bottom: .5rem }
144 | .px1{ padding-left: .5rem; padding-right: .5rem }
145 |
146 | .p2{ padding: 1rem }
147 | .pt2{ padding-top: 1rem }
148 | .pr2{ padding-right: 1rem }
149 | .pb2{ padding-bottom: 1rem }
150 | .pl2{ padding-left: 1rem }
151 | .py2{ padding-top: 1rem; padding-bottom: 1rem }
152 | .px2{ padding-left: 1rem; padding-right: 1rem }
153 |
154 | .p3{ padding: 2rem }
155 | .pt3{ padding-top: 2rem }
156 | .pr3{ padding-right: 2rem }
157 | .pb3{ padding-bottom: 2rem }
158 | .pl3{ padding-left: 2rem }
159 | .py3{ padding-top: 2rem; padding-bottom: 2rem }
160 | .px3{ padding-left: 2rem; padding-right: 2rem }
161 |
162 | .p4{ padding: 4rem }
163 | .pt4{ padding-top: 4rem }
164 | .pr4{ padding-right: 4rem }
165 | .pb4{ padding-bottom: 4rem }
166 | .pl4{ padding-left: 4rem }
167 | .py4{ padding-top: 4rem; padding-bottom: 4rem }
168 | .px4{ padding-left: 4rem; padding-right: 4rem }
169 |
170 | .col{
171 | float:left;
172 | box-sizing:border-box;
173 | }
174 |
175 | .col-right{
176 | float:right;
177 | box-sizing:border-box;
178 | }
179 |
180 | .col-1{
181 | width:8.33333%;
182 | }
183 |
184 | .col-2{
185 | width:16.66667%;
186 | }
187 |
188 | .col-3{
189 | width:25%;
190 | }
191 |
192 | .col-4{
193 | width:33.33333%;
194 | }
195 |
196 | .col-5{
197 | width:41.66667%;
198 | }
199 |
200 | .col-6{
201 | width:50%;
202 | }
203 |
204 | .col-7{
205 | width:58.33333%;
206 | }
207 |
208 | .col-8{
209 | width:66.66667%;
210 | }
211 |
212 | .col-9{
213 | width:75%;
214 | }
215 |
216 | .col-10{
217 | width:83.33333%;
218 | }
219 |
220 | .col-11{
221 | width:91.66667%;
222 | }
223 |
224 | .col-12{
225 | width:100%;
226 | }
227 | @media (min-width: 40em){
228 |
229 | .sm-col{
230 | float:left;
231 | box-sizing:border-box;
232 | }
233 |
234 | .sm-col-right{
235 | float:right;
236 | box-sizing:border-box;
237 | }
238 |
239 | .sm-col-1{
240 | width:8.33333%;
241 | }
242 |
243 | .sm-col-2{
244 | width:16.66667%;
245 | }
246 |
247 | .sm-col-3{
248 | width:25%;
249 | }
250 |
251 | .sm-col-4{
252 | width:33.33333%;
253 | }
254 |
255 | .sm-col-5{
256 | width:41.66667%;
257 | }
258 |
259 | .sm-col-6{
260 | width:50%;
261 | }
262 |
263 | .sm-col-7{
264 | width:58.33333%;
265 | }
266 |
267 | .sm-col-8{
268 | width:66.66667%;
269 | }
270 |
271 | .sm-col-9{
272 | width:75%;
273 | }
274 |
275 | .sm-col-10{
276 | width:83.33333%;
277 | }
278 |
279 | .sm-col-11{
280 | width:91.66667%;
281 | }
282 |
283 | .sm-col-12{
284 | width:100%;
285 | }
286 |
287 | }
288 | @media (min-width: 52em){
289 |
290 | .md-col{
291 | float:left;
292 | box-sizing:border-box;
293 | }
294 |
295 | .md-col-right{
296 | float:right;
297 | box-sizing:border-box;
298 | }
299 |
300 | .md-col-1{
301 | width:8.33333%;
302 | }
303 |
304 | .md-col-2{
305 | width:16.66667%;
306 | }
307 |
308 | .md-col-3{
309 | width:25%;
310 | }
311 |
312 | .md-col-4{
313 | width:33.33333%;
314 | }
315 |
316 | .md-col-5{
317 | width:41.66667%;
318 | }
319 |
320 | .md-col-6{
321 | width:50%;
322 | }
323 |
324 | .md-col-7{
325 | width:58.33333%;
326 | }
327 |
328 | .md-col-8{
329 | width:66.66667%;
330 | }
331 |
332 | .md-col-9{
333 | width:75%;
334 | }
335 |
336 | .md-col-10{
337 | width:83.33333%;
338 | }
339 |
340 | .md-col-11{
341 | width:91.66667%;
342 | }
343 |
344 | .md-col-12{
345 | width:100%;
346 | }
347 |
348 | }
349 | @media (min-width: 64em){
350 |
351 | .lg-col{
352 | float:left;
353 | box-sizing:border-box;
354 | }
355 |
356 | .lg-col-right{
357 | float:right;
358 | box-sizing:border-box;
359 | }
360 |
361 | .lg-col-1{
362 | width:8.33333%;
363 | }
364 |
365 | .lg-col-2{
366 | width:16.66667%;
367 | }
368 |
369 | .lg-col-3{
370 | width:25%;
371 | }
372 |
373 | .lg-col-4{
374 | width:33.33333%;
375 | }
376 |
377 | .lg-col-5{
378 | width:41.66667%;
379 | }
380 |
381 | .lg-col-6{
382 | width:50%;
383 | }
384 |
385 | .lg-col-7{
386 | width:58.33333%;
387 | }
388 |
389 | .lg-col-8{
390 | width:66.66667%;
391 | }
392 |
393 | .lg-col-9{
394 | width:75%;
395 | }
396 |
397 | .lg-col-10{
398 | width:83.33333%;
399 | }
400 |
401 | .lg-col-11{
402 | width:91.66667%;
403 | }
404 |
405 | .lg-col-12{
406 | width:100%;
407 | }
408 |
409 | }
410 | .flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex }
411 |
412 | @media (min-width: 40em){
413 | .sm-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex }
414 | }
415 |
416 | @media (min-width: 52em){
417 | .md-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex }
418 | }
419 |
420 | @media (min-width: 64em){
421 | .lg-flex{ display:-webkit-box; display:-webkit-flex; display:-ms-flexbox; display:flex }
422 | }
423 |
424 | .flex-column{ -webkit-box-orient:vertical; -webkit-box-direction:normal; -webkit-flex-direction:column; -ms-flex-direction:column; flex-direction:column }
425 | .flex-wrap{ -webkit-flex-wrap:wrap; -ms-flex-wrap:wrap; flex-wrap:wrap }
426 |
427 | .items-start{ -webkit-box-align:start; -webkit-align-items:flex-start; -ms-flex-align:start; -ms-grid-row-align:flex-start; align-items:flex-start }
428 | .items-end{ -webkit-box-align:end; -webkit-align-items:flex-end; -ms-flex-align:end; -ms-grid-row-align:flex-end; align-items:flex-end }
429 | .items-center{ -webkit-box-align:center; -webkit-align-items:center; -ms-flex-align:center; -ms-grid-row-align:center; align-items:center }
430 | .items-baseline{ -webkit-box-align:baseline; -webkit-align-items:baseline; -ms-flex-align:baseline; -ms-grid-row-align:baseline; align-items:baseline }
431 | .items-stretch{ -webkit-box-align:stretch; -webkit-align-items:stretch; -ms-flex-align:stretch; -ms-grid-row-align:stretch; align-items:stretch }
432 |
433 | .self-start{ -webkit-align-self:flex-start; -ms-flex-item-align:start; align-self:flex-start }
434 | .self-end{ -webkit-align-self:flex-end; -ms-flex-item-align:end; align-self:flex-end }
435 | .self-center{ -webkit-align-self:center; -ms-flex-item-align:center; align-self:center }
436 | .self-baseline{ -webkit-align-self:baseline; -ms-flex-item-align:baseline; align-self:baseline }
437 | .self-stretch{ -webkit-align-self:stretch; -ms-flex-item-align:stretch; align-self:stretch }
438 |
439 | .justify-start{ -webkit-box-pack:start; -webkit-justify-content:flex-start; -ms-flex-pack:start; justify-content:flex-start }
440 | .justify-end{ -webkit-box-pack:end; -webkit-justify-content:flex-end; -ms-flex-pack:end; justify-content:flex-end }
441 | .justify-center{ -webkit-box-pack:center; -webkit-justify-content:center; -ms-flex-pack:center; justify-content:center }
442 | .justify-between{ -webkit-box-pack:justify; -webkit-justify-content:space-between; -ms-flex-pack:justify; justify-content:space-between }
443 | .justify-around{ -webkit-justify-content:space-around; -ms-flex-pack:distribute; justify-content:space-around }
444 |
445 | .content-start{ -webkit-align-content:flex-start; -ms-flex-line-pack:start; align-content:flex-start }
446 | .content-end{ -webkit-align-content:flex-end; -ms-flex-line-pack:end; align-content:flex-end }
447 | .content-center{ -webkit-align-content:center; -ms-flex-line-pack:center; align-content:center }
448 | .content-between{ -webkit-align-content:space-between; -ms-flex-line-pack:justify; align-content:space-between }
449 | .content-around{ -webkit-align-content:space-around; -ms-flex-line-pack:distribute; align-content:space-around }
450 | .content-stretch{ -webkit-align-content:stretch; -ms-flex-line-pack:stretch; align-content:stretch }
451 | .flex-auto{
452 | -webkit-box-flex:1;
453 | -webkit-flex:1 1 auto;
454 | -ms-flex:1 1 auto;
455 | flex:1 1 auto;
456 | min-width:0;
457 | min-height:0;
458 | }
459 | .flex-none{ -webkit-box-flex:0; -webkit-flex:none; -ms-flex:none; flex:none }
460 |
461 | .order-0{ -webkit-box-ordinal-group:1; -webkit-order:0; -ms-flex-order:0; order:0 }
462 | .order-1{ -webkit-box-ordinal-group:2; -webkit-order:1; -ms-flex-order:1; order:1 }
463 | .order-2{ -webkit-box-ordinal-group:3; -webkit-order:2; -ms-flex-order:2; order:2 }
464 | .order-3{ -webkit-box-ordinal-group:4; -webkit-order:3; -ms-flex-order:3; order:3 }
465 | .order-last{ -webkit-box-ordinal-group:100000; -webkit-order:99999; -ms-flex-order:99999; order:99999 }
466 |
467 | .relative{ position:relative }
468 | .absolute{ position:absolute }
469 | .fixed{ position:fixed }
470 |
471 | .top-0{ top:0 }
472 | .right-0{ right:0 }
473 | .bottom-0{ bottom:0 }
474 | .left-0{ left:0 }
475 |
476 | .z1{ z-index: 1 }
477 | .z2{ z-index: 2 }
478 | .z3{ z-index: 3 }
479 | .z4{ z-index: 4 }
480 |
481 | .border{
482 | border-style:solid;
483 | border-width: 1px;
484 | }
485 |
486 | .border-top{
487 | border-top-style:solid;
488 | border-top-width: 1px;
489 | }
490 |
491 | .border-right{
492 | border-right-style:solid;
493 | border-right-width: 1px;
494 | }
495 |
496 | .border-bottom{
497 | border-bottom-style:solid;
498 | border-bottom-width: 1px;
499 | }
500 |
501 | .border-left{
502 | border-left-style:solid;
503 | border-left-width: 1px;
504 | }
505 |
506 | .border-none{ border:0 }
507 |
508 | .rounded{ border-radius: 3px }
509 | .circle{ border-radius:50% }
510 |
511 | .rounded-top{ border-radius: 3px 3px 0 0 }
512 | .rounded-right{ border-radius: 0 3px 3px 0 }
513 | .rounded-bottom{ border-radius: 0 0 3px 3px }
514 | .rounded-left{ border-radius: 3px 0 0 3px }
515 |
516 | .not-rounded{ border-radius:0 }
517 |
518 | .hide{
519 | position:absolute !important;
520 | height:1px;
521 | width:1px;
522 | overflow:hidden;
523 | clip:rect(1px, 1px, 1px, 1px);
524 | }
525 |
526 | @media (max-width: 40em){
527 | .xs-hide{ display:none !important }
528 | }
529 |
530 | @media (min-width: 40em) and (max-width: 52em){
531 | .sm-hide{ display:none !important }
532 | }
533 |
534 | @media (min-width: 52em) and (max-width: 64em){
535 | .md-hide{ display:none !important }
536 | }
537 |
538 | @media (min-width: 64em){
539 | .lg-hide{ display:none !important }
540 | }
541 |
542 | .display-none{ display:none !important }
543 |
544 |
--------------------------------------------------------------------------------
/docs/assets/fonts/EOT/SourceCodePro-Bold.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/docs/assets/fonts/EOT/SourceCodePro-Bold.eot
--------------------------------------------------------------------------------
/docs/assets/fonts/EOT/SourceCodePro-Regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/docs/assets/fonts/EOT/SourceCodePro-Regular.eot
--------------------------------------------------------------------------------
/docs/assets/fonts/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries.
2 |
3 | This Font Software is licensed under the SIL Open Font License, Version 1.1.
4 |
5 | This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
6 |
7 |
8 | -----------------------------------------------------------
9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
10 | -----------------------------------------------------------
11 |
12 | PREAMBLE
13 | The goals of the Open Font License (OFL) are to stimulate worldwide
14 | development of collaborative font projects, to support the font creation
15 | efforts of academic and linguistic communities, and to provide a free and
16 | open framework in which fonts may be shared and improved in partnership
17 | with others.
18 |
19 | The OFL allows the licensed fonts to be used, studied, modified and
20 | redistributed freely as long as they are not sold by themselves. The
21 | fonts, including any derivative works, can be bundled, embedded,
22 | redistributed and/or sold with any software provided that any reserved
23 | names are not used by derivative works. The fonts and derivatives,
24 | however, cannot be released under any other type of license. The
25 | requirement for fonts to remain under this license does not apply
26 | to any document created using the fonts or their derivatives.
27 |
28 | DEFINITIONS
29 | "Font Software" refers to the set of files released by the Copyright
30 | Holder(s) under this license and clearly marked as such. This may
31 | include source files, build scripts and documentation.
32 |
33 | "Reserved Font Name" refers to any names specified as such after the
34 | copyright statement(s).
35 |
36 | "Original Version" refers to the collection of Font Software components as
37 | distributed by the Copyright Holder(s).
38 |
39 | "Modified Version" refers to any derivative made by adding to, deleting,
40 | or substituting -- in part or in whole -- any of the components of the
41 | Original Version, by changing formats or by porting the Font Software to a
42 | new environment.
43 |
44 | "Author" refers to any designer, engineer, programmer, technical
45 | writer or other person who contributed to the Font Software.
46 |
47 | PERMISSION & CONDITIONS
48 | Permission is hereby granted, free of charge, to any person obtaining
49 | a copy of the Font Software, to use, study, copy, merge, embed, modify,
50 | redistribute, and sell modified and unmodified copies of the Font
51 | Software, subject to the following conditions:
52 |
53 | 1) Neither the Font Software nor any of its individual components,
54 | in Original or Modified Versions, may be sold by itself.
55 |
56 | 2) Original or Modified Versions of the Font Software may be bundled,
57 | redistributed and/or sold with any software, provided that each copy
58 | contains the above copyright notice and this license. These can be
59 | included either as stand-alone text files, human-readable headers or
60 | in the appropriate machine-readable metadata fields within text or
61 | binary files as long as those fields can be easily viewed by the user.
62 |
63 | 3) No Modified Version of the Font Software may use the Reserved Font
64 | Name(s) unless explicit written permission is granted by the corresponding
65 | Copyright Holder. This restriction only applies to the primary font name as
66 | presented to the users.
67 |
68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
69 | Software shall not be used to promote, endorse or advertise any
70 | Modified Version, except to acknowledge the contribution(s) of the
71 | Copyright Holder(s) and the Author(s) or with their explicit written
72 | permission.
73 |
74 | 5) The Font Software, modified or unmodified, in part or in whole,
75 | must be distributed entirely under this license, and must not be
76 | distributed under any other license. The requirement for fonts to
77 | remain under this license does not apply to any document created
78 | using the Font Software.
79 |
80 | TERMINATION
81 | This license becomes null and void if any of the above conditions are
82 | not met.
83 |
84 | DISCLAIMER
85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
93 | OTHER DEALINGS IN THE FONT SOFTWARE.
94 |
--------------------------------------------------------------------------------
/docs/assets/fonts/OTF/SourceCodePro-Bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/docs/assets/fonts/OTF/SourceCodePro-Bold.otf
--------------------------------------------------------------------------------
/docs/assets/fonts/OTF/SourceCodePro-Regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/docs/assets/fonts/OTF/SourceCodePro-Regular.otf
--------------------------------------------------------------------------------
/docs/assets/fonts/TTF/SourceCodePro-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/docs/assets/fonts/TTF/SourceCodePro-Bold.ttf
--------------------------------------------------------------------------------
/docs/assets/fonts/TTF/SourceCodePro-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/docs/assets/fonts/TTF/SourceCodePro-Regular.ttf
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/docs/assets/fonts/WOFF/OTF/SourceCodePro-Bold.otf.woff
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/docs/assets/fonts/WOFF/OTF/SourceCodePro-Regular.otf.woff
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/docs/assets/fonts/WOFF/TTF/SourceCodePro-Bold.ttf.woff
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/docs/assets/fonts/WOFF/TTF/SourceCodePro-Regular.ttf.woff
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Bold.otf.woff2
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/docs/assets/fonts/WOFF2/OTF/SourceCodePro-Regular.otf.woff2
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Bold.ttf.woff2
--------------------------------------------------------------------------------
/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/docs/assets/fonts/WOFF2/TTF/SourceCodePro-Regular.ttf.woff2
--------------------------------------------------------------------------------
/docs/assets/fonts/source-code-pro.css:
--------------------------------------------------------------------------------
1 | @font-face{
2 | font-family: 'Source Code Pro';
3 | font-weight: 400;
4 | font-style: normal;
5 | font-stretch: normal;
6 | src: url('EOT/SourceCodePro-Regular.eot') format('embedded-opentype'),
7 | url('WOFF2/TTF/SourceCodePro-Regular.ttf.woff2') format('woff2'),
8 | url('WOFF/OTF/SourceCodePro-Regular.otf.woff') format('woff'),
9 | url('OTF/SourceCodePro-Regular.otf') format('opentype'),
10 | url('TTF/SourceCodePro-Regular.ttf') format('truetype');
11 | }
12 |
13 | @font-face{
14 | font-family: 'Source Code Pro';
15 | font-weight: 700;
16 | font-style: normal;
17 | font-stretch: normal;
18 | src: url('EOT/SourceCodePro-Bold.eot') format('embedded-opentype'),
19 | url('WOFF2/TTF/SourceCodePro-Bold.ttf.woff2') format('woff2'),
20 | url('WOFF/OTF/SourceCodePro-Bold.otf.woff') format('woff'),
21 | url('OTF/SourceCodePro-Bold.otf') format('opentype'),
22 | url('TTF/SourceCodePro-Bold.ttf') format('truetype');
23 | }
24 |
--------------------------------------------------------------------------------
/docs/assets/github.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | github.com style (c) Vasily Polovnyov
4 |
5 | */
6 |
7 | .hljs {
8 | display: block;
9 | overflow-x: auto;
10 | padding: 0.5em;
11 | color: #333;
12 | background: #f8f8f8;
13 | -webkit-text-size-adjust: none;
14 | }
15 |
16 | .hljs-comment,
17 | .diff .hljs-header,
18 | .hljs-javadoc {
19 | color: #998;
20 | font-style: italic;
21 | }
22 |
23 | .hljs-keyword,
24 | .css .rule .hljs-keyword,
25 | .hljs-winutils,
26 | .nginx .hljs-title,
27 | .hljs-subst,
28 | .hljs-request,
29 | .hljs-status {
30 | color: #1184CE;
31 | }
32 |
33 | .hljs-number,
34 | .hljs-hexcolor,
35 | .ruby .hljs-constant {
36 | color: #ed225d;
37 | }
38 |
39 | .hljs-string,
40 | .hljs-tag .hljs-value,
41 | .hljs-phpdoc,
42 | .hljs-dartdoc,
43 | .tex .hljs-formula {
44 | color: #ed225d;
45 | }
46 |
47 | .hljs-title,
48 | .hljs-id,
49 | .scss .hljs-preprocessor {
50 | color: #900;
51 | font-weight: bold;
52 | }
53 |
54 | .hljs-list .hljs-keyword,
55 | .hljs-subst {
56 | font-weight: normal;
57 | }
58 |
59 | .hljs-class .hljs-title,
60 | .hljs-type,
61 | .vhdl .hljs-literal,
62 | .tex .hljs-command {
63 | color: #458;
64 | font-weight: bold;
65 | }
66 |
67 | .hljs-tag,
68 | .hljs-tag .hljs-title,
69 | .hljs-rules .hljs-property,
70 | .django .hljs-tag .hljs-keyword {
71 | color: #000080;
72 | font-weight: normal;
73 | }
74 |
75 | .hljs-attribute,
76 | .hljs-variable,
77 | .lisp .hljs-body {
78 | color: #008080;
79 | }
80 |
81 | .hljs-regexp {
82 | color: #009926;
83 | }
84 |
85 | .hljs-symbol,
86 | .ruby .hljs-symbol .hljs-string,
87 | .lisp .hljs-keyword,
88 | .clojure .hljs-keyword,
89 | .scheme .hljs-keyword,
90 | .tex .hljs-special,
91 | .hljs-prompt {
92 | color: #990073;
93 | }
94 |
95 | .hljs-built_in {
96 | color: #0086b3;
97 | }
98 |
99 | .hljs-preprocessor,
100 | .hljs-pragma,
101 | .hljs-pi,
102 | .hljs-doctype,
103 | .hljs-shebang,
104 | .hljs-cdata {
105 | color: #999;
106 | font-weight: bold;
107 | }
108 |
109 | .hljs-deletion {
110 | background: #fdd;
111 | }
112 |
113 | .hljs-addition {
114 | background: #dfd;
115 | }
116 |
117 | .diff .hljs-change {
118 | background: #0086b3;
119 | }
120 |
121 | .hljs-chunk {
122 | color: #aaa;
123 | }
124 |
--------------------------------------------------------------------------------
/docs/assets/site.js:
--------------------------------------------------------------------------------
1 | /* global anchors */
2 |
3 | // add anchor links to headers
4 | anchors.options.placement = 'left';
5 | anchors.add('h3');
6 |
7 | // Filter UI
8 | var tocElements = document.getElementById('toc')
9 | .getElementsByTagName('li');
10 |
11 | document.getElementById('filter-input')
12 | .addEventListener('keyup', function (e) {
13 |
14 | var i, element, children;
15 |
16 | // enter key
17 | if (e.keyCode === 13) {
18 | // go to the first displayed item in the toc
19 | for (i = 0; i < tocElements.length; i++) {
20 | element = tocElements[i];
21 | if (!element.classList.contains('display-none')) {
22 | location.replace(element.firstChild.href);
23 | return e.preventDefault();
24 | }
25 | }
26 | }
27 |
28 | var match = function () {
29 | return true;
30 | };
31 |
32 | var value = this.value.toLowerCase();
33 |
34 | if (!value.match(/^\s*$/)) {
35 | match = function (element) {
36 | return element.firstChild.innerHTML.toLowerCase().indexOf(value) !== -1;
37 | };
38 | }
39 |
40 | for (i = 0; i < tocElements.length; i++) {
41 | element = tocElements[i];
42 | children = Array.from(element.getElementsByTagName('li'));
43 | if (match(element) || children.some(match)) {
44 | element.classList.remove('display-none');
45 | } else {
46 | element.classList.add('display-none');
47 | }
48 | }
49 | });
50 |
51 | var toggles = document.getElementsByClassName('toggle-step-sibling');
52 | for (var i = 0; i < toggles.length; i++) {
53 | toggles[i].addEventListener('click', toggleStepSibling);
54 | }
55 |
56 | function toggleStepSibling() {
57 | var stepSibling = this.parentNode.parentNode.parentNode.getElementsByClassName('toggle-target')[0];
58 | var klass = 'display-none';
59 | if (stepSibling.classList.contains(klass)) {
60 | stepSibling.classList.remove(klass);
61 | stepSibling.innerHTML = '▾';
62 | } else {
63 | stepSibling.classList.add(klass);
64 | stepSibling.innerHTML = '▸';
65 | }
66 | }
67 |
68 | var items = document.getElementsByClassName('toggle-sibling');
69 | for (var j = 0; j < items.length; j++) {
70 | items[j].addEventListener('click', toggleSibling);
71 | }
72 |
73 | function toggleSibling() {
74 | var stepSibling = this.parentNode.getElementsByClassName('toggle-target')[0];
75 | var icon = this.getElementsByClassName('icon')[0];
76 | var klass = 'display-none';
77 | if (stepSibling.classList.contains(klass)) {
78 | stepSibling.classList.remove(klass);
79 | icon.innerHTML = '▾';
80 | } else {
81 | stepSibling.classList.add(klass);
82 | icon.innerHTML = '▸';
83 | }
84 | }
85 |
86 | function showHashTarget(targetId) {
87 | var hashTarget = document.getElementById(targetId);
88 | // new target is hidden
89 | if (hashTarget && hashTarget.offsetHeight === 0 &&
90 | hashTarget.parentNode.parentNode.classList.contains('display-none')) {
91 | hashTarget.parentNode.parentNode.classList.remove('display-none');
92 | }
93 | }
94 |
95 | window.addEventListener('hashchange', function() {
96 | showHashTarget(location.hash.substring(1));
97 | });
98 |
99 | showHashTarget(location.hash.substring(1));
100 |
101 | var toclinks = document.getElementsByClassName('pre-open');
102 | for (var k = 0; k < toclinks.length; k++) {
103 | toclinks[k].addEventListener('mousedown', preOpen, false);
104 | }
105 |
106 | function preOpen() {
107 | showHashTarget(this.hash.substring(1));
108 | }
109 |
--------------------------------------------------------------------------------
/docs/assets/style.css:
--------------------------------------------------------------------------------
1 | .documentation {
2 | font-family: Helvetica, sans-serif;
3 | color: #666;
4 | line-height: 1.5;
5 | background: #f5f5f5;
6 | }
7 |
8 | .black {
9 | color: #666;
10 | }
11 |
12 | .bg-white {
13 | background-color: #fff;
14 | }
15 |
16 | h4 {
17 | margin: 20px 0 10px 0;
18 | }
19 |
20 | .documentation h3 {
21 | color: #000;
22 | }
23 |
24 | .border-bottom {
25 | border-color: #ddd;
26 | }
27 |
28 | a {
29 | color: #1184CE;
30 | text-decoration: none;
31 | }
32 |
33 | .documentation a[href]:hover {
34 | text-decoration: underline;
35 | }
36 |
37 | a:hover {
38 | cursor: pointer;
39 | }
40 |
41 | .py1-ul li {
42 | padding: 5px 0;
43 | }
44 |
45 | .max-height-100 {
46 | max-height: 100%;
47 | }
48 |
49 | section:target h3 {
50 | font-weight:700;
51 | }
52 |
53 | .documentation td,
54 | .documentation th {
55 | padding: .25rem .25rem;
56 | }
57 |
58 | h1:hover .anchorjs-link,
59 | h2:hover .anchorjs-link,
60 | h3:hover .anchorjs-link,
61 | h4:hover .anchorjs-link {
62 | opacity: 1;
63 | }
64 |
65 | .fix-3 {
66 | width: 25%;
67 | max-width: 244px;
68 | }
69 |
70 | .fix-3 {
71 | width: 25%;
72 | max-width: 244px;
73 | }
74 |
75 | @media (min-width: 52em) {
76 | .fix-margin-3 {
77 | margin-left: 25%;
78 | }
79 | }
80 |
81 | .pre, pre, code, .code {
82 | font-family: Source Code Pro,Menlo,Consolas,Liberation Mono,monospace;
83 | font-size: 14px;
84 | }
85 |
86 | .fill-light {
87 | background: #F9F9F9;
88 | }
89 |
90 | .width2 {
91 | width: 1rem;
92 | }
93 |
94 | .input {
95 | font-family: inherit;
96 | display: block;
97 | width: 100%;
98 | height: 2rem;
99 | padding: .5rem;
100 | margin-bottom: 1rem;
101 | border: 1px solid #ccc;
102 | font-size: .875rem;
103 | border-radius: 3px;
104 | box-sizing: border-box;
105 | }
106 |
107 | table {
108 | border-collapse: collapse;
109 | }
110 |
111 | .prose table th,
112 | .prose table td {
113 | text-align: left;
114 | padding:8px;
115 | border:1px solid #ddd;
116 | }
117 |
118 | .prose table th:nth-child(1) { border-right: none; }
119 | .prose table th:nth-child(2) { border-left: none; }
120 |
121 | .prose table {
122 | border:1px solid #ddd;
123 | }
124 |
125 | .prose-big {
126 | font-size: 18px;
127 | line-height: 30px;
128 | }
129 |
130 | .quiet {
131 | opacity: 0.7;
132 | }
133 |
134 | .minishadow {
135 | box-shadow: 2px 2px 10px #f3f3f3;
136 | }
137 |
--------------------------------------------------------------------------------
/media/header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/media/header.png
--------------------------------------------------------------------------------
/media/logo.ai:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/media/logo.ai
--------------------------------------------------------------------------------
/media/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/media/logo.png
--------------------------------------------------------------------------------
/media/logo@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/terkelg/math-toolbox/0414644262d411a5ba65704197faa97417525060/media/logo@2x.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "math-toolbox",
3 | "description": "Lightweight and modular math toolbox",
4 | "main": "dist/math-toolbox.umd.js",
5 | "module": "dist/math-toolbox.es.js",
6 | "jsnext:main": "dist/math-toolbox.es.js",
7 | "cjs:main": "dist/math-toolbox.cjs.js",
8 | "version": "0.0.0-semantically-released",
9 | "scripts": {
10 | "build": "rollup -c",
11 | "build:uglify": "npm run build && uglifyjs dist/math-toolbox.umd.js -cm --preamble \"// math-toolbox - https://github.com/terkelg/math-toolbox\" > dist/math-toolbox.umd.min.js",
12 | "docs": "documentation build src/math-toolbox.js -f html -o docs",
13 | "test": "standard && jest",
14 | "test:watch": "npm test -- --watch",
15 | "test:coverage": "jest --coverage",
16 | "prepublish": "npm run build:uglify",
17 | "coveralls": "npm run test:coverage && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage",
18 | "semantic-release": "semantic-release pre && npm publish && semantic-release post"
19 | },
20 | "repository": {
21 | "type": "git",
22 | "url": "https://github.com/terkelg/math-toolbox"
23 | },
24 | "bugs": {
25 | "url": "https://github.com/terkelg/math-toolbox/issues"
26 | },
27 | "files": [
28 | "dist",
29 | "src"
30 | ],
31 | "keywords": [
32 | "math",
33 | "utils",
34 | "toolbox",
35 | "tools",
36 | "helper",
37 | "lerp",
38 | "map",
39 | "clamp",
40 | "average",
41 | "isOdd",
42 | "isEven",
43 | "smoothstep",
44 | "random",
45 | "distance",
46 | "trigonometry",
47 | "geometry",
48 | "mix",
49 | "gcd"
50 | ],
51 | "author": "Terkel Gjervig",
52 | "maintainers": [
53 | {
54 | "name": "Patrick Heng",
55 | "url": "https://github.com/patrickheng"
56 | },
57 | {
58 | "name": "Fabien Motte",
59 | "url": "https://github.com/FabienMotte"
60 | },
61 | {
62 | "name": "Terkel Gjervig",
63 | "email": "terkel@terkel.com",
64 | "url": "https://terkel.com"
65 | }
66 | ],
67 | "license": "MIT",
68 | "devDependencies": {
69 | "babel-jest": "^21.0.0",
70 | "babel-plugin-external-helpers": "^6.22.0",
71 | "babel-polyfill": "^6.23.0",
72 | "babel-preset-es2015": "^6.24.0",
73 | "coveralls": "^2.12.0",
74 | "jest": "^21.0.0",
75 | "jsdoc-to-markdown": "^4.0.0",
76 | "jest-cli": "^21.0.0",
77 | "rollup": "^0.48.0",
78 | "rollup-plugin-babel": "^2.7.1",
79 | "semantic-release": "^7.0.1",
80 | "standard": "^10.0.0",
81 | "uglify-js": "^3.0.0"
82 | },
83 | "standard": {
84 | "ignore": [
85 | "/docs",
86 | "/dist"
87 | ],
88 | "globals": [
89 | "expect",
90 | "it",
91 | "test",
92 | "describe"
93 | ]
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import babel from 'rollup-plugin-babel'
2 |
3 | export default {
4 | entry: 'src/math-toolbox.js',
5 | plugins: [ babel() ],
6 | moduleName: 'MathToolbox',
7 | targets: [
8 | { format: 'cjs', dest: 'dist/math-toolbox.cjs.js' },
9 | { format: 'umd', dest: 'dist/math-toolbox.umd.js' },
10 | { format: 'es', dest: 'dist/math-toolbox.es.js' }
11 | ],
12 | sourceMap: false
13 | }
14 |
--------------------------------------------------------------------------------
/src/almost-identity.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Almost Identity.
3 | *
4 | * @param {number} x - Input value.
5 | * @param {number} m - Threshold.
6 | * @param {number} n - The value to take when x is zero.
7 | * @return {number} Smoothed value.
8 | * @see {@link http://www.iquilezles.org/www/articles/functions/functions.htm}
9 | */
10 | function almostIdentity (x, m, n) {
11 | if (x > m) return x
12 |
13 | let a = 2 * n - m
14 | let b = 2 * m - 3 * n
15 | let t = x / m
16 |
17 | return (a * t + b) * t * t + n
18 | }
19 |
20 | export { almostIdentity }
21 |
--------------------------------------------------------------------------------
/src/average.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Return the avarage of all values passed to the function.
3 | *
4 | * @param {...number} numbers - The numbers to average.
5 | * @return {number} The average of all given values.
6 | */
7 | function average (...numbers) {
8 | let sum = 0
9 |
10 | for (let number of numbers) {
11 | sum += (+number)
12 | }
13 |
14 | return sum / numbers.length
15 | }
16 |
17 | export { average }
18 |
--------------------------------------------------------------------------------
/src/clamp-01.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Clamps a value between 0 and 1 and returns value
3 | *
4 | * @param {number} v - Value to clamp
5 | * @return {number} The clamped value
6 | */
7 | function clamp01 (v) {
8 | return v < 0 ? 0 : (v > 1 ? 1 : v)
9 | }
10 |
11 | export { clamp01 }
12 |
--------------------------------------------------------------------------------
/src/clamp.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Constrain a value to lie between two further values.
3 | *
4 | * @param {number} min - Lower end of the range into which to constrain v.
5 | * @param {number} max - Upper end of the range into which to constrain v.
6 | * @param {number} v - Value to clamp.
7 | * @return {number} The value to constrain.
8 | * @see {@link https://www.opengl.org/sdk/docs/man/html/clamp.xhtml}
9 | */
10 | function clamp (min, max, v) {
11 | return Math.min(max, Math.max(min, v))
12 | }
13 |
14 | export { clamp }
15 |
--------------------------------------------------------------------------------
/src/closest-power-of-two.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns the closest power of two value.
3 | *
4 | * @param {number} value - Value.
5 | * @return {number} The nearest power of 2i.
6 | */
7 | function closestPowerOfTwo (value) {
8 | return Math.pow(2, Math.round(Math.log(value) / Math.log(2)))
9 | }
10 |
11 | export { closestPowerOfTwo }
12 |
--------------------------------------------------------------------------------
/src/cubic-pulse.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Cubic Pulse.
3 | *
4 | * @param {number} c - Edge 1.
5 | * @param {number} w - Edge 2.
6 | * @param {number} x - Source value for interpolation.
7 | * @return {number} Cubic pulse.
8 | * @see {@link http://www.iquilezles.org/www/articles/functions/functions.htm}
9 | */
10 | function cubicPulse (c, w, x) {
11 | x = Math.abs(x - c)
12 | if (x > w) return 0
13 | x /= w
14 | return 1 - x * x * (3 - 2 * x)
15 | }
16 |
17 | export { cubicPulse }
18 |
--------------------------------------------------------------------------------
/src/deg-to-rad.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Convert degrees to radians.
3 | *
4 | * @param {number} degrees - Degrees.
5 | * @return {number} Angel in radians.
6 | */
7 | function degToRad (degrees) {
8 | return degrees * Math.PI / 180
9 | }
10 |
11 | export { degToRad, degToRad as toRadians }
12 |
--------------------------------------------------------------------------------
/src/delta-angle-deg.js:
--------------------------------------------------------------------------------
1 | import { mod } from './math-toolbox'
2 |
3 | /**
4 | * Calculates the shortest difference between two given angles given in degrees.
5 | *
6 | * @param {number} a - Current.
7 | * @param {number} b - Target.
8 | * @return {number} The distance.
9 | * @see {@link https://docs.unity3d.com/ScriptReference/Mathf.DeltaAngle.html}
10 | */
11 | function deltaAngleDeg (a, b) {
12 | let d = mod(b - a, 360)
13 | if (d > 180) d = Math.abs(d - 360)
14 | return d
15 | }
16 |
17 | export { deltaAngleDeg, deltaAngleDeg as deltaAngle }
18 |
--------------------------------------------------------------------------------
/src/delta-angle-rad.js:
--------------------------------------------------------------------------------
1 | import { degToRad, radToDeg, deltaAngleDeg } from './math-toolbox'
2 |
3 | /**
4 | * Calculates the shortest difference between two given angles given in radians.
5 | *
6 | * @param {number} a - Current.
7 | * @param {number} b - Target.
8 | * @return {number} The distance.
9 | * @see {@link https://docs.unity3d.com/ScriptReference/Mathf.DeltaAngle.html}
10 | */
11 | function deltaAngleRad (a, b) {
12 | return degToRad(deltaAngleDeg(radToDeg(a), radToDeg(b)))
13 | }
14 |
15 | export { deltaAngleRad }
16 |
--------------------------------------------------------------------------------
/src/delta-time.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Return delta time
3 | *
4 | * @param {number} oldTime - Time previous frame in milliseconds
5 | * @param {number} [newTime=Date.now()] - Time current frame in milliseconds
6 | * @return {number} Time difference in milliseconds
7 | */
8 | function deltaTime (oldTime, newTime = Date.now()) {
9 | return newTime - oldTime
10 | }
11 |
12 | export { deltaTime }
13 |
--------------------------------------------------------------------------------
/src/diagonal.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Return diagonal of a rectangle.
3 | *
4 | * @param {number} w - Width.
5 | * @param {number} h - Height.
6 | * @return {number} Diagonal length.
7 | */
8 | function diagonal (w, h) {
9 | return Math.sqrt(w * w + h * h)
10 | }
11 |
12 | export { diagonal }
13 |
--------------------------------------------------------------------------------
/src/difference.js:
--------------------------------------------------------------------------------
1 | /**
2 | * The absolute difference between two values.
3 | *
4 | * @param {number} a - The first value to check.
5 | * @param {number} b - The second value to check.
6 | * @return {number} The absolute difference between the two values.
7 | */
8 | function difference (a, b) {
9 | return Math.abs(a - b)
10 | }
11 |
12 | export { difference }
13 |
--------------------------------------------------------------------------------
/src/distance.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns the euclidian distance between the two given set of coordinates
3 | *
4 | * @param {number} x1 - X coord of the first point.
5 | * @param {number} y1 - Y coord of the first point.
6 | * @param {number} x2 - X coord of the second point.
7 | * @param {number} y2 - Y coord of the second point.
8 | * @return {number} The computed distance.
9 | */
10 | function distance (x1, y1, x2, y2) {
11 | const dx = x1 - x2
12 | const dy = y1 - y2
13 | return Math.sqrt(dx * dx + dy * dy)
14 | }
15 |
16 | export { distance }
17 |
--------------------------------------------------------------------------------
/src/dot-product.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Compute the dot product of any pair of 2D vectors.
3 | *
4 | * @param {number} x0 - First x start position.
5 | * @param {number} y0 - First y start position.
6 | * @param {number} x1 - First x end position.
7 | * @param {number} y1 - First y end position.
8 | * @param {number} x2 - Second x start position.
9 | * @param {number} y2 - Second y start position.
10 | * @param {number} x3 - Second x end position.
11 | * @param {number} y3 - Second y end position.
12 | * @return {number} Dot product.
13 | */
14 | function dotProduct (x0, y0, x1, y1, x2, y2, x3, y3) {
15 | let dx0 = x1 - x0
16 | let dy0 = y1 - y0
17 | let dx1 = x3 - x2
18 | let dy1 = y3 - y2
19 |
20 | return dx0 * dx1 + dy0 * dy1
21 | }
22 |
23 | export { dotProduct }
24 |
--------------------------------------------------------------------------------
/src/exp-step.js:
--------------------------------------------------------------------------------
1 | /**
2 | * ExpStep.
3 | *
4 | * @param {number} x - Value to be used to generate the step function.
5 | * @param {number} k - Edge of the step.
6 | * @param {number} n - n value.
7 | * @return {number} Exponential step.
8 | * @see {@link http://www.iquilezles.org/www/articles/functions/functions.htm}
9 | */
10 | function expStep (x, k, n) {
11 | return Math.exp(-k * Math.pow(x, n))
12 | }
13 |
14 | export { expStep }
15 |
--------------------------------------------------------------------------------
/src/fract.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Compute the fractional part of the argument.
3 | *
4 | * @param {number} v - Specify the value to evaluate.
5 | * @return {number} Returns the fractional part of x.
6 | * @see {@link https://www.opengl.org/sdk/docs/man/html/fract.xhtml}
7 | */
8 | function fract (v) {
9 | return v - Math.floor(v)
10 | }
11 |
12 | export { fract }
13 |
--------------------------------------------------------------------------------
/src/fuzzy-ceil.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Calculates a fuzzy ceil to the given value.
3 | *
4 | * @param {number} value - The value to ceil.
5 | * @param {number} [epsilon=0.0001] - The epsilon (a small value used in the calculation).
6 | * @return {number} ceiling(value+epsilon).
7 | */
8 | function fuzzyCeil (value, epsilon = 0.0001) {
9 | return Math.ceil(value + epsilon)
10 | }
11 |
12 | export { fuzzyCeil }
13 |
--------------------------------------------------------------------------------
/src/fuzzy-equal.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Two numbers are fuzzyEqual if their difference is less than epsilon.
3 | *
4 | * @param {number} a - The first number to compare.
5 | * @param {number} b - The second number to compare.
6 | * @param {number} [epsilon=0.0001] - The epsilon (a small value used in the calculation).
7 | * @return {boolean} True if |a-b|b-epsilon.
8 | */
9 | function fuzzyGreaterThan (a, b, epsilon = 0.0001) {
10 | return a > b - epsilon
11 | }
12 |
13 | export { fuzzyGreaterThan }
14 |
--------------------------------------------------------------------------------
/src/fuzzy-less-than.js:
--------------------------------------------------------------------------------
1 | /**
2 | * A is fuzzyLessThan B if it is less than B + epsilon.
3 | *
4 | * @param {number} a - The first number to compare.
5 | * @param {number} b - The second number to compare.
6 | * @param {number} [epsilon=0.0001] - The epsilon (a small value used in the calculation).
7 | * @return {boolean} True if a= 1) return y
13 | return x + a * (y - x)
14 | }
15 |
16 | export { lerpUnclamped, lerpUnclamped as mixUnclamped }
17 |
--------------------------------------------------------------------------------
/src/lerp.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Linearly interpolate between two values (mix).
3 | *
4 | * @param {number} x - Start of the range in which to interpolate.
5 | * @param {number} y - End of the range in which to interpolate.
6 | * @param {number} r - Value to use to interpolate between x and y.
7 | * @return {number} Lerped value
8 | * @see {@link https://www.opengl.org/sdk/docs/man/html/mix.xhtml}
9 | */
10 | function lerp (x, y, r) {
11 | return x + ((y - x) * r)
12 | }
13 |
14 | export { lerp, lerp as mix }
15 |
--------------------------------------------------------------------------------
/src/linear-to-gamma-space.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Converts the given value from linear to gamma (sRGB) color space.
3 | *
4 | * @param {number} v - Linear color space value.
5 | * @return {number} Value in gamma.
6 | * @see {@link https://docs.unity3d.com/ScriptReference/Mathf.LinearToGammaSpace.html}
7 | */
8 | function linearToGammaSpace (v) {
9 | return Math.pow(v, 1 / 2.2)
10 | }
11 |
12 | export { linearToGammaSpace }
13 |
--------------------------------------------------------------------------------
/src/map.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Re-maps a number from one range to another (Also known as scale)
3 | *
4 | * @param {number} value - The incoming value to be converted
5 | * @param {number} start1 - Lower bound of the value's current range
6 | * @param {number} stop1 - Upper bound of the value's current range
7 | * @param {number} start2 - Lower bound of the value's target range
8 | * @param {number} stop2 - Upper bound of the value's target range
9 | * @return {number} Remapped number
10 | */
11 | function map (value, start1, stop1, start2, stop2) {
12 | return ((value - start1) / (stop1 - start1)) * (stop2 - start2) + start2
13 | }
14 |
15 | export { map }
16 |
--------------------------------------------------------------------------------
/src/math-toolbox.js:
--------------------------------------------------------------------------------
1 | export { clamp } from './clamp'
2 | export { clamp01 } from './clamp-01'
3 | export { step } from './step'
4 | export { map } from './map'
5 | export { diagonal } from './diagonal'
6 | export { distance } from './distance'
7 | export { smoothStep } from './smooth-step'
8 | export { lerp, mix } from './lerp'
9 | export { normalize } from './normalize'
10 | export { randomFloat } from './random-float'
11 | export { randomInt } from './random-int'
12 | export { randomSign } from './random-sign'
13 | export { wrap } from './wrap'
14 | export { degToRad, toRadians } from './deg-to-rad'
15 | export { radToDeg, toDegrees } from './rad-to-deg'
16 | export { fuzzyFloor } from './fuzzy-floor'
17 | export { fuzzyCeil } from './fuzzy-ceil'
18 | export { fuzzyEqual } from './fuzzy-equal'
19 | export { fuzzyGreaterThan } from './fuzzy-greater-than'
20 | export { fuzzyLessThan } from './fuzzy-less-than'
21 | export { maxAdd } from './max-add'
22 | export { minSub } from './min-sub'
23 | export { isOdd } from './is-odd'
24 | export { isEven } from './is-even'
25 | export { isPowerOfTwo } from './is-power-of-two'
26 | export { closestPowerOfTwo } from './closest-power-of-two'
27 | export { nextPowerOfTwo } from './next-power-of-two'
28 | export { percent01 } from './percent-01'
29 | export { average } from './average'
30 | export { difference } from './difference'
31 | export { within } from './within'
32 | export { inverseLerp, inverseMix } from './inverse-lerp'
33 | export { lerpUnclamped, mixUnclamped } from './lerp-unclamped'
34 | export { deltaAngleDeg, deltaAngle } from './delta-angle-deg'
35 | export { deltaAngleRad } from './delta-angle-rad'
36 | export { fract } from './fract'
37 | export { mod } from './mod'
38 | export { lerpAngleDeg, lerpAngle } from './lerp-angle-deg'
39 | export { lerpAngleRad } from './lerp-angle-rad'
40 | export { gammaToLinearSpace } from './gamma-to-linear-space'
41 | export { linearToGammaSpace } from './linear-to-gamma-space'
42 | export { almostIdentity } from './almost-identity'
43 | export { impulse } from './impulse'
44 | export { cubicPulse } from './cubic-pulse'
45 | export { expStep } from './exp-step'
46 | export { parabola } from './parabola'
47 | export { powerCurve } from './power-curve'
48 | export { smoothMin } from './smooth-min'
49 | export { smoothMax } from './smooth-max'
50 | export { deltaTime } from './delta-time'
51 | export { gcd } from './gcd'
52 | export { dotProduct } from './dot-product'
53 |
--------------------------------------------------------------------------------
/src/max-add.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Adds the given amount to the value, but never lets the value go over the specified maximum.
3 | *
4 | * @param {number} value - The value to add the amount to.
5 | * @param {number} amount - The amount to add to the value.
6 | * @param {number} max - The maximum the value is allowed to be.
7 | * @return {number} The new value.
8 | */
9 | function maxAdd (value, amount, max) {
10 | return Math.min(value + amount, max)
11 | }
12 |
13 | export { maxAdd }
14 |
--------------------------------------------------------------------------------
/src/min-sub.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Subtracts the given amount from the value, but never lets the value go below the specified minimum.
3 | *
4 | * @param {number} value - The base value.
5 | * @param {number} amount - The amount to subtract from the base value.
6 | * @param {number} min - The minimum the value is allowed to be.
7 | * @return {number} The new value.
8 | */
9 | function minSub (value, amount, min) {
10 | return Math.max(value - amount, min)
11 | }
12 |
13 | export { minSub }
14 |
--------------------------------------------------------------------------------
/src/mod.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Compute value of one parameter modulo another.
3 | *
4 | * @param {number} a - Value a.
5 | * @param {number} n - Value b.
6 | * @return {number} Returns the value of x modulo n.
7 | * @see {@link https://www.opengl.org/sdk/docs/man4/html/mod.xhtml}
8 | */
9 | function mod (a, n) {
10 | return (a % n + n) % n
11 | }
12 |
13 | export { mod }
14 |
--------------------------------------------------------------------------------
/src/next-power-of-two.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns the next power of two value.
3 | *
4 | * @param {number} v - Value.
5 | * @return {number} The next power of two.
6 | */
7 | function nextPowerOfTwo (v) {
8 | return Math.pow(2, Math.ceil(Math.log(v) / Math.log(2)))
9 | }
10 |
11 | export { nextPowerOfTwo }
12 |
--------------------------------------------------------------------------------
/src/normalize.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Normalize a value between two bounds.
3 | *
4 | * @param {number} min - Minimum boundary.
5 | * @param {number} max - Maximum boundary.
6 | * @param {number} x - Value to normalize.
7 | * @return {number} Normalized value.
8 | */
9 | function normalize (min, max, x) {
10 | return (x - min) / (max - min)
11 | }
12 |
13 | export { normalize }
14 |
--------------------------------------------------------------------------------
/src/parabola.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Remap the 0..1 interval into 0..1 parabola, such that the corners are remaped to 0 and the center to 1.
3 | * In other words, parabola(0) = parabola(1) = 0, and parabola(1/2) = 1.
4 | *
5 | * @param {number} x - Coordinate on X axis.
6 | * @param {number} k - Value to map.
7 | * @return {number} Mapped value.
8 | * @see {@link http://www.iquilezles.org/www/articles/functions/functions.htm}
9 | */
10 | function parabola (x, k) {
11 | return Math.pow(4 * x * (1 - x), k)
12 | }
13 |
14 | export { parabola }
15 |
--------------------------------------------------------------------------------
/src/percent-01.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Work out what percentage value `a` is of value `b` using the given base.
3 | * Clamps returned value between 0-1.
4 | *
5 | * @param {number} a - The percent to work out.
6 | * @param {number} b - The value you wish to get the percentage of.
7 | * @param {number} [base=0] - The base value.
8 | * @return {number} The percentage a is of b, clamped between 0 and 1.
9 | */
10 | function percent01 (a, b, base = 0) {
11 | if (a > b || base > b) {
12 | return 1
13 | } else if (a < base || base > a) {
14 | return 0
15 | } else {
16 | return (a - base) / b
17 | }
18 | }
19 |
20 | export { percent01 }
21 |
--------------------------------------------------------------------------------
/src/power-curve.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Power Curve.
3 | *
4 | * @param {number} x - Input value.
5 | * @param {number} a - Edge 1.
6 | * @param {number} b - Edge 2.
7 | * @return {number} Value.
8 | * @see {@link http://www.iquilezles.org/www/articles/functions/functions.htm}
9 | */
10 | function powerCurve (x, a, b) {
11 | let k = Math.pow(a + b, a + b) / (Math.pow(a, a) * Math.pow(b, b))
12 | return k * Math.pow(x, a) * Math.pow(1 - x, b)
13 | }
14 |
15 | export { powerCurve }
16 |
--------------------------------------------------------------------------------
/src/rad-to-deg.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Convert radians to degrees.
3 | *
4 | * @param {number} radians - Radians.
5 | * @return {number} Angel in degrees.
6 | */
7 | function radToDeg (radians) {
8 | return radians * 180 / Math.PI
9 | }
10 |
11 | export { radToDeg, radToDeg as toDegrees }
12 |
--------------------------------------------------------------------------------
/src/random-float.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Generate a random float.
3 | *
4 | * @param {number} minValue - Minimum boundary.
5 | * @param {number} maxValue - Maximum boundary.
6 | * @param {number} [precision=2] - Precision.
7 | * @return {number} Generated float.
8 | */
9 | function randomFloat (minValue, maxValue, precision = 2) {
10 | return parseFloat(Math.min(minValue + (Math.random() * (maxValue - minValue)), maxValue).toFixed(precision))
11 | }
12 |
13 | export { randomFloat }
14 |
--------------------------------------------------------------------------------
/src/random-int.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Generate a random integer
3 | *
4 | * @param {number} min - Minimum boundary.
5 | * @param {number} max - Maximum boundary.
6 | * @return {number} Generated integer.
7 | */
8 | function randomInt (min, max) {
9 | return Math.floor(Math.random() * (max - min + 1) + min)
10 | }
11 |
12 | export { randomInt }
13 |
--------------------------------------------------------------------------------
/src/random-sign.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Generate random sign (1 or -1).
3 | *
4 | * @return {number} Either 1 or -1.
5 | */
6 | function randomSign () {
7 | return (Math.random() > 0.5) ? 1 : -1
8 | }
9 |
10 | export { randomSign }
11 |
--------------------------------------------------------------------------------
/src/smooth-max.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Smooth Max.
3 | *
4 | * @param {number} a - First value to compare.
5 | * @param {number} b - Second value to compare.
6 | * @param {number} k - Radious/distance of the smoothness.
7 | * @return {number} Smooth min output.
8 | * @see {@link http://iquilezles.org/www/articles/smin/smin.htm}
9 | */
10 | function smoothMax (a, b, k) {
11 | return Math.log(Math.exp(a) + Math.exp(b)) / k
12 | }
13 |
14 | export { smoothMax }
15 |
--------------------------------------------------------------------------------
/src/smooth-min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Smooth Min.
3 | *
4 | * @param {number} a - First value to compare.
5 | * @param {number} b - Second value to compare.
6 | * @param {number} k - Radious/distance of the smoothness.
7 | * @return {number} Smooth min output.
8 | * @see {@link http://iquilezles.org/www/articles/smin/smin.htm}
9 | */
10 | function smoothMin (a, b, k) {
11 | let res = Math.exp(-k * a) + Math.exp(-k * b)
12 | return -Math.log(res) / k
13 | }
14 |
15 | export { smoothMin }
16 |
--------------------------------------------------------------------------------
/src/smooth-step.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Smooth a value.
3 | *
4 | * @param {number} min - Minimum boundary.
5 | * @param {number} max - Maximum boundary.
6 | * @param {number} v - Value.
7 | * @return {number} Smoothed value.
8 | */
9 | function smoothStep (min, max, v) {
10 | const x = Math.max(0, Math.min(1, (v - min) / (max - min)))
11 | return x * x * (3 - 2 * x)
12 | }
13 |
14 | export { smoothStep }
15 |
--------------------------------------------------------------------------------
/src/step.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Generate a step function by comparing two values.
3 | *
4 | * @param {number} edge - Location of the edge of the step function.
5 | * @param {number} v - Value to be used to generate the step function.
6 | * @return {number} Step value.
7 | * @see {@link https://www.opengl.org/sdk/docs/man/html/step.xhtml}
8 | */
9 | function step (edge, v) {
10 | return (v < edge) ? 0 : 1
11 | }
12 |
13 | export { step }
14 |
--------------------------------------------------------------------------------
/src/within.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Checks if two values are within the given tolerance of each other.
3 | *
4 | * @param {number} a - The first number to check
5 | * @param {number} b - The second number to check
6 | * @param {number} tolerance - The tolerance. Anything equal to or less than this is considered within the range.
7 | * @return {boolean} True if a is <= tolerance of b.
8 | */
9 | function within (a, b, tolerance) {
10 | return (Math.abs(a - b) <= tolerance)
11 | }
12 |
13 | export { within }
14 |
--------------------------------------------------------------------------------
/src/wrap.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Ensures that the value always stays between min and max, by wrapping the value around.
3 | * If 'max' is not larger than 'min' the result is 0.
4 | *
5 | * @param {number} value - The value to wrap.
6 | * @param {number} min - The minimum the value is allowed to be.
7 | * @param {number} max - The maximum the value is allowed to be, should be larger than 'min'.
8 | * @return {number} Wrapped value.
9 | */
10 | function wrap (value, min, max) {
11 | const range = max - min
12 | if (range <= 0) return 0
13 |
14 | let result = (value - min) % range
15 | if (result < 0) result += range
16 |
17 | return result + min
18 | }
19 |
20 | export { wrap }
21 |
--------------------------------------------------------------------------------
/test/almost-identity.test.js:
--------------------------------------------------------------------------------
1 | import { almostIdentity } from '../src/math-toolbox'
2 |
3 | describe('Almost Identity', () => {
4 | it('Expect 2 when input is 0, when n = 2', () => {
5 | expect(almostIdentity(0, 10, 2)).toBe(2)
6 | })
7 |
8 | it('Expect 2.512 when input is (2, 1, 2)', () => {
9 | expect(almostIdentity(2, 1, 2)).toBe(2)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/average.test.js:
--------------------------------------------------------------------------------
1 | import { average } from '../src/math-toolbox'
2 |
3 | describe('Calculate average', () => {
4 | it('Expect the everage of 10, 10, 10, 20, 30 to be 16', () => {
5 | expect(average(10, 20, 10, 10, 30)).toBe(16)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/clamp-01.test.js:
--------------------------------------------------------------------------------
1 | import { clamp01 } from '../src/math-toolbox'
2 |
3 | describe('Clamp value between 0 and 1', () => {
4 | it('Expect clamp01 with 1 to be 1', () => {
5 | expect(clamp01(1)).toBe(1)
6 | })
7 |
8 | it('Expect clamp01 with 2 to be 1', () => {
9 | expect(clamp01(2)).toBe(1)
10 | })
11 |
12 | it('Expect clamp01 with 0.5 to be 0.5', () => {
13 | expect(clamp01(0.5)).toBe(0.5)
14 | })
15 |
16 | it('Expect clamp01 with -2 to be 0', () => {
17 | expect(clamp01(-2)).toBe(0)
18 | })
19 | })
20 |
--------------------------------------------------------------------------------
/test/clamp.test.js:
--------------------------------------------------------------------------------
1 | import { clamp } from '../src/math-toolbox'
2 |
3 | describe('Force a value within the boundaries by clamping it to the range `min`, `max`.', () => {
4 | it('Clamp 30 between 10 and 20 and expect 30', () => {
5 | expect(clamp(10, 20, 30)).toBe(20)
6 | })
7 |
8 | it('Clamp 30 between 20 and 45 and expect 30', () => {
9 | expect(clamp(20, 45, 30)).toBe(30)
10 | })
11 |
12 | it('Clamp 10 between 20 and 45 and expect 20', () => {
13 | expect(clamp(20, 45, 10)).toBe(20)
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/test/closest-power-of-two.test.js:
--------------------------------------------------------------------------------
1 | import { closestPowerOfTwo } from '../src/math-toolbox'
2 |
3 | describe('Find closest power of two', () => {
4 | it('Expect nearest power of two with 127 to be 128', () => {
5 | expect(closestPowerOfTwo(127)).toBe(128)
6 | })
7 |
8 | it('Expect nearest power of two with 180 to be 128', () => {
9 | expect(closestPowerOfTwo(180)).toBe(128)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/cubic-pulse.test.js:
--------------------------------------------------------------------------------
1 | import { cubicPulse } from '../src/math-toolbox'
2 |
3 | describe('Cubic Pulse', () => {
4 | it('Expect (0, 1, 0.5) to be 0.5', () => {
5 | expect(cubicPulse(0, 1, 0.5)).toBe(0.5)
6 | })
7 |
8 | it('Expect (0, 1, 0.65) to be close to 0.281749', () => {
9 | expect(cubicPulse(0, 1, 0.65)).toBeCloseTo(0.281749, 5)
10 | })
11 |
12 | it('Expect (0, 0.5, 0.65) to be 0', () => {
13 | expect(cubicPulse(0, 0.5, 0.65)).toBe(0)
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/test/deg-to-rad.test.js:
--------------------------------------------------------------------------------
1 | import { degToRad } from '../src/math-toolbox'
2 |
3 | describe('Convert degrees to radians', () => {
4 | it('Expect 180 degrees to be ≈ 3.14159 radians', () => {
5 | expect(degToRad(180)).toBeCloseTo(3.14159, 5)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/delta-angle-deg.test.js:
--------------------------------------------------------------------------------
1 | import { deltaAngleDeg } from '../src/math-toolbox'
2 |
3 | describe('Calculate the shortest difference between to given angles', () => {
4 | it('Expect (90, 80) to be 10', () => {
5 | expect(deltaAngleDeg(90, 80)).toBe(10)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/delta-angle-rad.test.js:
--------------------------------------------------------------------------------
1 | import { deltaAngleRad } from '../src/math-toolbox'
2 |
3 | describe('Calculate the shortest difference between to given angles', () => {
4 | it('Expect (1.39626, 1.5708) to be close to 0.1745399', () => {
5 | expect(deltaAngleRad(1.39626, 1.5708)).toBeCloseTo(0.1745399, 5)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/delta-time.test.js:
--------------------------------------------------------------------------------
1 | import { deltaTime } from '../src/math-toolbox'
2 |
3 | describe('Calculate delta time', () => {
4 | it('Test delta time with 200 ms deifference', () => {
5 | expect(deltaTime(752976000, 752976200)).toBe(200) // Some time the test is too slow
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/diagonal.test.js:
--------------------------------------------------------------------------------
1 | import { diagonal } from '../src/math-toolbox'
2 |
3 | describe('Calculate the diagonal of an rectangle', () => {
4 | it('Diagonal of 30x13 to be ≈ 32.6956', () => {
5 | expect(diagonal(30, 13)).toBeCloseTo(32.6956, 4)
6 | })
7 |
8 | it('Diagonal of 16x10 to be ≈ 18.868', () => {
9 | expect(diagonal(16, 10)).toBeCloseTo(18.868, 3)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/difference.test.js:
--------------------------------------------------------------------------------
1 | import { difference } from '../src/math-toolbox'
2 |
3 | describe('Calculate absolute difference', () => {
4 | it('Expect difference between 10 and 20 t0 be 10', () => {
5 | expect(difference(10, 20)).toBe(10)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/distance.test.js:
--------------------------------------------------------------------------------
1 | import { distance } from '../src/math-toolbox'
2 |
3 | describe('Returns the euclidian distance between the two given set of coordinates', () => {
4 | it('Expect distance between (3,2) and (5,-1) to ≈ 3.60555', () => {
5 | expect(distance(3, 2, 5, -1)).toBeCloseTo(3.60555, 5)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/dot-product.test.js:
--------------------------------------------------------------------------------
1 | import { dotProduct } from '../src/math-toolbox'
2 |
3 | describe('Calculate dot product', () => {
4 | it('Expect -24', () => {
5 | expect(dotProduct(1, 1, 4, 4, 5, 6, 2, 1)).toBe(-24)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/exp-step.test.js:
--------------------------------------------------------------------------------
1 | import { expStep } from '../src/math-toolbox'
2 |
3 | describe('Exponential step', () => {
4 | it('Expect (1, 0.5, 0.2) to be close to 0.60653', () => {
5 | expect(expStep(1, 0.5, 0.2)).toBeCloseTo(0.60653, 5)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/fract.test.js:
--------------------------------------------------------------------------------
1 | import { fract } from '../src/math-toolbox'
2 |
3 | describe('Fract', () => {
4 | it('Expect 1.50 to be 0.5', () => {
5 | expect(fract(1.50)).toBe(0.5)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/fuzzy-ceil.test.js:
--------------------------------------------------------------------------------
1 | import { fuzzyCeil } from '../src/math-toolbox'
2 |
3 | describe('Fuzzy ceil', () => {
4 | it('Expect fuzzy ceiling(1.12+1) to be 3', () => {
5 | expect(fuzzyCeil(1.12, 1)).toBe(3)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/fuzzy-equal.test.js:
--------------------------------------------------------------------------------
1 | import { fuzzyEqual } from '../src/math-toolbox'
2 |
3 | describe('Fuzzy equal', () => {
4 | it('Expect fuzzy equal 10 == 20 with default epsilon 0.0001 to be false', () => {
5 | expect(fuzzyEqual(10, 20)).toBe(false)
6 | })
7 |
8 | it('Expect fuzzy equal 10 == 11 with epsilon 3 to be true', () => {
9 | expect(fuzzyEqual(10, 11, 3)).toBe(true)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/fuzzy-floor.test.js:
--------------------------------------------------------------------------------
1 | import { fuzzyFloor } from '../src/math-toolbox'
2 |
3 | describe('Fuzzy floor', () => {
4 | it('Expect fuzzy floor(1.12-1) to be 2', () => {
5 | expect(fuzzyFloor(1.12, 1)).toBe(2)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/fuzzy-greater-than.test.js:
--------------------------------------------------------------------------------
1 | import { fuzzyGreaterThan } from '../src/math-toolbox'
2 |
3 | describe('Fuzzy greater than', () => {
4 | it('Expect fuzzy 10.5 > 10.55 with epsilon 0.08 to be true', () => {
5 | expect(fuzzyGreaterThan(10.5, 10.55, 0.08)).toBe(true)
6 | })
7 |
8 | it('Expect fuzzy 10.5 > 10.55 with epsilon 0.05 to be false', () => {
9 | expect(fuzzyGreaterThan(10.5, 10.55, 0.05)).toBe(false)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/fuzzy-less-than.test.js:
--------------------------------------------------------------------------------
1 | import { fuzzyLessThan } from '../src/math-toolbox'
2 |
3 | describe('Fuzzy less than', () => {
4 | it('Expect fuzzy 10.55 < 10.50 with epsilon 0.15 to be true', () => {
5 | expect(fuzzyLessThan(10.55, 10.50, 0.15)).toBe(true)
6 | })
7 |
8 | it('Expect fuzzy 10.5 < 10.55 with epsilon 0.05 to be true', () => {
9 | expect(fuzzyLessThan(10.55, 10.55, 0.05)).toBe(true)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/gamma-to-linear-space.test.js:
--------------------------------------------------------------------------------
1 | import { gammaToLinearSpace } from '../src/math-toolbox'
2 |
3 | describe('Gamma to linear color space', () => {
4 | it('Expect 1 to be 1', () => {
5 | expect(gammaToLinearSpace(1)).toBe(1)
6 | })
7 |
8 | it('Expect 0.5 to be close to 0.2176', () => {
9 | expect(gammaToLinearSpace(0.5)).toBeCloseTo(0.2176, 4)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/gcd.test.js:
--------------------------------------------------------------------------------
1 | import { gcd } from '../src/math-toolbox'
2 |
3 | describe('Compute the greatest common divisor', () => {
4 | it('Expect 48, 18 to be 6', () => {
5 | expect(gcd(48, 18)).toBe(6)
6 | })
7 |
8 | it('Expect 54, 24 to be 6', () => {
9 | expect(gcd(54, 24)).toBe(6)
10 | })
11 |
12 | it('Expect 48, 180 to be 12', () => {
13 | expect(gcd(48, 180)).toBe(12)
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/test/impulse.test.js:
--------------------------------------------------------------------------------
1 | import { impulse } from '../src/math-toolbox'
2 |
3 | describe('Impulse', () => {
4 | it('Expect (0.5, 10) to be close to 0.091578', () => {
5 | expect(impulse(0.5, 10)).toBeCloseTo(0.091578, 6)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/inverse-lerp.test.js:
--------------------------------------------------------------------------------
1 | import { inverseLerp } from '../src/math-toolbox'
2 |
3 | describe('Inverse Lerp', () => {
4 | it('Expect (1, 10, 5) to be close to 0.44444', () => {
5 | expect(inverseLerp(1, 10, 5)).toBeCloseTo(0.44444, 5)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/is-even.test.js:
--------------------------------------------------------------------------------
1 | import { isEven } from '../src/math-toolbox'
2 |
3 | describe('Returns true if the number given is even', () => {
4 | it('Expect input value 5 to be false', () => {
5 | expect(isEven(5)).toBe(false)
6 | })
7 |
8 | it('Expect input value 2 to be true', () => {
9 | expect(isEven(2)).toBe(true)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/is-odd.test.js:
--------------------------------------------------------------------------------
1 | import { isOdd } from '../src/math-toolbox'
2 |
3 | describe('Returns true if the number given is odd', () => {
4 | it('Expect input value 5 to be true', () => {
5 | expect(isOdd(5)).toBe(true)
6 | })
7 |
8 | it('Expect input value 2 to be false', () => {
9 | expect(isOdd(2)).toBe(false)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/is-power-of-two.test.js:
--------------------------------------------------------------------------------
1 | import { isPowerOfTwo } from '../src/math-toolbox'
2 |
3 | describe('Returns true if the value is power of two.', () => {
4 | it('Expect input value 5 to be false', () => {
5 | expect(isPowerOfTwo(5)).toBe(false)
6 | })
7 |
8 | it('Expect input value 2 to be true', () => {
9 | expect(isPowerOfTwo(2)).toBe(true)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/lerp-angle-deg.test.js:
--------------------------------------------------------------------------------
1 | import { lerpAngleDeg } from '../src/math-toolbox'
2 |
3 | describe('Lerp Angle Deg', () => {
4 | it('Expect (0, 10, 0.2) to be 2', () => {
5 | expect(lerpAngleDeg(0, 10, 0.2)).toBe(2)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/lerp-angle-rad.test.js:
--------------------------------------------------------------------------------
1 | import { lerpAngleRad } from '../src/math-toolbox'
2 |
3 | describe('Lerp Angle Rad', () => {
4 | it('Expect (0, 10, 0.2) to be 2', () => {
5 | expect(lerpAngleRad(3.14159, 1.0472, 0.174533)).toBeCloseTo(3.507130, 5)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/lerp-unclamped.test.js:
--------------------------------------------------------------------------------
1 | import { lerpUnclamped } from '../src/math-toolbox'
2 |
3 | describe('Lerp Unclamped', () => {
4 | it('Expect (0, 10, 0.2) to be 2', () => {
5 | expect(lerpUnclamped(0, 10, 0.2)).toBe(2)
6 | })
7 |
8 | it('Expect (0, 10, 2) to be 10', () => {
9 | expect(lerpUnclamped(0, 10, 2)).toBe(10)
10 | })
11 |
12 | it('Expect (0, 10, 0.5) to be 5', () => {
13 | expect(lerpUnclamped(0, 10, 0.5)).toBe(5)
14 | })
15 |
16 | it('Expect (0, 10, 0) to be 0', () => {
17 | expect(lerpUnclamped(0, 10, 0)).toBe(0)
18 | })
19 | })
20 |
--------------------------------------------------------------------------------
/test/lerp.test.js:
--------------------------------------------------------------------------------
1 | import { lerp, mix } from '../src/math-toolbox'
2 |
3 | describe('Lerp with x = 0, y = 1 and interpolation value 0.5 to be 0.5', () => {
4 | it('lerp', () => {
5 | expect(lerp(0, 1, 0.5)).toBe(0.5)
6 | })
7 |
8 | it('test mix alias', () => {
9 | expect(mix(0, 1, 0.5)).toBe(0.5)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/linear-to-gamma-space.test.js:
--------------------------------------------------------------------------------
1 | import { linearToGammaSpace } from '../src/math-toolbox'
2 |
3 | describe('Linear to gamma space', () => {
4 | it('Expect 0.25 to be 0.5325', () => {
5 | expect(linearToGammaSpace(0.25)).toBeCloseTo(0.5325)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/map.test.js:
--------------------------------------------------------------------------------
1 | import { map } from '../src/math-toolbox'
2 |
3 | describe('Check mapping', () => {
4 | it('Map input 1 in range 1-100 to value between 0-10', () => {
5 | expect(map(1, 0, 100, 0, 10)).toBe(0.1)
6 | })
7 |
8 | it('Map input 5 in range 0-10 to value between 0-100', () => {
9 | expect(map(5, 0, 10, 0, 100)).toBe(50)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/max-add.test.js:
--------------------------------------------------------------------------------
1 | import { maxAdd } from '../src/math-toolbox'
2 |
3 | describe('Adds the given amount to the value, but never lets the value go over the specified maximum', () => {
4 | it('Add 10 to 30 with max 35, expect to it to return 35', () => {
5 | expect(maxAdd(10, 30, 35)).toBe(35)
6 | })
7 |
8 | it('Add 10 to 30 with max 45, expect to it to return 40', () => {
9 | expect(maxAdd(10, 30, 45)).toBe(40)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/min-sub.test.js:
--------------------------------------------------------------------------------
1 | import { minSub } from '../src/math-toolbox'
2 |
3 | describe('Subtracts the given amount from the value, but never lets the value go below the specified minimum', () => {
4 | it('Substract 10 from 30 with min 25, expect to it to return 25', () => {
5 | expect(minSub(10, 30, 25)).toBe(25)
6 | })
7 |
8 | it('Substract 10 from 30 with min 35, expect to it to return 35', () => {
9 | expect(minSub(10, 30, 35)).toBe(35)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/mod.test.js:
--------------------------------------------------------------------------------
1 | import { mod } from '../src/math-toolbox'
2 |
3 | describe('Mod', () => {
4 | it('Expect (13, 10) to be 3', () => {
5 | expect(mod(13, 10)).toBe(3)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/next-power-of-two.test.js:
--------------------------------------------------------------------------------
1 | import { nextPowerOfTwo } from '../src/math-toolbox'
2 |
3 | describe('Test next power of two', () => {
4 | it('Expect next power of two with 1022 to be 1024', () => {
5 | expect(nextPowerOfTwo(1022)).toBe(1024)
6 | })
7 |
8 | it('Expect next power of two with 400 to be 512', () => {
9 | expect(nextPowerOfTwo(400)).toBe(512)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/normalize.test.js:
--------------------------------------------------------------------------------
1 | import { normalize } from '../src/math-toolbox'
2 |
3 | describe('Normalize values', () => {
4 | it('Normalize 0-100 with input 50', () => {
5 | expect(normalize(0, 100, 50)).toBe(0.5)
6 | })
7 |
8 | it('Normalize 1-10 with input 1', () => {
9 | expect(normalize(1, 10, 1)).toBe(0)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/parabola.test.js:
--------------------------------------------------------------------------------
1 | import { parabola } from '../src/math-toolbox'
2 |
3 | describe('Check parabola', () => {
4 | it('Parabola x = 1 and k = 5', () => {
5 | expect(parabola(1, 5)).toBe(0)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/percent-01.test.js:
--------------------------------------------------------------------------------
1 | import { percent01 } from '../src/math-toolbox'
2 |
3 | describe('Calculate percentage to clamped decimal value between 0-1', () => {
4 | it('Expect 125 of 100 to be 1', () => {
5 | expect(percent01(125, 100)).toBe(1)
6 | })
7 |
8 | it('Expect 1 of 100 to in base 2 to be 0.5', () => {
9 | expect(percent01(1, 100, 2)).toBe(0)
10 | })
11 |
12 | it('Expect 50 of 100 to be 0.5', () => {
13 | expect(percent01(50, 100)).toBe(0.5)
14 | })
15 | })
16 |
--------------------------------------------------------------------------------
/test/power-curve.test.js:
--------------------------------------------------------------------------------
1 | import { powerCurve } from '../src/math-toolbox'
2 |
3 | describe('Power curve', () => {
4 | it('Expect (0.2, 0, 1) to be 0.8', () => {
5 | expect(powerCurve(0.2, 0, 1)).toBe(0.8)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/rad-to-deg.test.js:
--------------------------------------------------------------------------------
1 | import { radToDeg } from '../src/math-toolbox'
2 |
3 | describe('Convert radians to degrees', () => {
4 | it('Expect 1.5708 radians to be ≈ 90 degrees', () => {
5 | expect(radToDeg(1.5708)).toBeCloseTo(90.000, 3)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/random-float.test.js:
--------------------------------------------------------------------------------
1 | import { randomFloat } from '../src/math-toolbox'
2 |
3 | describe('Random float in range 5-10 with a precision 4', () => {
4 | it('Expect value to be less than 10', () => {
5 | expect(randomFloat(5, 10, 4)).toBeLessThanOrEqual(10)
6 | })
7 |
8 | it('Expect value to be greater than 5', () => {
9 | expect(randomFloat(5, 10, 4)).toBeGreaterThanOrEqual(5)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/random-int.test.js:
--------------------------------------------------------------------------------
1 | import { randomInt } from '../src/math-toolbox'
2 |
3 | describe('Random int in range 5-10', () => {
4 | const value = randomInt(5, 10)
5 | it('Expect value to be less than 10', () => {
6 | expect(value).toBeLessThanOrEqual(10)
7 | })
8 |
9 | it('Expect value to be greater than 5', () => {
10 | expect(value).toBeGreaterThanOrEqual(5)
11 | })
12 | })
13 |
--------------------------------------------------------------------------------
/test/random-sign.test.js:
--------------------------------------------------------------------------------
1 | import { randomSign } from '../src/math-toolbox'
2 |
3 | describe('Return random sign 1 or -1', () => {
4 | let sign = randomSign()
5 |
6 | it('Should be greater than or equal to -1', () => {
7 | expect(sign).toBeGreaterThanOrEqual(-1)
8 | })
9 |
10 | it('Should be less than or equal to 1', () => {
11 | expect(sign).toBeLessThanOrEqual(1)
12 | })
13 | })
14 |
--------------------------------------------------------------------------------
/test/smooth-max.test.js:
--------------------------------------------------------------------------------
1 | import { smoothMax } from '../src/math-toolbox'
2 |
3 | describe('Smooth Max', () => {
4 | it('Expect (1, 5, 8) to be close to 0.62726', () => {
5 | expect(smoothMax(1, 5, 8)).toBeCloseTo(0.627268, 5)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/smooth-min.test.js:
--------------------------------------------------------------------------------
1 | import { smoothMin } from '../src/math-toolbox'
2 |
3 | describe('Smooth Min', () => {
4 | it('Expect (1, 5, 8) to be close to 0.99999', () => {
5 | expect(smoothMin(1, 5, 8)).toBeCloseTo(0.999999, 5)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/smooth-step.test.js:
--------------------------------------------------------------------------------
1 | import { smoothStep } from '../src/math-toolbox'
2 |
3 | describe('Smooth step values', () => {
4 | it('Smooth value 50 between 0-100', () => {
5 | expect(smoothStep(0, 100, 50)).toBe(0.5)
6 | })
7 |
8 | it('Smooth value 50 between 10-50', () => {
9 | expect(smoothStep(10, 50, 50)).toBe(1)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/step.test.js:
--------------------------------------------------------------------------------
1 | import { step } from '../src/math-toolbox'
2 |
3 | describe('Test step function', () => {
4 | it('Expect (1, 0.5) to be 0', () => {
5 | expect(step(1, 0.5)).toBe(0)
6 | })
7 |
8 | it('Expect (1, 2) to be 1', () => {
9 | expect(step(1, 2)).toBe(1)
10 | })
11 | })
12 |
--------------------------------------------------------------------------------
/test/within.test.js:
--------------------------------------------------------------------------------
1 | import { within } from '../src/math-toolbox'
2 |
3 | describe('Checks if two values are within the given tolerance of each other', () => {
4 | it('Expect 20.5 and 21 to be within each other with the tolerance 0.5', () => {
5 | expect(within(20.5, 21, 0.50)).toBe(true)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/test/wrap.test.js:
--------------------------------------------------------------------------------
1 | import { wrap } from '../src/math-toolbox'
2 |
3 | describe('Wrap any value that is not inbetween the two bounds', () => {
4 | it('Expect value 1 in range 0-10 to return 1', () => {
5 | expect(wrap(1, 0, 10)).toBe(1)
6 | })
7 |
8 | it('Expect value 11 in range 0-10 to return 1', () => {
9 | expect(wrap(11, 0, 10)).toBe(1)
10 | })
11 |
12 | it('Expect value -2 in range 0-10 to return 8', () => {
13 | expect(wrap(-2, 0, 10)).toBe(8)
14 | })
15 |
16 | it('Expect value 10 in range 1 - -10 to return 0', () => {
17 | expect(wrap(10, 1, -10)).toBe(0)
18 | })
19 | })
20 |
--------------------------------------------------------------------------------