VIDEO LESSON

JavaScriptのMath.tanh():入力に応じた移動量を滑らかに制限するの解説動画

再生時間 7:41動画を別のタブで開く ↗
動画の字幕・文字起こしを読む

再生中の字幕を濃い黒で表示し、一番上に追従します。字幕の行を選ぶと、その位置から再生できます。

  1. 0:00こんにちは。
  2. 0:00今回はジャバスクリプトのマス・タンエイチを紹介します。
  3. 0:05これは、数値の双曲線正接を求める、組み込みの計算関数です。
  4. 0:09ドラッグ操作やポインターに反応する演出では、入力をそのまま移動量にすると、
  5. 0:14操作が大きいほど要素が遠くまで動いてしまいます。
  6. 0:19かといって、境界で突然打ち切ると、上限の近くで反応が急に変わります。
  7. 0:24マス・タンエイチは、ゼロ付近では入力の変化を比較的よく伝えながら、絶対値が大きくなるほど出力の変化を小さくします。
  8. 0:34この動画では、正負の入力を最大およそ四十ピクセルの移動量へ変換する例を中心に、
  9. 0:39基本、計算の読み方、失敗しやすい注意点の順に解説します。
  10. 0:44まず動作環境です。
  11. 0:46マス・タンエイチは、二千十五年七月以降、ブラウザー間で広く利用できる機能とされています。
  12. 0:52現在のクローム、エッジ、ファイアフォックス、サファリで使えます。
  13. 0:57ノード・ジェイエスでも、追加パッケージなしで動作します。
  14. 1:01ドムや外部ライブラリーを使わないため、同じ計算コードをブラウザーとノード・ジェイエスの両方で利用できます。
  15. 1:09古い組み込みブラウザーを対象に含める場合は、タイプオブで関数として存在するかを確認してください。
  16. 1:16記事の確認日は二千二十六年十月二十四日で、ノード・ジェイエスの対象は二十二系と二十四系です。
  17. 1:23基本の書き方を見ましょう。
  18. 1:26マス・タンエイチは、マスオブジェクトの静的メソッドなので、マスのインスタンスを作る必要はありません。
  19. 1:35いつもマス・タンエイチ、かっこ、という形で呼び出します。
  20. 1:40引数は、双曲線正接を求めたい数値を一つだけ渡します。
  21. 1:45戻り値は計算結果を表す数値です。
  22. 1:48たとえば入力がゼロなら結果はゼロ、入力が一なら結果はおよそゼロ点七六一六になります。
  23. 1:55入力がゼロ点五なら、結果はおよそゼロ点四六二一です。
  24. 2:00入力の符号は結果にもそのまま現れるので、正の入力には正の結果、負の入力には負の結果が返ります。
  25. 2:09出力の範囲を押さえましょう。
  26. 2:11数学の上では、有限の入力に対する結果は、マイナス一より大きく、一より小さい範囲におさまります。
  27. 2:18入力の絶対値が大きくなるほど、結果は一、またはマイナス一へ近づいていきます。
  28. 2:25ただし注意点があります。
  29. 2:26ジャバスクリプトの数値は、倍精度の浮動小数点数で表されるため、計算には精度の限界があります。
  30. 2:34十分に大きな有限の入力では、丸めによって結果がちょうど一やマイナス一になることがあります。
  31. 2:41スライドの例でも、入力が二十だと結果は一になっています。
  32. 2:45有限の値なら端には絶対に届かない、という判定には使わないでください。
  33. 2:51特別な値の扱いも確認しておきましょう。
  34. 2:53入力がゼロのときはゼロが返り、マイナスゼロのときはマイナスゼロが返ります。
  35. 2:58符号付きのゼロが区別される点が特徴です。
  36. 3:01入力が正の無限大なら一、負の無限大ならマイナス一が返ります。
  37. 3:05入力が数値ではないことを示すナンなら、結果もナンになります。
  38. 3:09実務のコードでは、こうした特別な値をそのまま通してよいのかを先に決めておくことが大切です。
  39. 3:15このあとの実例では、有限ではない入力をエラーとして扱い、想定外の値が移動量に化けてしまうことを防いでいます。
  40. 3:22ここからは実例です。
  41. 3:24入力を移動量へ変換する、トューオフセットという関数を考えます。
  42. 3:29この関数は、まず入力が有限の数値かどうかを確かめ、有限でなければタイプエラーを投げます。
  43. 3:36スケールとリミットについても、正の有限の数値かどうかを確かめ、問題があればレンジエラーを投げます。
  44. 3:44そのうえで、入力をスケールで割り、マス・タンエイチを通し、最後にリミットを掛けて返します。
  45. 3:51計算そのものは一行ですが、その前の検証が、設定ミスや入力ミスを静かに飲み込まないための大切な部分です。
  46. 3:59処理はすべて同期的で、非同期の待ち合わせは不要です。
  47. 4:04期待出力を読みましょう。
  48. 4:06入力が百のとき、スケールで割ると一になり、マス・タンエイチの結果はおよそゼロ点七六一六です。
  49. 4:13これにリミットの四十を掛けると、およそ三十点四六ピクセルになります。
  50. 4:19入力が三百になっても、結果はおよそ三十九点八十ピクセルにとどまり、四十を超えることはありません。
  51. 4:27負の入力では、符号を保ったまま同じ大きさが返ります。
  52. 4:31また、文字列の百を渡すとタイプエラー、スケールにゼロを渡すとレンジエラーが表示されます。
  53. 4:39これらの出力は、ノード・ジェイエスの実機でも同じになることを確認済みです。
  54. 4:45調整の考え方です。
  55. 4:46リミットは、出力の上限の大きさを決める値です。
  56. 4:50まず許容できる最大の移動量としてリミットを決めてください。
  57. 4:55次にスケールを調整します。
  58. 4:57スケールは反応の強さを決める値で、小さくすると小さな入力でも上限へ早く近づき、
  59. 5:02大きくすると同じ入力に対する移動量が小さくなります。
  60. 5:08ゼロ付近の感度は、おおよそリミットをスケールで割った値で考えられます。
  61. 5:13この例ではおよそゼロ点四なので、非常に小さな入力では、入力のおよそゼロ点四倍が移動量になります。
  62. 5:21上限と感度を別々の設定として持つと、調整の意図を説明しやすくなります。
  63. 5:27注意点の一つ目は、暗黙の型変換です。
  64. 5:30マス・タンエイチ自体は、引数を数値へ変換してから計算します。
  65. 5:35そのため、数値の文字列はそのまま計算され、ヌルはゼロとして扱われ、アンディファインドはナンになります。
  66. 5:44入力ミスを検出したい処理では、この動作をそのまま受け入れると、問題が隠れてしまいます。
  67. 5:51また、ビッグイントやシンボルを渡すと、数値への変換ができずタイプエラーになります。
  68. 5:58実例のトューオフセットが、有限の数値だけを受け付けて文字列も拒否しているのは、
  69. 6:02このためです。
  70. 6:06フォーム入力を使う場合は、呼び出す前に空欄を確認し、数値へ変換したうえで検証してください。
  71. 6:14注意点の二つ目は、設定値の扱いです。
  72. 6:16スケールがゼロだと、ゼロ以外の入力を割った結果は、正負の無限大になります。
  73. 6:22するとマス・タンエイチの結果が端点になり、設定ミスなのに正常に制限できたように見えてしまいます。
  74. 6:29実例のコードが、スケールとリミットを正の有限の数値かどうか先に確認している理由はここにあります。
  75. 6:36さらに、極端に小さな正のスケールでも、割り算の結果が無限大へあふれる可能性があります。
  76. 6:42通常の画面設定では、極端な値を許可しない設計が扱いやすいでしょう。
  77. 6:47例外は同期的に起きるので、トライキャッチで処理できます。
  78. 6:51活用場面とまとめです。
  79. 6:53マス・タンエイチは、ドラッグの端で抵抗感を出す変換、ポインターからの距離に応じてカードの傾きを一定範囲に収める計算、
  80. 7:00ゲームの入力値から上限のある操作量を求める処理などに向いています。
  81. 7:07一方で、この変換は非線形なので、入力が二倍になっても出力は二倍にはなりません。
  82. 7:13正確な距離や測定値の表示には向かず、操作感を調整する用途に適しています。
  83. 7:19また、結果は入力値だけから決まるため、時間に沿った揺れを取り除く効果はありません。
  84. 7:25導入するときは、元の入力値も保持し、表示に使う値だけを変換すると、あとから再調整しやすくなります。
  85. 7:33お疲れさまでした。
  86. 7:35マス・タンエイチは、入力をなめらかに制限する関数だと覚えておいてください。
日本語字幕をダウンロード(WebVTT)

この動画で学べること

Math.tanh()で正負の入力を一定範囲の移動量へ変換する方法を解説。引数・戻り値、ブラウザーとNode.jsの実行手順、期待出力、入力検証や丸め誤差の注意点を学べます。

解説記事・サンプルコードを読む:JavaScriptのMath.tanh():入力に応じた移動量を滑らかに制限する →