PixiJS 不只用來呈現視覺動態,也適合用在一些功能
本篇講的是合圖 / 紙娃娃功能
實作時想法:
Step1. 先用測試的圖片實作功能:
先使用固定的圖片,可以的話再讓使用者自己上傳
Step2. 選到的圖可以拖動、縮放、旋轉:
合圖 / 紙娃娃玩的是調整位置與大小,看起來使用 PixiJS 不難做到
Step3. 匯出與測試:
與後端配合,可以的話串接資料越單純越好
Step4. 讓使用者上傳圖片
由於後端部分由同事製作,因此實作時我的第一步是:
匯出測試
匯出測試用,文字為當下時間
按下Submit按鈕後會存圖開在新視窗裡
var basicText;
var now = new Date();
// 建立一個 PIXI.Text 元件
basicText = new PIXI.Text(getDateString(now));
app.stage.addChild(basicText);
setInterval(
function(){
now = new Date();
// 更新顯示文字
basicText.text = getDateString(now);
}, 1000);
// 單純回傳顯示的文字
function getDateString($date){
return $date.getFullYear()+"/"+
($date.getMonth()+1)+"/"+
$date.getDate()+" "+
$date.getHours()+":"+
$date.getMinutes()+":"+
$date.getSeconds();
}
匯出部分:
document.getElementById("submit").click = function(){
submitData();
};
function submitData(){
// 將圖片存下來
var dataUrl = app.view.toDataURL("image/jpeg");
// 目前無法把 data URI 直接開在新視窗
// window.open(dataUrl);
// 需用 iframe 的方式
var iframe = "<iframe width='100%' height='100%' src='" + dataUrl + "' style='margin:0; border:0;'></iframe>"
var openWindow = window.open();
openWindow.document.open();
openWindow.document.write('<html><head><title>Test</title><style>html, body{margin:0;}</style></head><body>');
openWindow.document.write(iframe);
openWindow.document.write('</body></html>');
openWindow.document.close();
}
開啟的視窗是單純的 data URI
,圖片上也包含了圖片建立的時間
後端接值時會單純很多
Step1. 可以選擇要放的圖:
回到 Step1,將測試圖片放進場景裡
var bunny = PIXI.Sprite.fromImage('http://pixijs.io/examples/required/assets/basics/bunny.png')
bunny.anchor.set(0.5);
bunny.scale.set(3);
app.stage.addChild(bunny);
Step2. 選到的圖可以拖動、縮放、旋轉:
先處理拖動:
// 設定圖片可互動
bunny.interactive = true;
// 設定圖片在滑鼠滑過時是手勢的形狀
bunny.buttonMode = true;
bunny
.on('pointerdown', onDragStart)
.on('pointerup', onDragEnd)
.on('pointerupoutside', onDragEnd)
.on('pointermove', onDragMove);
function onDragStart(event) { … };
function onDragEnd(event) { … };
function onDragMove(event) { … };
拖曳部分直接參考官網 DEMOS - Dragging 即可
再處理縮放與旋轉:
這裡使用 dat.GUI
var gui = new dat.GUI();
var bunnyScale = 3;
var bunnyRotate = 0;
var effectController = {
bunnyScale: bunnyScale,
bunnyRotate: bunnyRotate
};
gui.add( effectController, "bunnyScale", 0.1, 6, 0.1 ).onChange( guiChange );
gui.add( effectController, "bunnyRotate", -180, 180, 5 ).onChange( guiChange );
function guiChange(){
bunny.scale.x = effectController.bunnyScale;
bunny.scale.y = effectController.bunnyScale;
bunny.rotation = effectController.bunnyRotate* (Math.PI / 180);
}
結合了拖曳、旋轉與縮放,紙娃娃系統幾乎完成了
變形與互動都由 PixiJS 完成,不用計算邊界、不用計算角度
省了很多工
Step3. 匯出與測試
如前文 .toDataURL
的部分
Step4. 使用者選擇圖片:
在 PixiJS裡,將使用者選擇的圖片放進場景也很方便
var sprite = PIXI.Sprite.from(source);
Sprite 類別原始碼:
446. static from(source)
447. {
448. return new Sprite(Texture.from(source));
449. }
而 Texture.from 的方法,在前文讀入材質有提到:
PIXI.Texture.from (source):PIXI.Texturesource
number | string | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | PIXI.BaseTexture
然後就完成了
為了方便說明,範例少提到一些部分:
拖曳時的中心點:
在 Dragging 範例裡,拖動時是將圖片的中心點直接設定在滑鼠中心
假設拖曳時抓的是圖片的角落,圖片會跳一下
需要將座標移回去
匯出時的BUG:
本文裡的程式碼是:
app.view.toDataURL("image/jpeg");
在 iPhone Safari 可能會遇到問題,如前文
範例解說跟第一張圖不太一樣:
介面部分沒有多說,主要提的是 PixiJS 實作上的功能
使用 dat.GUI 測試
本文用到的一些方法,如有不太清楚的話可以參考先前的文章: