vue3 ➕ pixi ➕pixi-live2d-display模型的展示

4,168 阅读5分钟

前言

  一直想做个看板娘作为博客的吉祥物,但翻遍各个摸鱼平台发现很多案例都是采用HTML页面去做案例教学。要么就是Vue2版本的技术,模型也采用的是cdn去引用,导致很多模型链接已经失效了,导致一功能不能进行测试
  同时很多案例也没有模型的动作配置的方法,很多动作配置讲的都很模糊
  因此就自己去研究了live2d的模型展示方式。故而有了这篇文章

效果图展示

先上效果图

20230620-1047-1.gif

目标效果

  • ✅效果一:成功的展示本地的模型或者线上模型
  • ✅效果二:模型眼睛跟随鼠标位置
  • ✅效果三:模型动作的配置
  • ✅效果四:点击模型不同的部位触发不同的动作

使用技术栈

技术栈官网 or github
vue3.2cn.vuejs.org/
pixi.js ^6.4.2pixijs.com/
pixi-live2d-display^0.4.0github.com/guansss/pix…
Cubism SDK ps:2或4版本根据自己的模型选择www.live2d.com/

代码结构

一、项目文件整体结构
使用的是js版本的vue3,如果要使用ts版本使用方法也是一样的。不过项目插件还得用js的后缀

image.png

二、插件的引入

必须使用6版本的pixi.js。使用7会报错,因为有些方法已经弃用了
这两个是有npm包的可以直接采用npm引入

npm install pixi.js@6.4.2
npm install pixi-live2d-display

剩下的两个依赖因为没有npm包所以只能在项目的index.html文件中导入
同时也要注意将live2dcubismcore.js.map这个文件放在和live2dcubismcore.min.js同级目录下

    <script src="./src/library/live2d.min.js"></script>
    <script src="./src/library/live2dcubismcore.min.js"></script>
三、模型的引入

我这边是直接在app.vue文件上挂载了。不想在app引入的话可以自己封装成一个组件
  1、模板上先创建一个画布

<template>
  <div style="width:100%;height:100%;z-index: -1000;">
    <canvas id="canvas_view"></canvas>
  </div>
</template>

  2、创建一个index.js方法文件,引入pixi.jspixi-live2d-display
并且将PIXI挂载到全局

import * as PIXI from 'pixi.js'
import {
  Live2DModel,
  MotionPreloadStrategy,
  InternalModel,
} from 'pixi-live2d-display';

// 挂载pixi
window.PIXI = PIXI;

export一个init方法,注意方法要加async关键字保证模型读取完整

export async function init() {
    // 引入模型
  const model = await Live2DModel.from('../../src/assets/model2/HK416_805/normal.model3.json', { motionPreload: MotionPreloadStrategy.NONE,  })

// 创建模型对象
  const app = new PIXI.Application({
    // 配置模型舞台
    view: document.getElementById('canvas_view'),
    // 背景是否透明
    transparent: true,
    autoDensity:true,
    autoResize: true,
    antialias: true,
    // 高度
    height: '1080',
    // 宽度
    width:'1900'
  })
}
四、模型的配置和挂载

配置一些模型对象并且挂载到页面中

  // 鼠标跟踪方法
  model.trackedPointers = [{ id: 1, type: 'pointerdown', flags: true }, { id: 2, type: 'mousemove', flags: true }]
  // 添加模型到舞台
  app.stage.addChild(model)
  // 模型的缩放
  model.scale.set(0.1)
  // 模型的位置,x,y相较于窗口左上角
  model.x = 0
  // 添加模型状态管理器
  const a = new InternalModel(model)
  model.InternalModel = a

在app.vue中引入index.js方法
注意一定要在mounted钩子执行,不然拿不到节点,会报错

<script setup>
    import { init } from './components/index'
    import {onMounted} from 'vue'

    onMounted(() => {
      init()
    })
