vue
getCurrentInstance
getCurrentInstance 是 Vue 3 中的一个函数,用于获取当前组件实例。它可以在组件内部的任何地方使用。 在 Vue 3 中,由于 Composition API 的引入,我们可以在组件中使用函数式的方式编写代码。 getCurrentInstance 函数可以获取到当前组件实例的引用,从而可以访问组件实例的属性、方法和生命周期钩子
import { getCurrentInstance } from 'vue';
export default {
mounted() {
const instance = getCurrentInstance();
console.log(instance.props); // 访问组件的 props
console.log(instance.emit); // 访问组件的自定义事件方法
},
};
通过vite实现按需加载 依赖包
// "agora-rtc-sdk-ng": "^4.18.2", 这个依赖包
// 1 安装plugin-legacy插件,兼容低版浏览器
npm install --save-dev @vite/plugin-legacy
// 2 在vite.config.js中配置
import { defineConfig } from 'vite';
import legacy from '@vite/plugin-legacy';
export default defineConfig({
plugins: [
legacy({
targets: ['ie >= 11'],
additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
}),
],
});
// 3 代码中使用动态导入(dynamic import)来按需加载 Agora RTC SDK NG:
async function loadAgoraSDK() {
const AgoraRTC = await import('agora-rtc-sdk-ng');
// 使用 AgoraRTC
}
loadAgoraSDK();
// 这样,当你的代码执行到 loadAgoraSDK 函数时,Agora RTC SDK NG 将会被动态加载
libpag封装
import { useLibpag } from '../stores';
import { toRaw } from 'vue';
export class LibPag {
buffer;
pagFile;
canvas;
pagView;
audioEl;
id = Symbol(); // 消息队列的唯一标识
constructor(pagUrl, dom, repeat = 1) {
this.pagUrl = pagUrl;
this.dom = dom;
this.repeat = repeat;
}
async init(PAG) {
this.buffer = await fetch(this.pagUrl).then((response) => response.arrayBuffer());
this.pagFile = await PAG.PAGFile.load(this.buffer);
const { height, width } = this.dom?.getBoundingClientRect();
this.dom.innerHTML ='';
// const childNodes = this.dom.childNodes;
// let i = childNodes.length;
// while (i--) {
// this.dom.removeChild(childNodes[i]);
// }
this.canvas = document.createElement('canvas');
this.canvas.width = width;
this.canvas.height = height;
// this.canvas.width = this.pagFile.width();
this.dom.appendChild(this.canvas);
}
async mount(PAG, firstFrame = true, useScale = true) {
// Create PAGView.
this.pagView = await PAG.PAGView.init(this.pagFile, this.canvas, { firstFrame, useScale });
this.pagView.setRepeatCount(this.repeat);
this.pagView.addListener('onAnimationEnd', (view) => {
this.destroy();
clearSingle(this.dom, this.id);
});
return this.dom;
}
audioPlay(){ // 如果涉及audio
const audioBytes = this.pagFile.audioBytes();
if (audioBytes?.byteLength > 0) {
this.audioEl = document.createElement('audio');
this.audioEl.preload = 'auto';
const blob = new Blob([audioBytes], { type: 'audio/mp3' });
this.audioEl.src = URL.createObjectURL(blob);
this.pagView.addListener('onAnimationStart', (event) => {
this.audioEl.play();
});
this.pagView.addListener('onAnimationEnd', (event) => {
this.audioEl.pause();
});
this.pagView.addListener('onAnimationCancel', (event) => {
this.audioEl.pause();
});
this.pagView.addListener('onAnimationRepeat', (event) => {
this.audioEl.currentTime = 0;
});
}
}
// 播放
async play() {
this.audioPlay();
try {
await this.pagView?.play();
} catch (error) {
this.destroy()
}
}
// 暂停
pause() {
this.pagView?.pause();
}
// 停止
stop() {
this.pagView?.stop();
}
// 回收无用的 PAGView 实例和移除 Canvas 的引用
destroy() {
// 释放音频URL
this.audioEl?.pause();
URL.revokeObjectURL(this.audioEl?.src);
this.pagView?.destroy();
this.dom.removeChild(this.canvas);
}
// 设置动画次数
setRepeat(n) {
this.repeat = n;
}
// 设置进度
setPropress(propress) {
// 值是0-1
this.pagView.setProgress(propress);
}
// 获取时长
getDuration() {
return this.pagFile.duration();
}
// 获取可编辑图片数量
getEditNums() {
return this.pagFile.numImages();
}
// 替换image
async replaceImage(PAG, img, index = 0) {
const image = await this.loadImage(img); // ./cat.png
if (!image) return;
const pagImage = PAG.PAGImage.fromSource(image);
this.pagFile.replaceImage(index, pagImage); // 替换索引为index的图片 默认为0
}
// 替换文字
repalceText(text, index = 0) {
const textDoc = this.pagFile.getTextData(index);
textDoc.text = text;
this.pagFile.replaceText(index, textDoc);
}
// 替换文字以及样式 ,传入一个方法
replaceStyle(fn, ...args) {
fn?.apply(that, args);
}
// 加载图片
loadImage(src) {
return new Promise((resolve) => {
const image = new Image();
image.onload = () => {
resolve(image);
};
image.onerror = () => {
resolve(false);
};
image.crossOrigin = 'anonymous';
image.src = src;
});
}
}
// 清除当前dom元素上的一个动画
export const clearSingle = (dom,id)=>{
// 注销后,将对应的pag在消息队列中删除
const pagStore = useLibpag();
pagStore.clearSingle(dom, id);
}
// 清除当前dom元素上的所有动画
export const clearDomNode =(dom) =>{
const pagStore = useLibpag();
const pags = pagStore.getPag(dom);
if (pags?.length) {
pagStore.clearDomNode(dom);
for(let ele of pags){
console.log(ele, 11)
toRaw(ele).destroy();
}
}
}
// 清除当前所有动效
export const clearAll = () =>{
const pagStore = useLibpag();
pagStore.clearAll();
toRaw(pagStore.pagMap).forEach((item) => {
if (item?.length) {
for(let ele of item){
toRaw(ele).destroy();
}
}
});
}
import { defineStore } from 'pinia'
export default defineStore('useLibpag', {
state: () => ({ pagMap: new Map([]), }),
getters: {
},
actions: {
getPag(key) {
return this.pagMap.get(key);
},
incrementPag(key, value){
if(this.pagMap.has(key)){
this.pagMap.set(key, [value,...this.pagMap.get(key)])
}else{
this.pagMap.set(key,[value])
}
},
clearSingle(key, id){
if(this.pagMap.has(key)){
const idMaps = this.pagMap.get(key);
const index = idMaps.findIndex(item=>item.id===id)
if(index!=-1){
idMaps.splice(index, 1);
}
idMaps == []?this.pagMap.delete(key) : this.pagMap.set(key, idMaps);
}
},
clearDomNode(key){
if(this.pagMap.has(key)){
this.pagMap.delete(key);
}
},
clearAll(){
this.pagMap.clear();
}
},
})
<script setup>
import { ref, onMounted, toRaw } from 'vue'
import { PAGInit, types } from 'libpag';
import { useLibpag } from '../stores'
import { LibPag, clearDomNode, clearAll, clearSingle } from '../utils/pag'
let PAG;
const count = ref(0);
const myRef = ref(null);
const myRef2 = ref(null);
const arr = [ './sd.pag','./music.pag' ,'./snowman.pag', './like.pag', './text.pag', './city.pag', './jp.pag', './1.pag', './2.pag', './3.pag']
const pagStore = useLibpag();
let timer =null;
onMounted(async ()=>{
PAG = await PAGInit();
const pagUrl2 = './1.pag';
const imgSrc = './cat.png';
//add()
timerEvent()
// const pagObj1 = new LibPag(pagUrl2, myRef2.value, 0);
// await pagObj1.init(PAG);
// const dom = await pagObj1.mount(PAG);
// pagStore.incrementPag(dom, pagObj1);
// await pagObj1.play();
// console.log(pagStore.pagMap)
// const pagObj2 = new LibPag(pagUrl2, myRef2.value, 0);
// await pagObj2.init(PAG)
// await pagObj2.replaceImage(PAG, imgSrc, 1)
// await pagObj2.mount(PAG);
// pagStore.incrementPag(myRef2.value, pagObj2); // 保存图片实例
// await pagObj2.play();
// for(let i=0;i<arr.length;i++){
// const pagUrl = arr[i];
// const pagObj1 = new LibPag(pagUrl, myRef2.value, 1);
// await pagObj1.init(PAG);
// await pagObj1.mount(PAG);
// await pagObj1.play();
// }
})
function timerEvent(){
console.log(123)
timer = setInterval(() => {
add()
}, 5000);
}
document.addEventListener("visibilitychange", () => {
if (document.hidden) {
console.log('页面被挂起')
clearInterval(timer);
}else{
console.log('页面呼出')
timerEvent();
}
})
async function add(){
// 清除之前的动效
// const pags = pagStore.getPag(myRef.value);
// console.log(1, pags)
// if(pags?.length){
// console.log(pags)
// toRaw(pags).forEach(element => {
// element.destroy();
// });
// }
clearDomNode(myRef.value)
// 添加新的动效
console.log(arr.length, count.value)
const pag = new LibPag(arr[count.value], myRef.value,0);
await pag.init(PAG);
await pag.mount(PAG);
pagStore.incrementPag(myRef.value, pag);
await pag.play();
console.log(pagStore.pagMap)
count.value< arr.length - 1? count.value++ : (count.value=0);
}
function deletec(){
clearDomNode(myRef.value)
}
function deleteAll(){
clearAll();
}
</script>
<template>
<div class="mydom2" ref="myRef"></div>
<div class="mydom" ref="myRef2"></div>
<!-- <div class="mydom2" ref="myRef2"></div> -->
<button @click="add"> 添加新动效</button>
<button @click="deletec"> 删除动效</button>
<button @click="deleteAll"> 删除所有动效</button>
</template>
<style>
.mydom{
width: 100%;
height: 300px;
}
.mydom2{
position: fixed;
z-index: 22;
left: 0;
top: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
</style>