Web事業部_クリエイティブ
Web事業部_クリエイティブ
2018.04.04

とても軽量! ドラッグアニメーションに優れたPopmotion.js実装例!

はやち

どうもですよ、はやちでございますよ。(:D
最大11.5kbしかないトゥイーンアニメーション、ドラッグアニメーションに優れたPopmotion.jsについてご紹介します。(☞ ՞ਊ ՞)☞

導入方法

npmからインストールはこちらから。

npm install popmotion –save

importはこちら!

import { action } from 'popmotion';
// or stand-alone:
import action from 'popmotion/action';

これで導入は完了になります。

実装の紹介

実装できるアニメーションをご紹介します。(☞ ՞ਊ ՞)☞

トゥイーンアニメーション

popmotionイメージ1

const { easing, tween, styler } = window.popmotion;

const divStyler = styler(document.querySelector('.target'));

tween({
from: 0,
to: { x: 300, rotate: 180 },
duration: 1000,
ease: easing.backOut,
flip: Infinity,
}).start(divStyler.set);

ドラッグの操作

ドラッグに合わせてついていく仕様

popmotionイメージ2

const { styler, spring, listen, pointer, value } = window.popmotion;

const ball = document.querySelector('.target');
const divStyler = styler(ball);
const ballXY = value({ x: 0, y: 0 }, divStyler.set);

listen(ball, 'mousedown touchstart')
.start((e) => {
e.preventDefault();
pointer(ballXY.get()).start(ballXY);
});

listen(document, 'mouseup touchend')
.start(() => {
ballXY.stop();
});

ドラッグから手を放したら元の位置に戻る仕様

popmotionイメージ3

const { styler, spring, listen, pointer, value } = window.popmotion;

const ball = document.querySelector('.target');
const divStyler = styler(ball);
const ballXY = value({ x: 0, y: 0 }, divStyler.set);

listen(ball, 'mousedown touchstart')
.start((e) => {
e.preventDefault();
pointer(ballXY.get()).start(ballXY);
});

listen(document, 'mouseup touchend')
.start(() => {
spring({
from: ballXY.get(),
velocity: ballXY.getVelocity(),
to: { x: 0, y: 0 },
stiffness: 200,
}).start(ballXY);
});

クリックの操作によるアニメーション

popmotionイメージ4

const { easing, physics, spring, tween, styler, listen, value, transform } = window.popmotion;
const { pipe, clampMax } = transform;

const ball = document.querySelector('.target');
const ballStyler = styler(ball);
const ballY = value(0, (v) => ballStyler.set('y', Math.min(0, v)));
const ballScale = '';
let count = 0;
let isFalling = false;

const checkBounce = () => {
if (!isFalling || ballY.get() < 0) return;

isFalling = false;
const impactVelocity = ballY.getVelocity();
const compression = spring({
to: 1,
from: 1,
velocity: - impactVelocity * 0.01,
stiffness: 800
}).pipe((s) => {
if (s >= 1) {
s = 1;
compression.stop();

if (impactVelocity > 20) {
isFalling = true;
gravity
.set(0)
.setVelocity(- impactVelocity * 0.5);
}
}
return s;
}).start(ballScale);
};

const gravity = physics({
acceleration: 2500,
restSpeed: false
}).start((v) => {
ballY.update(v);
checkBounce(v);
});

listen(ball, 'mousedown touchstart').start((e) => {
e.preventDefault();

isFalling = true;
ballScale.stop();
ballScale.update(1);

gravity
.set(Math.min(0, ballY.get()))
.setVelocity(-1200);
});

まとめ

いかがでしたか?
ドラッグ系のモーションが手軽に実装できるのが大きいなと思いました! 容量が軽量なのもあり! 使えるのではないかと! なにかドラッグ操作のUIやおもしろい動作のするデザインに使えたらいいですね……ではでは。