ぷるるんっアニメーション

ぷるるんっ!っていうのを実装してみたかったのでお試し実装。
下の四角をマウスでふるふるしたら揺れます。
sin(t)を増幅する増幅率をどんどん減衰させていけば十分だと気づいたので、それで。

ぷるるん

おとなしく、ライブラリを使った方が楽なのは事実だけど、プリミティブに実装してみるのも楽しい。

<svg xmlns="http://www.w3.org/2000/svg"
     width="192px" height="192px"
     viewbox="-32 -32 192 192">
<g id="prrn">
<rect width="128" height="128" fill="#d04034"/>
<text x="0" y="80" font-size="32" fill="black">ぷるるん</text>
</g>
</svg>
<script>
var delta = Math.PI / 16; // 角速度(ラジアン/フレーム)
var th = 0.01; // アニメーション終了の閾値
var v0 = 30; // マウスでふるふるしたときの初速度
var vr = 0.93; // 振幅(増幅率)の減衰率
var x = 0, v = 0; // 角座標, 振幅
var animating = false;
var g = document.getElementById("prrn");
g.addEventListener("mouseover", function() {
  if (!animating) {
    v = v0;
    animating = true;
    anim();
  } else {
    v = Math.min(v + v0, 90); // 90度以上は回らないように調整
  }
});
function anim() {
  var c = Math.sin(x * delta) * v;
  x++;
  var t = "";
  if (v < v0 * th && -th <= c && c <= th) { // アニメーション終了
    x = v = 0;
    animating = false;
  } else {
    var p = g.getBBox().width / 2;
    t = "rotate(" + c + " " + p + " " + p + ")";
    v *= vr;
  }
  g.setAttribute("transform", t);
  if (t != "") setTimeout("anim()", 10);
}
</script>