最近要作一個 3D 卡片的效果,設計圖以下: javascript
PixiJS 使用的版本:PixiJS 4.8.7 - WebGLhtml
第一次嘗試中,我使用了我比較熟悉的 PixiJS ,雖然 PixiJS 是 2D 渲染引擎,可是 pixi-projection 插件提供了 PixiJS 將來版本中 2d 和 3d 投影。java
截止本文發佈, 官方尚未提供 v5 的 api 。git
我在以前的項目中已經使用過 Sprite2d
、Container2d
、setAxisY
、AFFINE.AXIS_X
等 api 實現過 2d 投影效果,效果還不錯,有興趣的能夠 戳這裏查看 。github
因此此次我想用 Camera3d
、Container3d
、Sprite3d
、position3d
、euler
等 3d 投影的 api 實現此次 3D 卡片的效果。web
效果圖以下,在線預覽戳這裏 。若是以爲效果慘不忍睹,就直接跳過下面的代碼部分看總結吧,或者看我第二次嘗試使用 three.js CSS3DRenderer 實現的文章,使用 three.js 實現效果戳這裏 。api
首先創建一個相機(Camera3d),而後經過 Container3d
和 Sprite3d
將 3d 元素加入到相機,再經過 euler
和 position3d
來調整佈局,最後經過改變元素的位置和投影,或者改變相機的位置來實現動畫。如下核心代碼省略了位置和旋轉中心的設置。app
引入組件佈局
import * as PIXI from 'pixi.js';
import 'pixi-projection';
import {TweenMax} from "gsap/TweenMax";
複製代碼
camera3d 初始化post
const camera = new PIXI.projection.Camera3d();
camera.setPlanes(350,-5000,5000); // 參數依次爲 焦距、z 軸最近距離, z 軸最遠距離
app.stage.addChild(camera);
複製代碼
豎直背景初始化
const card_bg_vertical = new PIXI.projection.Sprite3d(PIXI.loader.resources['bg_0.jpg'].texture);
camera.addChild(card_bg_vertical);
複製代碼
地面初始化
this.card_ground = new PIXI.projection.Container3d();
this.card_ground.euler.x = -Math.PI/180*10; // 給地面添加透視
camera.addChild(this.card_ground);
const card_ground_bg:PIXI.projection.Sprite3d = new PIXI.projection.Sprite3d(PIXI.loader.resources['bg_1.jpg'].texture);
this.card_ground.addChild(card_ground_bg);
複製代碼
把場景元素添加到地面
for(let i = 0; i < 10; i++){
const thing = new PIXI.projection.Sprite3d(PIXI.loader.resources['card1_thing_'+i+'.png'].texture);
thing.euler.x = Math.PI/180*10; // 將父元素的透視復原
this.card_ground.addChild(thing);
}
複製代碼
添加動畫,旋轉地面閉合卡片
const cardTween = new TweenMax.to(this.card_ground.euler,2,{x:-Math.PI/180*180});
複製代碼
Camera3d
定義了 3d 場景,咱們要把 3d 元素添加到改相機中, Camera3d
提供了焦距、最近 z 軸、最遠 z 軸以及是否正交投影等參數;Container3d
、Sprite3d
用來定義 3d 元素,使用方法與 Container
、Sprite
相似,部分屬性添加了 z 軸的控制;Container3d
、Sprite3d
的屬性:position3d
、scale3d
、pivot3d
與 position
、scale
、pivot
的區別是添加了 z 軸的控制。其中 api 沒有提供 rotation3d
,能夠使用 euler
來實現 3d 旋轉;查看個人更多文章:github.com/NalvyBoo/bl…