SVGパスを使ったアニメーションライブラリ
mo.jsは非jQuery依存のシンプルなアニメーションライブラリです。http://mojs.io/
公式デモがかなり軽量に動いていたので試しに触ってみました。
svgのパスを元にstyleをガシガシ書き換えてつくり込む感じ。
APIは公式を見ればあんまり説明必要なさそうだったので、webpack+babelでやってみたらこうなった、というコードを乗せておきます。凝った動きを作りこむためには沢山svgを用意しパスをゴネゴネする必要がありそうだったので、svgはsvg-inline-loaderで読み込み、GUIで演出に集中できる様にするのがゴールです。
loaders: [
{ test: /\.js$/, loaders: ['babel-loader'], exclude: /node_modules/ },
{ test: /\.svg$/, loader: 'svg-inline'}
]
こんな感じのsvgを用意しておきます。サイズは100px_100px。
バウンスのイージング曲線ですね。
円を10個動かして何かしようとしてみました。
import Circles from './circles';
new Circles('.circles',10).run();
せっかくの非jQuery依存なので、querySelectorとDOMParserで、importしたsvgからpath要素のd属性を拾います。そのd属性からTweenに渡すeasing関数を生成します。これでわざわざd属性をコピペしなくて済む様になりました。
import mojs from 'mo-js';
import Circle from './circle';
import AnimatePath from '../svg/animatePath.svg';
export default class Circles {
constructor(selector, count) {
this.circles = [];
const dom = document.querySelector(selector);
const svg = new DOMParser().parseFromString(AnimatePath,'text/xml');
const d = svg.querySelector('path').getAttribute('d');
const easing = mojs.easing.path(d);
for (let i=0; i<count; i++) {
const c = new Circle(easing,i);
dom.appendChild(c.dom);
this.circles.push(c);
}
return this;
}
run() {
for (let i=0; i<this.circles.length; i++) {
this.circles[i].run();
}
return this;
}
}
せっかくのbabelなので、OOPに寄せていければいいなと。今のとこmojs.Tweenのoptionがかなり少ないので、setTimeoutでdelayを追加してみた。(今入っているoptionのdelayはアニメーションリピートのインターバルを指してる)公式のAPIsが非リンクだったので、まだこれからいろいろ実装するものだと思われる。
import mojs from 'mo-js';
export default class Circle {
constructor(easing,x) {
let div = document.createElement('div');
div.setAttribute('class', 'circle');
div.setAttribute('data-css-hide', 'true');
this.dom = div;
this.easing = easing;
this.x = x;
return this;
}
run() {
setTimeout(() => {
new mojs.Tween({
repeat: 99999,
delay: 0,
duration: 2000,
onUpdate: (progress) => {
let value = this.easing(progress);
this.dom.style.transform =
`translateX(${20*this.x-100}px)
translateY(${(1-value)*100}px)
scale(${value})`;
}
}).run();
this.dom.setAttribute('data-css-hide', 'false');
}, this.x*30);
return this;
}
};
用意したstyleはこんな感じ。
@import 'nib';
global-reset();
.container {
width: 100%;
height: 100%;
position: fixed;
overflow: hidden;
}
.circles {
top: 50%;
left: 50%;
position: fixed;
}
.circle {
size = 10px;
width: size;
height: size;
position: absolute;
margin-left: @width*-.5;
margin-top: @height*-.5;
border-radius: @width*.5;
background: #aaf;
&[data-css-hide="true"] {
display:none;
}
}
これらをpackするとこんな残念な感じのサンプルができます。
これだったらcssAnimationだけで完結できるね…
で、演出には集中できるの?
svgを保存する度にbrowserSyncとかで即確認、演出に集中しようっていう目的なのですが、svgファイルは一度閉じてしまうとIllustratorでは座標がずれてしまい、sketch.appでは直接編集出来ず、どちらも元ファイルから書き出ししなければいけない様子で、ここのフローは今後も調査が必要だなぁというお話でした。