Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

easingを計算でやってみる

More than 1 year has passed since last update.

CSSアニメーションでも各種JSのライブラリでも、easingはとても簡単にできるようになりましたが、
それらを使わずにJavaScriptで値を計算してやるのも面白いです。
昔ActionAcriptでやっていたことの復習です。

練習がてらやってみます。
今回はまず基本的な徐々に減速するやつ

javascript
const fps = 1000/30 //calを実行するインターバル1秒間に30回
const dx = 200 //目標値
const speed = 0.3
let _tmp = 0 //現在値
function cal()
{
  _tmp += (dx - _tmp) * speed
  console.log(_tmp)
}
const int = setInterval(cal, fps)

目的地(値)と現在値との距離を少しずつ加算していく感じ。
距離がつまってくると加算される値も小さくなるので減速する
というイメージです。

大筋はこんなところいいですが、
目標値に至ったところでsetIntervalをクリアしないといけません。
が、tmpをトレースしても
加算される値が小さくなるので現在値tmpが99.999999...のまま100にはなりません。

なので加算される値がある程度小さくなったら処理を停止し、現在値に目標値を代入します。

let _sa = 200
function cal()
{
  if(_sa >= 0.03 )
    _sa = (dx - _tmp) * speed
    _tmp += _sa
    console.log(_tmp)
  }
}
else
{
  clearInterval(int)
}

こんな感じです。
https://jsfiddle.net/urtyo64x/4/

もうひとつMath.sinを使った減速と加速の繰り返し。
sinについてはこのgifを見るとすごく理解しやすかったです。
https://twitter.com/InfinityLoopGIF/status/997448838737776641

javascript
function cal()
{   

  if(ang < 360 )
  {

    ang += 3 //角度を3度づつ増やしていく
    _tmp = Math.sin(ang * (Math.PI / 180)) 

    obj.style.left = (100 * _tmp) +'px'

  }
  else
  {
    //角度をリセット
    ang = 0
  }
}
const int = setInterval(cal, fps)

うまく振り子のようになっています。
https://jsfiddle.net/pryvn4tx/6/

今日はここまで。

dskymd
JavaScript, Vue.js, Nuxt.js書いてます。
https://dskymd.com
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away