当前位置: 首页 > 工具软件 > Pixi.js > 使用案例 >

PIXI.JS一镜到底动画

姜明贤
2023-12-01

一、创建程序

创建一个程序,并把程序添加到DOM结构中

const app = new PIXI.Application({
  width: 750,
  height: 1448
});

doucument.body.appendChild(app.view)

二、加载器

用于预加载项目中所需要的所有资源,是一个提供了用于异步加载图像和音频文件等资源的工具。

//加载器
const loader = new PIXI.Loader()
//加载资源
loader.add('资源1').add("资源2").load(setup)

//load属性是资源加载完成后需要调用的函数

//onProgress => 监控加载资源的进度,一般用于首页加载的进度条
loader.onProgress.add((loader,resource) => {
   //接收两个参数:
  //资源加载的进度
   console.log(loader.progress.toFixed(0) + '%');
})

三、精灵

3.1 创建精灵组

可以理解为图层

//容器(精灵组)
const spriteGroupBg = new PIXI.Container();  
//容器的位置
spriteGroupBg.position.set(0, 0);  
//为容器添加别名,方便后续控制元素使用
spriteGroupBg.name = 'spriteGroupBg'
 //将精灵组加到舞台中,这样我们才能看到
app.stage.addChild(spriteGroupBg);


//创建精灵组
let spriteGroupSences = new PIXI.Container();
//将精灵组加到舞台中
app.stage.addChild(spriteGroupSences);
//spriteGroupSences精灵组下的四个小精灵组,用于加载每个场景的精灵图


//四个场景
let sence1 = new PIXI.Container();
sence1.position.set(1784, 621); //每个场景的位置
//设置锚点的位置
sence1.pivot.set(1784, 621);
sence1.name = 'sence1' //别名
let sence2 = new PIXI.Container();
sence2.position.set(1773, 0);
sence2.name = 'sence2'
//场景二默认隐藏
sence2.alpha = 0; //透明度
let sence3 = new PIXI.Container();
sence3.position.set(4960, 0);
sence3.name = 'sence3'
let sence4 = new PIXI.Container();
sence4.position.set(7902, 0);
sence4.name = 'sence4'

//将所有小精灵组加入到大精灵组中
spriteGroupSences.addChild(sence1);
spriteGroupSences.addChild(sence2);
spriteGroupSences.addChild(sence3);
spriteGroupSences.addChild(sence4);

3.2 创建精灵组加载精灵图

把每一张图片资源创建成精灵图,并插入到每个精灵组中

/**
   * @param img  需要设置为精灵图的图片
   * @param x    精灵图x轴起点位置
   * @param y    精灵图y轴起点位置
   * @param alpah 透明度
   * @param sprName 精灵图别名
   * @param sprGroup 精灵组(可以理解为把精灵加入到哪个地方中)
   */
function addSprToGroup(img, x, y, alpah, sprName, sprGroup) {
  let spr = new PIXI.Sprite.from(img); //创建精灵图
  spr.position.set(x, y);  //精灵图位置
  spr.alpha = alpah;   //透明度
  spr.name = sprName;  //别名
  let sprArr = sprGroup.split('/');
  let sprites = app.stage.getChildByName(sprArr[0]);
  let sprArrNum = sprArr.length
  //判断场景是否很多层级
  if (sprArrNum > 1) {
    for (let i = 1; i < sprArrNum; i++) {
      let midName = sprArr[i];
      sprites = sprites.getChildByName(midName);
    }
  }
  sprites.addChild(spr);
}

四、触摸事件

整体的动画是根据触摸屏幕进行的

4.1 安装phy-touch库

npm install phy-touch

4.2 基本使用

  
//先确定场景总体的长度大小,例
let maxLong = -(10800 - 750);

const touchAction () => {
  new PhyTouch({
    touch: "body", //触摸的对象
    vertical: true,
    maxSpeed: 0.8, //最大速度
    max: 0, 
    min: maxLong,
    bindSelf: false,
    value: 0 //初始值
    change(value) {
      if (value <= 0 && value > maxLong) {
        //使用seek监听屏幕的滑动
        let progress = value / maxLong;  //滑动到总长度的百分之多少
        console.log(value, progress);
        //滑动触发动画
        allTimeLine.seek(progress);
        animationPlay(progress);
        //声音
        audioLine(progress);
      }
    }
  })
}

五、动画

5.1 安装gsap动画库

npm install gsap

5.2 基本使用

//1. 先创建一个总的时间轴
//总时间轴
let allTimeLine = gsap.timeline({paused: true})

//2. 把时间轴放到phy-touch的change函数中调用
change(value) {
  if (value <= 0 && value > maxLong) {
    //使用seek监听屏幕的滑动
    let progress = value / maxLong;  //滑动到总长度的百分之多少
    allTimeLine.seek(progress);
  }
}

5.3 控制场景与精灵的动画

//根据别名获取舞台中的子元素
let sences = app.stage.getChildByName('spriteGroupSences');

//这是整个屏幕,duration是百分之百
const sencesTimeLine = gsap.to(sences.position, {x: maxLong, duration: 1});

//将动画加入到总时间轴中
allTimeLine.add(sencesTimeLine, 0); //0 不基于上个动画执行 (一定要加,否则可能没效果)

//例子



//音符飘动
let yinfu = app.stage.getChildByName('spriteGroupSences').
  getChildByName('sence2').getChildByName('p2Yinfu');
let yinfuStartTime = -2450 / maxLong;  //开始执行动画的位置progress
let yunfuDuringTime = -200 / maxLong;  //开始执行动画的位置progress-开始执行动画的位置progress
let yinfuTimeLine1 = gsap.to(yinfu.position, {
  x:3400,
  y: 300,
  delay:yinfuStartTime,
  duration: yunfuDuringTime
});
let yinfuTimeLine2 = gsap.to(yinfu, {
  alpha: 0,
  delay: yinfuStartTime,
  duration: yunfuDuringTime
});
//把动画加入到总时间轴中
allTimeLine.add(yinfuTimeLine1, 0);
allTimeLine.add(yinfuTimeLine2, 0);

六、音频

6.1 安装pixi-sound库

npm install pixi-sound

6.2 基本使用

import {Sound} from "@pixi/sound"

let music = {
  bgMusic: require("@/assets/audios/bg.mp3"),
  starMusic: require("@/assets/audios/ding.mp3"),
  hhMusic: require("@/assets/audios/huanhu.mp3"),
};

const bgMusic = Sound.from(music.bgMusic);
/*
  属性:
    //声音循环
    music.loop = true
  
    //设置音量
    //1是全音量,2是双倍音量,0.5是半音量,等等。
    music.volume = 0.7;
  
    //暂停声音。要恢复暂停的声音,请再次调用`play`
    music.pause();
  
    //从特定时间开始播放(秒)
    music.playFrom(10)
  
    //-1是全左扬声器,0是中间扬声器,1是全右扬声器
    //扬声器
    music.pan = -0.8;
  
    //在3秒内淡出声音
    music.fadeOut(3);
  
    //在2秒内淡入声音
    music.fadeIn(2);
  
    //在1秒钟内将声音淡化到“0.3”的音量
    music.fade(0.3, 1);
*/
//结合动画位置progress触发声音播放
function audioLine(progress) {
  //星星的声音
  const auStarStartTime = -20 / maxLong;
  const auStarEndTime = -40 / maxLong;
  if (progress > auStarStartTime && progress <= auStarEndTime) {
    //播放
    starMusic.play();
  }
  if (progress < auStarStartTime) {
    starMusic.stop();
  }
}
 类似资料: