我用 PixiJS 中的 Sprite3d 做了一個失敗的 3D 卡片

NingBo發表於2019-04-16

前言

最近要做一個 3D 卡片的效果,設計圖如下:

我用 PixiJS 中的 Sprite3d 做了一個失敗的 3D 卡片

版本說明

PixiJS 使用的版本:PixiJS 4.8.7 - WebGL

嘗試的原因

第一次嘗試中,我使用了我比較熟悉的 PixiJS ,雖然 PixiJS 是 2D 渲染引擎,但是 pixi-projection 外掛提供了 PixiJS 未來版本中 2d 和 3d 投影。

截止本文釋出, 官方還沒有提供 v5 的 api 。

我在之前的專案中已經使用過 Sprite2dContainer2dsetAxisYAFFINE.AXIS_X 等 api 實現過 2d 投影效果,效果還不錯,有興趣的可以 戳這裡檢視

所以這次我想用 Camera3dContainer3dSprite3dposition3deuler 等 3d 投影的 api 實現這次 3D 卡片的效果。

效果

效果圖如下,線上預覽戳這裡 。如果覺得效果慘不忍睹,就直接跳過下面的程式碼部分看總結吧,或者看我第二次嘗試使用 three.js CSS3DRenderer 實現的文章使用 three.js 實現效果戳這裡

我用 PixiJS 中的 Sprite3d 做了一個失敗的 3D 卡片

實現過程

首先建立一個相機(Camera3d),然後通過 Container3dSprite3d 將 3d 元素加入到相機,再通過 eulerposition3d 來調整佈局,最後通過改變元素的位置和投影,或者改變相機的位置來實現動畫。以下核心程式碼省略了位置和旋轉中心的設定。

核心程式碼

引入元件

import * as PIXI from 'pixi.js';
import 'pixi-projection';
import {TweenMax} from "gsap/TweenMax";
複製程式碼

camera3d 初始化

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});
複製程式碼

總結

關於 api

  • Camera3d 定義了 3d 場景,我們要把 3d 元素新增到改相機中, Camera3d 提供了焦距、最近 z 軸、最遠 z 軸以及是否正交投影等引數;
  • Container3dSprite3d 用來定義 3d 元素,使用方法與 ContainerSprite 類似,部分屬性新增了 z 軸的控制;
  • Container3dSprite3d 的屬性:position3dscale3dpivot3dpositionscalepivot 的區別是新增了 z 軸的控制。其中 api 沒有提供 rotation3d,可以使用 euler 來實現 3d 旋轉;

使用心得

  • 對於熟悉 PixiJS api 的同學,想要上手 2d 和 3d 的投影效果,還是比較簡單的,只是官方沒有提供文件,需要研究官網的例子來檢視每個 api 的作用與效果;
  • 2d 和 3d 的投影效果是在舊版本基礎上的擴充,因此舊版本所具備的優勢,新版本依然可以享受;
  • 畢竟 PixiJS 為 2d 渲染引擎,如果想要做出炫酷的 3d 效果,可能還是得需要使用 three.js 等庫來實現。
  • 第二次嘗試,我使用 three.js 中的 CSS3DRenderer 實現了上面的效果,可以戳這裡檢視,雖然效果出來了,但也是一次失敗的嘗試,後續會寫一篇總結 。

相關文章