</script>
五、模型拖拽方法与模型区域遮罩方法

拖拽方法可以让模型在画布内可以任意的拖拽模型行位置

  /**
   * 模型拖拽方法
   * @param {Live2DModel} model -模型对象
   */
  function draggable(model) {
    model.buttonMode = true;
    model.on("pointerdown", (e) => {
      model.dragging = true;
      model._pointerX = e.data.global.x - model.x;
      model._pointerY = e.data.global.y - model.y;
    });
    model.on("pointermove", (e) => {
      if (model.dragging) {
        model.position.x = e.data.global.x - model._pointerX;
        model.position.y = e.data.global.y - model._pointerY;
      }
    });
    model.on("pointerupoutside", () => (model.dragging = false));
    model.on("pointerup", () => (model.dragging = false));
  }
  
    // 绑定模型拖拽方法
  draggable(model);

显示模型区域方法可以方便开发的时候看见模型的区域

/**
   * 模型区域范围遮罩
   * @param {Live2DModel} model -模型对象
   */
  function addFrame(model) {
    const foreground = PIXI.Sprite.from(PIXI.Texture.WHITE);
    foreground.width = model.internalModel.width;
    foreground.height = model.internalModel.height;
    foreground.alpha = 0.2;

    model.addChild(foreground);
    foreground.visible = true
  }
  
  //添加模型范围遮罩
  addFrame(model);
六、模型的动作配置

使用model.on(event, backcall() )。event:触发事件,backcall():事件触发回调

// 绑定模型点击事件动作
 model.on('pointerdown', (hitAreas) => {
   // hitAreas:模型的一些上下文
   model.motion("TapHead");
 });

这个案例是当鼠标点击的时候触发模型的动作
model.motion("TapHEad")表示模型执行一个叫TapHEad的动作
这样就可以事件点击触发模型的动作了
(ps:模型本身要有动作文件,在model3.json中查看Motions这个数组下看看有哪些动作组)

常见的事件

event解释
pointerdown当模型被按下时触发的事件
pointerup当用户释放模型时触发的事件
pointermove当用户在模型上移动时触发的事件
pointerenter当鼠标指针进入模型区域时触发的事件
pointerleave当鼠标指针离开模型区域时触发的事件
pointerleave当鼠标指针离开模型区域时触发的事件
pointercancel当触摸事件被取消时触发的事件
pointerout当鼠标指针移出模型区域时触发的事件
七、模型的触发区域查看

一个live2d模型有不同的触发区域,当点击模型的不同触发区域的时候就选择触发不同的事件


这样可以看到模型的所有的触发区域
  // 查看模型触发区域
  var hitAreas = model.internalModel.hitAreas;

使用model.hitTest(x, y)可以获得鼠标点击的那个区域。命中则返回区域名数组,未命中返回为空
x:鼠标X的坐标
y:鼠标Y坐标

所以可以加上之前的绑定动作的方法去根据不同的点击命中区域去执行不同的动作,如下

// 绑定模型点击事件动作
  model.on('pointerdown', (hitAreas) => {
    // hitAreas:模型的一些上下文
    const { x, y } = hitAreas.data.global 
    const point = model.hitTest(x, y)
    if (point.includes(Head)) {
      model.motion("TapHead");
    }
  });

上面这个表示当鼠标点击了头部区域则执行TaoHead的动作
hitAreas:回调方法的参数,里面存储了一些live2d的信息
const { x, y } = hitAreas.data.global 表示从回调参数中解构出鼠标的x,y的坐标

代码地址

代码地址:gitee.com/liu_soon/li…

结语

本文是由我一时兴起写的文章,所以没有讲太详细,再加上 pixi-live2d-display 的文档是英文的(ps:本人英语小辣鸡),所以有些并没有写的很好,有兴趣去文档官网看看。后续专栏会更新live2d模型的其他应用,但是什么时候更新就不知道了