みなさんこんにちは、エンジニアののびすけです。
最近はWeb上で動画背景を使った表現のサイトが増えてきてますね。Webブラウザの性能が上がってきている昨今では、(スペックにもよるのですが)ブラウザ側でそういった処理もガンガンできます。
今回はそんなリッチな表現ができる「Seriously.js」をご紹介します。
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
パノラマ写真に対して、エフェクトやスケールなどをリアルタイムで変更できます。
Three.js利用
http://brianchirls.github.io/Seriously.js/examples/demo/threejs-source.html
WebGLをサポートしているので、Three.jsを使ってWebGLを操作しつつ、リアルタイムエフェクトを掛けることができます。
Web Cameraを使ったサンプル
http://brianchirls.github.io/Seriously.js/examples/camera/
PCのWebカメラを使ってエフェクトを掛けることができます。
Seriously.jsを使ってみよう (準備)
実際に使ってみましょう。公式チュートリアルは少し分かりにくい気がしたので、独自で説明してみます。
Seriously.jsのダウンロードはこちらからできます。
ページ右下のDownload ZIPからダウンロードするか、git cloneしましょう。
$ git clone git@github.com:brianchirls/Seriously.js.git
Seriously.js本体
ダウンロードした場合、Seriously.js-master/seriously.jsを使います。
Effectsモジュール
さまざまなエフェクトが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ファイル
コピペ実装でSeriously.jsを使ってみよう
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体験
※ 刀でズバッと斬るようなアニメーションをHTML・CSS・JS(jQuery)で実装する方法
※ CSS3とjQueryでオリジナル画像のスプライトアニメーションを実装する方法
LIGはWebサイト制作を支援しています。ご興味のある方は事業ぺージをぜひご覧ください。