みなさんこんにちは、エンジニアののびすけです。
最近はWeb上で動画背景を使った表現のサイトが増えてきてますね。Webブラウザの性能が上がってきている昨今では、(スペックにもよるのですが)ブラウザ側でそういった処理もガンガンできます。
今回はそんなリッチな表現ができる「Seriously.js」をご紹介します。
少し前に話題になった、動画や画像にブラウザ上でリアルタイムエフェクトを掛けることができるライブラリ。複雑なエフェクトをたくさん使えるにもかかわらず、簡単なJavascriptの記述で操作できます。
まずは、どんなことができるのかが気になると思います。Seriously.jsの公式デモを紹介してきます。
こちらのページにデモへのリンクがあるので試してみましょう。
※執筆時点ではGoogleChromeで動作確認をしています。
http://brianchirls.github.io/Seriously.js/examples/crop.html
クロップ処理をリアルタイムに行えます。けっこう使いどころがあるのではないでしょうか。
http://brianchirls.github.io/Seriously.js/examples/blur/blur.html
よくある表現ですね。画像や動画のぼかしをリアルタイムに変更できます。
http://brianchirls.github.io/Seriously.js/examples/demo/panorama.html
パノラマ写真に対して、エフェクトやスケールなどをリアルタイムで変更できます。
http://brianchirls.github.io/Seriously.js/examples/demo/threejs-source.html
WebGLをサポートしているので、Three.jsを使ってWebGLを操作しつつ、リアルタイムエフェクトを掛けることができます。
http://brianchirls.github.io/Seriously.js/examples/camera/
PCのWebカメラを使ってエフェクトを掛けることができます。
実際に使ってみましょう。公式チュートリアルは少し分かりにくい気がしたので、独自で説明してみます。
Seriously.jsのダウンロードはこちらからできます。
ページ右下のDownload ZIPからダウンロードするか、git cloneしましょう。
$ git clone git@github.com:brianchirls/Seriously.js.git
ダウンロードした場合、Seriously.js-master/seriously.jsを使います。
さまざまなエフェクトがSeriously.js-master/effectsフォルダにあります。このフォルダごとコピーしましょう。
Seriously.jsでエフェクトを掛ける対象の画像や動画を用意する必要があります。
とりあえず、サンプルの色鉛筆とロボットの画像をダウンロードしておきます。
effectsフォルダ、seriously.js、require.jsを以下のように設置しましょう。
mysample ├─ img │ ├─ pencils.jpg │ └─ robot.jpg │ ├─ js │ ├─ require.js │ ├─ seriously.js │ └─ effects │ ├─ seriously.accumulator.js │ ├─ seriously.ascii.js │ └─ ・・・省略 │ └─ index.html //メインのhtmlファイル
index.htmlに以下のコードをコピペで貼り付けてみましょう。
<!DOCTYPE html>
<html>
<head>
<title>Seriously.js Gradient Wipe Example</title>
<style>
canvas {
display: block;
margin: auto;
border: black solid 1px;
}
img {
display: none;
}
</style>
</head>
<body>
<img id="robot" src="img/robot.jpg"/>
<img id="pencils" src="img/pencils.jpg"/>
<canvas id="canvas" width="960" height="540"></canvas>
<div id="controls">
<label>Transition <input id="transition" type="range" min="0" max="1" step="0.0001" value="0"/></label>
<label>Smoothness <input id="smoothness" type="range" min="0" max="1" step="0.0001" value="0.1"/></label>
</div>
<script src="js/seriously.js"></script>
<script src="js/effects/seriously.gradientwipe.js"></script>
<script src="js/effects/seriously.simplex.js"></script>
<script src="js/effects/seriously.blend.js"></script>
<script>
(function (Seriously) {
// declare our variables
var source = document.getElementById('source'),
seriously, // the main object that holds the entire composition
gradientwipe, // gradientwipe node
ctx, grd,
reformatRobot,
reformatPencils,
blend,
target; // a wrapper object for our target canvas
seriously = new Seriously();
gradientwipe = seriously.effect('gradientwipe');
blend = seriously.effect('blend');
target = seriously.target('#canvas');
reformatRobot = seriously.transform('reformat');
reformatPencils = seriously.transform('reformat');
reformatRobot.source = '#robot';
reformatRobot.width = 960;
reformatRobot.height = 540;
reformatRobot.mode = 'cover';
reformatPencils.source = '#pencils';
reformatPencils.width = 960;
reformatPencils.height = 540;
reformatPencils.mode = 'cover';
noise = seriously.effect('simplex');
noise.width = 960;
noise.height = 540;
noise.noiseScale = [5, 5];
noise.octaves = 3;
gradientwipe.source = reformatRobot;
gradientwipe.gradient = noise;
gradientwipe.transition = '#transition';
gradientwipe.smoothness = '#smoothness';
blend.bottom = reformatPencils;
blend.top = gradientwipe;
target.source = blend;
//render
seriously.go();
}(window.Seriously));
</script>
</body>
</html>
パソコンのローカルサーバーなどでindex.htmlにアクセスしてみましょう。
http://localhost/mysample/index.htmlなどになると思います。
メモリの位置を変更することで、2枚重なった写真のエフェクトを調節できます。
index.htmlにファイルアクセスしようとすると、Unable to access cross-domain imageというエラーが出て画像や動画は表示されません。Seriously.js側でクロスドメイン制御をしているみたいです。
同じサーバー(ドメイン)に画像や動画を設置するようにしましょう。
今回の記事を書くにあたり、ゴキブリおもちゃでドッキリ動画を作りました。
| 人物紹介:せいと フロントエンドエンジニア。通称ほりぼーい。今回のドッキリ動画の対象者。 |
| 人物紹介:まろ フロントエンドエンジニア。通称まろ氏。ブログネタに困るとほりぼーいを使う。 |
| 人物紹介:のびすけ バックエンドエンジニア。通称のびすけ。上京するまでゴキブリは見たことがなかった。 |
ほりぼーいが昼休みから帰ってきたときに、パソコンにゴキブリのおもちゃを仕込んで驚かす動画です。まろ氏は、撮影していることをほりぼーいに悟られないようにトランプタワーをしています(謎)
2つのカメラで撮影した動画を使ってエフェクトをかけてみます。メインの動画上にマウスホバーをすることで、もう1つの角度から撮影した動画がマスクとなって表示されます。マウスを動かすことで違う視点で動画を見ることができます。
↓動画スタート!のボタンを押すと、開始されます。
プロジェクトのルートにvideoフォルダを作成して、利用する2つ動画を設置しておきます。
mysample2 ├─ video │ ├─ boy_main.mov //今回使った動画1 │ └─ boy_sub.mov //今回使った動画2 │ ├─ js │ ├─ require.js │ ├─ seriously.js │ └─ effects │ ├─ seriously.accumulator.js │ ├─ seriously.ascii.js │ └─ ・・・省略 │ └─ index.html //メインのhtmlファイル
これもコピペで使えると思います。
もし、動画読み込みで403エラーなどが発生した場合は以下のように権限を変更してみましょう。
$ pwd /path/to/maysample2 $ chmod 644 ./video/*.mov
動画の拡張子がvideoタグで利用できるものなのかという確認もしておくと良いです。動画が動作しない場合の原因はほぼこれで解決できる気がします。
<!DOCTYPE html>
<html>
<head>
<title>Seriously.js Channels Example</title>
<style type="text/css">
img, video {
display: none;
}
</style>
</head>
<body>
<button name="button" id="start_btn">動画スタート!</button>※音が出ます。Chromeなどモダンブラウザ推奨。<br/>
<video src="./video/boy_main.mov" id="main_video"></video>
<video src="./video/boy_sub.mov" id="sub_video"></video>
<canvas id="canvas" width="640" height="619"></canvas>
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="./js/require.js"></script>
<script>
var main_v = document.getElementById("main_video");
var sub_v = document.getElementById("sub_video");
require.config({
baseUrl: './js'
});
require([
'seriously',
'effects/seriously.channels',
'effects/seriously.blend'
], function (Seriously) {
// declare our variables
var seriously, // the main object that holds the entire composition
channels, // a split effect
blend,
target, // a wrapper object for our target canvas
scaleSub,
scaleMain,
moveMask,
resizeMask,
mask = document.createElement('canvas'),
ctx = mask.getContext('2d');
seriously = new Seriously();
target = seriously.target('#canvas');
channels = seriously.effect('channels');
blend = seriously.effect('blend');
scaleSub = seriously.transform('2d');
scaleSub.source = seriously.source('#sub_video');
scaleSub.scale(440/989);
scaleMain = seriously.transform('reformat');
scaleMain.source = seriously.source('#main_video');
scaleMain.width = 640;
scaleMain.height = 619;
scaleMain.mode = 'cover';
//draw mask
mask.width = 100;
mask.height = 100;
ctx.fillColor = 'black';
ctx.fillRect(0, 0, 400, 400);
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, 160, 160);
console.log(ctx);
resizeMask = seriously.transform('reformat');
resizeMask.source = mask;
resizeMask.width = target.width;
resizeMask.height = target.height;
moveMask = seriously.transform();
moveMask.source = resizeMask;
// moveMask.rotation = 30;
moveMask.scale(0.7);
channels.source = scaleSub;
channels.alphaSource = moveMask;
channels.alpha = 'red';
channels.blue = 'green';
channels.green = 'blue';
blend.bottom = scaleMain;
blend.top = channels;
target.source = blend;
window.addEventListener('mousemove', function (evt) {
var canvas = target.original,
x = evt.pageX - canvas.offsetLeft,
y = evt.pageY - canvas.offsetTop;
moveMask.translateX = x - canvas.width / 2;
moveMask.translateY = canvas.height / 2 - y;
}, false);
$('#start_btn').on('click', function(){
main_v.play();
sub_v.play();
seriously.go();
});
});
</script>
</body>
</html>
基本的にはChannel Mappingのデモを参考にして書いています。
対象とした動画はネタな感じになりましたが、最近は動画を使ったサイトが多くなってきていて、2015年トレンドとも言われているみたいです。Seriously.jsのように、簡単に動画エフェクトを行えるライブラリの使い方を覚えておくと流行の表現ができると思います。
2つの動画を重ね合わせるという表現はまだまだ一般的ではないかもしれませんが、表現したい内容によってはかなり活きてくると思いますので、参考になれば幸いです。
それでは!
【表現の幅を広げよう】
※ p5.jsでProcessingのようにリッチなWeb表現を作るチュートリアル
※ 圧倒的な3D表現にWebの未来を感じるWebGLを使ったサイト・デモ20選
※ デザイナー・ノンプログラマにおすすめしたいThree.jsのカンタン3D体験