微信小程序 MiniProgram
组件 gif-mock
介绍:
通过在canvas中播放序列静态图片,达到跟播放gif动图类似的效果。
缘由:
- gif图限制,gif图无法实现半透明效果的,要么是透明要么不透明,导致一些效果无法实现,例如光影效果
- 微信小程序限制,目前发现能实现背景透明的视频为webm以及mov,但是尝试webm发现,微信小程序的背景是黑色的(在浏览器中为透明)
引用:
{
"usingComponents": {
"gif-mock": "/components/gif-mock/index"
}
}
使用:
<gif-mock src="{{imgUrl}}vip/coupon/{{theme.name}}/s4/#index.png" pic-count="20" bindload="onStartBgLoadEnd"></gif-mock>
下面是相关代码,可以复制保存为指定文件即可
index.wxml
<!--components/gif-mock/index.wxml-->
<canvas id="output" type="2d" style="width:{{width * dpr}}rpx;height:{{height * dpr}}rpx; display: inline-block;"></canvas>
<view hidden="true">
<image src="{{item.remoteSrc}}" wx:for="{{remoteSrcItems}}" wx:for-index="idx" wx:for-item="item" wx:key="idx" bindload="onImageLoadEnd" data-idx='{{item.idx}}' ></image>
</view>
index.js
// components/gif-mock/index.js
Component({
/**
* 组件的属性列表
*/
properties: {
width: { // 属性名
type: Number,
value: 300
},
height: { // 属性名
type: Number,
value: 300
},
interval: {
type: Number,
value: 80
},
src: {
type: String,
value: ''
},
picCount: {
type: Number,
value: 0
}
},
/**
* 组件的初始数据
*/
data: {
remoteSrcItems: []
},
intervalHandler: null,
lifetimes: {
attached() {
var that = this;
var dpr = wx.getSystemInfoSync().pixelRatio;
that.setData({
dpr: dpr
});
this.data.remoteSrcItems.length = 0;
for (var i = 0; i < this.data.picCount; i++) {
var remoteSrc = that.data.src.replace(/#index/g, i + 1);
console.log(remoteSrc)
this.data.remoteSrcItems.push({
idx: i,
remoteSrc: remoteSrc,
loading: true
});
}
that.setData({
remoteSrcItems: this.data.remoteSrcItems
});
},
detached: function () {
// 在组件实例被从页面节点树移除时执行
clearInterval(this.intervalHandler);
}
},
/**
* 组件的方法列表
*/
methods: {
onImageLoadEnd(e) {
console.log(e);
this.data.remoteSrcItems[e.currentTarget.dataset.idx].loading = false;
this.checkLoadEnd();
},
checkLoadEnd() {
for (var i = 0; i < this.data.picCount; i++) {
if (this.data.remoteSrcItems[i].loading) {
return;
}
}
this.triggerEvent("load");
this.play();
},
play() {
var that = this;
if (this.intervalHandler) {
return;
}
wx.createSelectorQuery().in(this).select('#output')
.fields({
node: true,
size: true
})
.exec((res2) => {
// 如果没有指定Id的元素,res2将为null
console.log("abc", res2)
if (!res2 || res2.length <= 0) {
return;
}
var canvas = res2[0].node;
const output = canvas.getContext('2d')
var dpr = that.data.dpr;
console.log('canvas', canvas, dpr)
canvas.width = that.data.width * dpr
canvas.height = that.data.height * dpr
// output.scale(dpr, dpr)
console.log(canvas);
var i = 0;
this.intervalHandler = setInterval(() => {
var remoteSrc = that.data.remoteSrcItems[i].remoteSrc;
// console.log(remoteSrc)
i = i >= (this.data.picCount - 1) ? 0 : i + 1;
let img = canvas.createImage(); //创建img对象
img.onload = () => {
output.clearRect(0, 0, canvas.width, canvas.height)
output.drawImage(img, 0, 0, canvas.width, canvas.height); //drawImage(要绘画的元素, x轴, y轴)
};
img.src = remoteSrc;
}, that.data.interval);
});
}
}
})