注意書き
2019 年 10 月 9 日に開催の #tc39_study 用に作成した資料です。
執筆時点で TC39 の Proposals に上がっている機能を紹介します。
将来的に JavaScript(ECMAScript)に取り入れられるかもしれませんし、取り入れられないかもしれませんし、紹介内容から仕様が大きく変更になるかもしれません。
TC39 の承認プロセスについては、https://tc39.es/process-document/ をご覧ください。
Math Extensions
Math
に 4 つの関数と 2 つの定数を追加する Proposal です。
コンピュータグラフィックス方面で時々使うような処理が追加されます。
本記事の執筆時点で Stage 1 です。
Math.clamp(x, lower, upper)
x
が lower
を下回ったときは lower
を、upper
を上回った時は upper
を、どちらでもないときは x
を返すような関数です。
値が設定された下限と上限を超えないように変換するときに有用です。
Math.min
と Math.max
を使えば同等の処理ができます。
使い方
console.log(Math.clamp(0, -100, 100))
// -> 0
console.log(Math.clamp(-200, -100, 100))
// -> -100
console.log(Math.clamp(200, -100, 100))
// -> 100
console.log(Math.clamp(NaN, -100, 100))
// -> NaN
console.log(Math.clamp(0, NaN, 100))
// -> NaN
console.log(Math.clamp(0, -100, NaN))
// -> NaN
同等の処理
const clamp = (x, lower, upper) => {
return Math.min(Math.max(x, lower), upper)
}
console.log(clamp(0, -100, 100))
console.log(clamp(-200, -100, 100))
console.log(clamp(200, -100, 100))
console.log(clamp(NaN, -100, 100))
console.log(clamp(0, NaN, 100))
console.log(clamp(0, -100, NaN))
Math.scale(x, inLow, inHigh, outLow, outHigh)
x
を線形変換した値を返します。
2つの数直線があり、片方に x
と inLow
、inHigh
が、もう片方に y
と outLow
、 outHight
があり、inLow
と outLow
、inHigh
と outHigh
がそれぞれ対応しているとき、x
に対応する y
を計算するイメージです。
以下の関係が成り立ちます。
\frac{x - \text{inLow}}{\text{inHigh} - \text{inLow}} = \frac{y - \text{outLow}}{\text{outHigh} - \text{outLow}}
使い方
console.log(Math.scale(50, 0, 100, -10, 10))
// -> 0
console.log(Math.scale(200, 0, 100, -10, 10))
// -> 30
console.log(Math.scale(80, 0, 100, 10, -10))
// -> -6
console.log(Math.scale(NaN, 0, 100, -10, 10))
// -> NaN
console.log(Math.scale(50, NaN, 100, -10, 10))
// -> NaN
console.log(Math.scale(50, 0, NaN, -10, 10))
// -> NaN
console.log(Math.scale(50, 0, 100, NaN, 10))
// -> NaN
console.log(Math.scale(50, 0, 100, -10, NaN))
// -> NaN
console.log(Math.scale(Infinity, 0, 100, -10, 10))
// -> Infinity
console.log(Math.scale(-Infinity, 0, 100, -10, 10))
// -> -Infinity
console.log(Math.scale(50, -Infinity, 100, -10, 10))
// -> NaN
console.log(Math.scale(50, 0, Infinity, -10, 10))
// -> -10
console.log(Math.scale(50, 0, 100, -Infinity, 10))
// -> NaN
console.log(Math.scale(50, 0, 100, -10, Infinity))
// -> Infinity
Math.radians(degrees)
degrees
をラジアンに変換した値を返します。
使い方
console.log(Math.degrees(-1))
// -> -57.29577951308232
console.log(Math.degrees(0))
// -> 0
console.log(Math.degrees(1))
// -> 57.29577951308232
console.log(Math.degrees(Math.PI))
// -> 180
console.log(Math.degrees(2 * Math.PI))
// -> 360
console.log(Math.degrees(3 * Math.PI))
// -> 540
console.log(Math.degrees(NaN))
// -> NaN
console.log(Math.degrees(+Infinity))
// -> Infinity
console.log(Math.degrees(-Infinity))
// -> -Infinity
Math.degrees(radians)
radians
を度数に変換した値を返します。
使い方
console.log(Math.radians(-120))
// -> -2.0943951023931953
console.log(Math.radians(0))
// -> 0
console.log(Math.radians(120))
// -> 2.0943951023931953
console.log(Math.radians(240))
// -> 4.1887902047863905
console.log(Math.radians(360))
// -> 6.283185307179586
console.log(Math.radians(480))
// -> 8.377580409572781
console.log(Math.radians(NaN))
// -> NaN
console.log(Math.radians(+Infinity))
// -> Infinity
console.log(Math.radians(-Infinity))
// -> -Infinity
Math.RAD_PER_DEG
1° あたりのラジアンを表す定数です。
\frac{180}{\pi} = 57.29577951308232
Math.DEG_PER_RAD
1 ラジアンあたりの度数を表す定数です。
\frac{\pi}{180} = 0.0174532925199432
Polyfill
core-js/proposals/math-extensions
を読み込んでください。
CommonJS
require('core-js/proposals/math-extensions')
ES Modules
import 'core-js/proposals/math-extensions'
所感
JavaScriptでお絵描きしてたらたまに必要になる。
個人的に特にscale
は、これのためだけにd3-scaleを入れたりするので標準で入ってくれると嬉しい。