javascript
<template>
<view class="content">
<!-- #ifdef MP-WEIXIN -->
<canvas type="webgl" @touchstart="touchEvent" @touchmove="touchEvent" @touchend="touchEvent" @touchcancel="touchEvent" id="croplandCanvas" class="cropland_canvas"></canvas>
<!-- #endif -->
<!-- #ifdef H5 -->
<div ref="game"></div>
<!-- #endif -->
<div @click="reset">重置转盘数据</div>
</view>
</template>
<script>
//#ifdef MP-WEIXIN
import {
createPIXI
} from "@/libs/pixi.miniprogram";
const unsafeEval = require("@/libs/unsafeEval");
const installSpine = require("@/libs/pixi-spine");
const installAnimate = require("@/libs/pixi-animate");
//#endif
//#ifdef H5
import * as PIXI from 'pixi.js'
//#endif
import {detailRes,getP} from './data';
let detailData=JSON.parse(detailRes.content);//游戏活动
let zpbg='https://*****/test/material/20231206/TZBz2gpN.png';//大转盘背景图片
let lipin='https://***/test/material/20231206/KuHdLruy.png';//礼品图片
let btn='https://****/test/material/20231206/1tuBp4zX.png';//按钮图片
let imgbg='https://***/test/material/20231206/n3bf2zW4.jpg';//背景图片
let successPri=JSON.parse(getP.content);//获奖信息
//#ifdef MP-WEIXIN
var PIXI={};
// let selfThis;
let canvasObj;
let animationFrame;
//#endif
var app ={}
var info = wx.getSystemInfoSync();
var sw = info.screenWidth;//获取屏幕宽高
var sh = info.windowHeight;//获取屏幕宽高
var ratio=info.devicePixelRatio;
var devicePixelRatio=sw/375;
let zIndex=20;
console.log(devicePixelRatio,"===devicePixelRatio")
//#ifdef H5
app = new PIXI.Application({
backgroundAlpha: 0 ,
antialias: true,
autoDensity:true,
width:sw,
height:sh,
resolution:info.devicePixelRatio,
});
//#endif
/* 创建container */
let containerObj={
container:{} ,
container2:{} ,
container3:{} ,
container4:{} ,
}
function createContainerCom(
con,
x=app.screen.width / 2,
y=app.screen.height / 2
){
containerObj[con] = new PIXI.Container();
containerObj[con].x = x;
containerObj[con].y = y;
containerObj[con].sortableChildren =true;
//#ifdef H5
app.stage.addChild(containerObj[con]);
//#endif
}
/* 创建背景 */
function createBg(){
// 创建背景精灵
const background = PIXI.Sprite.from(imgbg);
// 将背景精灵添加到舞台上
containerObj['container2'].addChild(background);
// 设置背景图片的宽高
background.width = sw;
background.height = sh;
}
/* 创建转盘 */
function createZp(){
const zpbgAprite = PIXI.Sprite.from(zpbg);
containerObj['container3'].addChild(zpbgAprite);
zpbgAprite.anchor.set(0.5);
zpbgAprite.x = 0;
zpbgAprite.y = 0;
let ratio=(devicePixelRatio/2);
zpbgAprite.scale.x=ratio;
zpbgAprite.scale.y=ratio;
zpbgAprite.zIndex=zIndex;
}
/* 转盘转动数据 */
let acceleration = 0.01; // 加速度
let speed=0.1;//初始速度
let playStart=false;//转盘是否转动
let angleSuccess=0;//转动角度
/* 重置转盘数据 */
function reset(){
acceleration = 0.01; // 加速度
speed=0.1;
playStart=false;
angleSuccess=0;
containerObj.container.angle =0;
}
/* 放置按钮图片 */
function createBtn(){
const btnAprite = PIXI.Sprite.from(btn);
btnAprite.interactive = true; // 启用交互
btnAprite.eventMode = 'static';
btnAprite.anchor.set(0.5);
containerObj['container4'].addChild(btnAprite);
btnAprite.x =0;// sw / 2;
btnAprite.y = 0;//sh / 2 -8*1/devicePixelRatio;
console.log(btnAprite,"====btnAprite")
let scale=(devicePixelRatio/2);
btnAprite.scale.x=scale;
btnAprite.scale.y=scale;
btnAprite.zIndex=5000;
btnAprite.on('tap',function(event){//手机端用tap,pc用click
console.log("按钮点击事件")
if(playStart){
return;
}
event.stopPropagation(); // 阻止事件继续冒泡
let findIndex=detailData.prizes.findIndex((item)=>item.id==successPri.prizeId);
let angle=(Math.PI * 2)/detailData.prizes.length;
//转6圈
angleSuccess=360*6-(findIndex*angle*180/Math.PI+90+angle*90/Math.PI);
console.log(app,"====appp")
// #ifdef H5
app.ticker.add(animate2);
//#endif
//#ifdef MP-WEIXIN
function test(){
animate2();
animationFrame=canvasObj.requestAnimationFrame(test);
app.render(containerObj.container2);
}
test()
//#endif
})
}
/* 转动 */
let mxSpeed=0;
function animate2() {
// 可选:当速度达到一定阈值时,减小加速度,实现变速效果
if (containerObj.container.angle>(angleSuccess/2)) {
mxSpeed=speed>mxSpeed?speed:mxSpeed;
acceleration = -0.015;
if(speed<mxSpeed/1.5){
acceleration=-0.007
}
}
if (speed <= 0.01&&acceleration<0) {
acceleration = 0;
speed=0.01
}
speed=speed+acceleration;
if((containerObj.container.angle+speed)>angleSuccess){
playStart=false;
//#ifdef MP-WEIXIN
animationFrame && canvasObj.cancelAnimationFrame(animationFrame);
//#endif
//#ifdef H5
app.ticker.remove(animate2);
//#endif
return;
}
containerObj.container.angle += speed;
}
/* 创建奖项 */
let startAngle=0,endAngle=0;
function createPrizes(){
let prizes=detailData.prizes;
let angle=(Math.PI * 2)/prizes.length;//弧度
prizes.map((item,index)=>{
if(index<10){
let name=item.name;
let pic=item.pic;
let id=item.id;
startAngle = endAngle;
endAngle = startAngle + angle;
//扇形背景
let ctx = new PIXI.Graphics();
let color=(index%2===0)?'0xFFF4D6':'0xFFFFFF';
ctx.beginFill(color);
console.log(280*(devicePixelRatio/2))
ctx.arc(0, 0, 280*(devicePixelRatio/2), startAngle, endAngle);
ctx.lineTo(0, 0);
ctx.endFill();
containerObj.container.addChild(ctx);
ctx.zIndex=20+index;
//文字
const text = new PIXI.Text(name, {
fontFamily: 'Arial',
fontSize: 14,
fill:0xE5302F,
autoDensity:true,
antialias:true
});
text.anchor.set(0.5);
text.angle=(180*((angle/2)+startAngle))/ Math.PI+90;//文字旋转角度
containerObj.container.addChild(text);
text.zIndex=2*zIndex+index;//文字层级
//文字位置
let centerX = (200*(devicePixelRatio/2)) * Math.cos(((endAngle-startAngle)/2)+startAngle);
let centerY = (200*(devicePixelRatio/2)) * Math.sin( ((endAngle-startAngle)/2)+startAngle);
text.x=centerX;
text.y=centerY;
//礼物图片
const liwuAprite = PIXI.Sprite.from(lipin);
containerObj.container.addChild(liwuAprite);
liwuAprite.anchor.set(0.5);
liwuAprite.angle=(180*((angle/2)+startAngle))/ Math.PI+90
let liwuX = (240*(devicePixelRatio/2)) * Math.cos((angle/2)+startAngle);
let liwuY = (240*(devicePixelRatio/2)) * Math.sin( (angle/2)+startAngle);
liwuAprite.x = liwuX;
liwuAprite.y = liwuY;
liwuAprite.scale.x=devicePixelRatio/2.5;
liwuAprite.scale.y=devicePixelRatio/2.5;
liwuAprite.zIndex=3*zIndex+index;
}
})
}
export default {
methods:{
//#ifdef MP-WEIXIN
initMp(){
// 获取 canvas
wx.createSelectorQuery().select('#croplandCanvas').fields({
node: true,
size: true
}).exec((res) => {
const canvas = res[0].node;
canvasObj=canvas;
// canvasInstance = canvas;
// 设置canvas实际宽高
canvas.width = sw/ratio;
canvas.height = sh/ratio;
// PIXI 初始化 -----start
PIXI = createPIXI(canvas, sw)
unsafeEval(PIXI); //适配PIXI里面使用的eval函数
installSpine(PIXI); //注入Spine库
installAnimate(PIXI); //注入Animate库
// 通过view把小程序的canvas传入
app = PIXI.autoDetectRenderer({
width: sw,
height: sh,
'view': canvas,
antialias: true,
autoDensity:true,
resolution:ratio,
backgroundAlpha:0
});
createContainerCom('container2',0,0);
createContainerCom('container3')
createContainerCom('container',sw / 2,sh / 2 -8*1/devicePixelRatio)
createContainerCom('container4')
createBg();
createZp();
createPrizes();
createBtn();
containerObj.container2.addChild(containerObj.container3);
containerObj.container2.addChild(containerObj.container);
containerObj.container2.addChild(containerObj.container4);
function animate() {
canvas.requestAnimationFrame(animate);
app.render(containerObj.container2);
}
animate();
})
},
//#endif
//#ifdef H5
initH5(){
this.$nextTick(()=>{
//开始
this.$refs.game.appendChild(app.view);
createContainerCom('container2',0,0)
createContainerCom('container3')
createContainerCom('container',sw / 2,sh / 2 -8*1/devicePixelRatio)
createContainerCom('container4')
createBg();
createZp();
createPrizes();
createBtn();
})
},
//#endif
//#ifdef MP-WEIXIN
// 小程序事件绑定至pixi
touchEvent(e) {
PIXI.dispatchEvent(e)
},
//#endif
/* 重置转盘数据 */
reset(){
acceleration = 0.01; // 加速度
speed=0.1;
playStart=false;
angleSuccess=0;
containerObj.container.angle =0;
}
},
mounted(){
//#ifdef MP-WEIXIN
this.initMp();
//#endif
//#ifdef H5
this.initH5();
//#endif
// selfThis=this;
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin: 200rpx auto 50rpx auto;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
#croplandCanvas{width:100vw;height:100vh;background:#fff;}
/*#canvs2d{position:absolute;left:-10000px;top:-10000px;width:16px;height:16px;} */
</style>
javascript
import {
createPIXI
} from "@/libs/pixi.miniprogram";
const unsafeEval = require("@/libs/unsafeEval");
const installSpine = require("@/libs/pixi-spine");
const installAnimate = require("@/libs/pixi-animate");
上边的文件是使用的pixi-miniprogram
代码中的data.js为mock数据如下
javascript
export let detailRes={"code":"200","content":"{\"backGroundImg\":\"/pic/20231121/170054609830040B1RH7N_1700546098300_associationbg.jpg\",\"backGroundMusic\":\"/pic/20210202/16122355616909ZTQMPFK_1612235561690_抽奖背景音乐.mp3\",\"days\":null,\"description\":\"游戏说明\",\"endDate\":\"2024-01-04 23:59:59\",\"freeMaxCount\":100,\"isFree\":1,\"isJoinNum\":1,\"isQrCodePic\":1,\"isScore\":1,\"isShare\":1,\"isTimeFrame\":0,\"isTimeLimitType\":0,\"joinNum\":21,\"lotteryMusic\":\"/pic/20210310/1615346550064W01KTU1L_1615346550064_转盘转动音效.mp3\",\"name\":\"llj查看大转盘4\",\"prizes\":[{\"awardId\":null,\"awardName\":null,\"awardType\":2,\"couponNum\":10,\"id\":\"1000154524\",\"level\":1,\"name\":\"1111\",\"num\":0,\"pic\":\"/pic/20231121/1700545276964S3B0C8MG_1700545276964_associationtitle.png\",\"scoreValue\":4.00},{\"awardId\":null,\"awardName\":null,\"awardType\":2,\"couponNum\":1,\"id\":\"1000154530\",\"level\":2,\"name\":\"2222\",\"num\":0,\"pic\":\"/pic/20210220/1613801467673IW4LJEFH_1613801467673_defaultAwards.png\",\"scoreValue\":4.00},{\"awardId\":\"1000132326\",\"awardName\":\"赠品券\",\"awardType\":2,\"couponNum\":1,\"id\":\"1000154531\",\"level\":3,\"name\":\"3333\",\"num\":0,\"pic\":\"/pic/20210220/1613801467673IW4LJEFH_1613801467673_defaultAwards.png\",\"scoreValue\":4.00},{\"awardId\":null,\"awardName\":null,\"awardType\":2,\"couponNum\":1,\"id\":\"1000154532\",\"level\":4,\"name\":\"4444\",\"num\":0,\"pic\":\"/pic/20210220/1613801467673IW4LJEFH_1613801467673_defaultAwards.png\",\"scoreValue\":3.00},{\"awardId\":\"1000132398\",\"awardName\":\"凉拌茄子商品\",\"awardType\":2,\"couponNum\":1,\"id\":\"1000154538\",\"level\":5,\"name\":\"5555\",\"num\":0,\"pic\":\"/pic/20210220/1613801467673IW4LJEFH_1613801467673_defaultAwards.png\",\"scoreValue\":1.00},{\"awardId\":\"1000132334\",\"awardName\":\"童商品\",\"awardType\":2,\"couponNum\":1,\"id\":\"1000154539\",\"level\":6,\"name\":\"6666\",\"num\":0,\"pic\":\"/pic/20210220/1613801467673IW4LJEFH_1613801467673_defaultAwards.png\",\"scoreValue\":5.00},{\"awardId\":null,\"awardName\":null,\"awardType\":null,\"couponNum\":null,\"id\":\"100000\",\"level\":null,\"name\":\"谢谢参与\",\"num\":0,\"pic\":null,\"scoreValue\":null},{\"awardId\":null,\"awardName\":null,\"awardType\":2,\"couponNum\":1,\"id\":\"1000154532\",\"level\":4,\"name\":\"4444\",\"num\":0,\"pic\":\"/pic/20210220/1613801467673IW4LJEFH_1613801467673_defaultAwards.png\",\"scoreValue\":3.00},{\"awardId\":\"1000132398\",\"awardName\":\"凉拌茄子商品\",\"awardType\":2,\"couponNum\":1,\"id\":\"1000154538\",\"level\":5,\"name\":\"5555\",\"num\":0,\"pic\":\"/pic/20210220/1613801467673IW4LJEFH_1613801467673_defaultAwards.png\",\"scoreValue\":1.00},{\"awardId\":\"1000132334\",\"awardName\":\"童商品\",\"awardType\":2,\"couponNum\":1,\"id\":\"1000154539\",\"level\":6,\"name\":\"6666\",\"num\":0,\"pic\":\"pic/20210220/1613801467673IW4LJEFH_1613801467673_defaultAwards.png\",\"scoreValue\":5.00}],\"qrCodePic\":\"/pic/20231121/1700545199936Q3AC6SQA_1700545199936_eqDiamondS.png\",\"scoreDeduction\":\"1\",\"scoreMaxCount\":10,\"sharePic\":\"/pic/20210305/1614934733055AQC0IF4B_1614934733055_分享图标.jpg\",\"shareTitle\":\"参与活动赢大奖\",\"startDate\":\"2023-12-04 00:00:00\",\"times\":null,\"weeks\":null}","msg":"success"};
export let getP={"code":"200","content":"{\"couponMemberCountId\":null,\"couponNum\":null,\"couponType\":null,\"freeTimes\":98,\"haveScore\":4.00,\"merchantFlg\":null,\"payTimes\":10,\"prizeAwardId\":null,\"prizeId\":\"1000154530\",\"prizeName\":\"2222\",\"prizeType\":2,\"prizesAwardDes\":\"与他人有人提议他弱由他弱\",\"prizesAwardDesFlg\":1,\"prizesAwardName\":null,\"score\":15.00}","msg":"success"};