视频播放列表更新,增加分享海报生成
This commit is contained in:
@@ -1,283 +0,0 @@
|
||||
<template>
|
||||
<view style="background: #FFFFFF;">
|
||||
<canvas v-if="!tempFilePath" :canvas-id="CanvasID"
|
||||
:style="{ width: canvasW + 'px', height: canvasH + 'px' }"></canvas>
|
||||
<image v-else lazy-load :src="tempFilePath" mode="widthFix" class="is-response"
|
||||
@longpress="toSave(tempFilePath)"></image>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
var _this;
|
||||
export default {
|
||||
name: 'wm-poster',
|
||||
props: {
|
||||
CanvasID: {
|
||||
//CanvasID 等同于 canvas-id
|
||||
Type: String,
|
||||
default: 'PosterCanvas'
|
||||
},
|
||||
imgSrc: {
|
||||
//展示图
|
||||
Type: String,
|
||||
default: ''
|
||||
},
|
||||
QrSrc: {
|
||||
//二维码
|
||||
Type: String,
|
||||
default: ''
|
||||
},
|
||||
Title: {
|
||||
//文本内容
|
||||
Type: String,
|
||||
default: '短剧'
|
||||
},
|
||||
TitleColor: {
|
||||
//标题颜色
|
||||
Type: String,
|
||||
default: '#333333'
|
||||
},
|
||||
LineType: {
|
||||
//标题显示行数 大于两行是否省略 (注超出2行显示会导致画布布局絮乱)
|
||||
Type: [String, Boolean],
|
||||
default: true
|
||||
},
|
||||
PriceTxt: {
|
||||
//价格值
|
||||
Type: String,
|
||||
default: ''
|
||||
},
|
||||
PriceColor: {
|
||||
//价格颜色
|
||||
Type: String,
|
||||
default: '#e31d1a'
|
||||
},
|
||||
OriginalTxt: {
|
||||
//原价值
|
||||
Type: String,
|
||||
default: ''
|
||||
},
|
||||
OriginalColor: {
|
||||
//默认颜色(如原价与扫描二维码颜色)
|
||||
Type: String,
|
||||
default: '#b8b8b8'
|
||||
},
|
||||
Width: {
|
||||
//画布宽度 (高度根据图片比例计算 单位upx)
|
||||
Type: String,
|
||||
default: 750
|
||||
},
|
||||
CanvasBg: {
|
||||
//canvas画布背景色
|
||||
Type: String,
|
||||
default: '#ffffff'
|
||||
},
|
||||
Referrer: {
|
||||
//推荐人信息
|
||||
Type: String,
|
||||
default: '精选好剧'
|
||||
},
|
||||
ViewDetails: {
|
||||
//描述提示文字
|
||||
Type: String,
|
||||
default: '长按或扫描识别二维码观看'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tempFilePath: '',
|
||||
canvasW: 0,
|
||||
canvasH: 0,
|
||||
canvasImgSrc: '',
|
||||
ctx: null
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
toSave(url) {
|
||||
|
||||
//#ifndef H5
|
||||
uni.getImageInfo({
|
||||
src: url,
|
||||
success: function(image) {
|
||||
console.log('图片信息:', JSON.stringify(image));
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: image.path,
|
||||
success: function() {
|
||||
console.log('save success');
|
||||
uni.showToast({
|
||||
title: '海报已保存相册',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
//#endif
|
||||
},
|
||||
async OnCanvas() {
|
||||
uni.showLoading({
|
||||
title: '海报生成中...'
|
||||
})
|
||||
_this.ctx = uni.createCanvasContext(_this.CanvasID, this);
|
||||
const C_W = uni.upx2px(_this.Width), //canvas宽度
|
||||
C_P = uni.upx2px(30), //canvas Paddng 间距
|
||||
C_Q = uni.upx2px(150); //二维码或太阳码宽高
|
||||
let _strlineW = 0; //文本宽度
|
||||
let _imgInfo = await _this.getImageInfo({
|
||||
imgSrc: _this.imgSrc
|
||||
}); //广告图
|
||||
console.log('图片信息0:', JSON.stringify(""));
|
||||
|
||||
let _QrCode = await _this.getImageInfo({
|
||||
imgSrc: _this.QrSrc
|
||||
}); //二维码或太阳码
|
||||
|
||||
console.log('图片信息1:', JSON.stringify(""));
|
||||
|
||||
let r = [_imgInfo.width, _imgInfo.height];
|
||||
let q = [_QrCode.width, _QrCode.height];
|
||||
let imgW = C_W - C_P * 2;
|
||||
if (r[0] != imgW) {
|
||||
r[1] = Math.floor((imgW / r[0]) * r[1]);
|
||||
r[0] = imgW;
|
||||
}
|
||||
if (q[0] != C_Q) {
|
||||
q[1] = Math.floor((C_Q / q[0]) * q[1]);
|
||||
q[0] = C_Q;
|
||||
}
|
||||
_this.canvasW = C_W;
|
||||
_this.canvasH = r[1] + q[1] + 40;
|
||||
_this.ctx.setFillStyle(_this.CanvasBg); //canvas背景颜色
|
||||
_this.ctx.fillRect(0, 0, C_W, _this.canvasH); //canvas画布大小
|
||||
|
||||
//添加图片展示
|
||||
_this.ctx.drawImage(_imgInfo.path, C_P, C_P, r[0], r[1]);
|
||||
//添加图片展示 end
|
||||
|
||||
//设置文本
|
||||
_this.ctx.setFontSize(uni.upx2px(32)); //设置标题字体大小
|
||||
_this.ctx.setFillStyle(_this.TitleColor); //设置标题文本颜色
|
||||
let _strLastIndex = 0; //每次开始截取的字符串的索引
|
||||
let _strHeight = r[1] + C_P * 2 + 10; //绘制字体距离canvas顶部的初始高度
|
||||
let _num = 1;
|
||||
// for (let i = 0; i < _this.Title.length; i++) {
|
||||
// _strlineW += _this.ctx.measureText(_this.Title[i]).width;
|
||||
// if (_strlineW > r[0]) {
|
||||
// if (_num == 2 && _this.LineType) {
|
||||
// //文字换行数量大于二进行省略号处理
|
||||
// _this.ctx.fillText(_this.Title.substring(_strLastIndex, i - 8) + '...', C_P, _strHeight);
|
||||
// _strlineW = 0;
|
||||
// _strLastIndex = i;
|
||||
// _num++;
|
||||
// break;
|
||||
// } else {
|
||||
// _this.ctx.fillText(_this.Title.substring(_strLastIndex, i), C_P, _strHeight);
|
||||
// _strlineW = 0;
|
||||
// _strHeight += 20;
|
||||
// _strLastIndex = i;
|
||||
// _num++;
|
||||
// }
|
||||
// } else if (i == _this.Title.length - 1) {
|
||||
// _this.ctx.fillText(_this.Title.substring(_strLastIndex, i + 1), C_P, _strHeight);
|
||||
// _strlineW = 0;
|
||||
// }
|
||||
// }
|
||||
//设置文本 end
|
||||
//设置价格
|
||||
_strlineW = C_P;
|
||||
_strHeight += uni.upx2px(60);
|
||||
if (_num == 1) {
|
||||
_strHeight += 20; //单行标题时占位符
|
||||
}
|
||||
// if (_this.PriceTxt != '') {
|
||||
// //判断是否有销售价格
|
||||
// _this.ctx.setFillStyle(_this.PriceColor);
|
||||
// _this.ctx.setFontSize(uni.upx2px(38));
|
||||
// // _this.ctx.fillText('券后价 ¥' + _this.PriceTxt, _strlineW, _strHeight); //商品价格
|
||||
// _strlineW += _this.ctx.measureText('券后价 ¥' + _this.PriceTxt).width + uni.upx2px(10);
|
||||
// }
|
||||
// // #ifdef H5
|
||||
// if (_this.PriceTxt != '' && _this.OriginalTxt != '') {
|
||||
// //判断是否有销售价格且原价
|
||||
// _this.ctx.setFillStyle(_this.OriginalColor);
|
||||
// _this.ctx.setFontSize(uni.upx2px(24));
|
||||
// _this.ctx.fillText(_this.OriginalTxt, _strlineW, _strHeight); //商品原价
|
||||
// }
|
||||
// #endif
|
||||
_this.ctx.strokeStyle = _this.OriginalColor;
|
||||
_this.ctx.moveTo(_strlineW, _strHeight - uni.upx2px(10)); //起点
|
||||
_this.ctx.lineTo(_strlineW + _this.ctx.measureText(_this.OriginalTxt).width, _strHeight - uni.upx2px(
|
||||
10)); //终点
|
||||
_this.ctx.stroke();
|
||||
//设置价格 end
|
||||
|
||||
//添加二维码
|
||||
_strHeight += uni.upx2px(20);
|
||||
let toTop = uni.upx2px(20);
|
||||
// _this.ctx.drawImage(_QrCode.path, r[0] - q[0] + C_P, _strHeight, q[0], q[1]);
|
||||
_this.ctx.drawImage(_QrCode.path, r[0] - q[0] + C_P, _this.canvasH - q[1] - toTop, q[0], q[1]);
|
||||
//添加二维码 end
|
||||
|
||||
//添加推荐人与描述
|
||||
_this.ctx.setFillStyle(_this.TitleColor);
|
||||
_this.ctx.setFontSize(uni.upx2px(30));
|
||||
_this.ctx.fillText(_this.Title, C_P, _this.canvasH - q[1] - toTop + q[1] / 2);
|
||||
_this.ctx.setFillStyle(_this.OriginalColor);
|
||||
_this.ctx.setFontSize(uni.upx2px(24));
|
||||
_this.ctx.fillText(_this.ViewDetails, C_P, _this.canvasH - q[1] - toTop + q[1] / 2 + 20);
|
||||
//添加推荐人与描述 end
|
||||
//延迟后渲染至canvas上
|
||||
setTimeout(function() {
|
||||
_this.ctx.draw(true, ret => {
|
||||
_this.getNewImage();
|
||||
});
|
||||
}, 600);
|
||||
},
|
||||
async getImageInfo({
|
||||
imgSrc
|
||||
}) {
|
||||
return new Promise((resolve, errs) => {
|
||||
uni.getImageInfo({
|
||||
src: imgSrc,
|
||||
success: function(image) {
|
||||
resolve(image);
|
||||
},
|
||||
fail(err) {
|
||||
// errs(err);
|
||||
_this.$emit('error', err);
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
getNewImage() {
|
||||
uni.canvasToTempFilePath({
|
||||
canvasId: _this.CanvasID,
|
||||
quality: 1,
|
||||
complete: res => {
|
||||
_this.tempFilePath = res.tempFilePath;
|
||||
_this.$emit('success', res);
|
||||
|
||||
// uni.showToast({
|
||||
// title: '长按图片保存海报',
|
||||
// mask: false,
|
||||
// duration: 2000,
|
||||
// icon: "none"
|
||||
// });
|
||||
|
||||
}
|
||||
},
|
||||
this
|
||||
);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
_this = this;
|
||||
this.OnCanvas();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
204
components/my-poster/my-poster.vue
Normal file
204
components/my-poster/my-poster.vue
Normal file
@@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<view class="qrcode">
|
||||
<up-qrcode :size="qrcodeData.size" :val="qrcodeData.val" @result="qrcodeResult"></up-qrcode>
|
||||
</view>
|
||||
<view class="poster-box" @click="hide">
|
||||
<view class="bg-fff container" @click.stop>
|
||||
<canvas canvas-id="myCanvas" class="myCanvas" id="myCanvas" style="width: 100%;flex: 1;"></canvas>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<up-popup :show="posterData.result?true:false" mode="center" width="700rpx" closeOnClickOverlay @close="reset">
|
||||
<image :src="posterData.result" mode="widthFix"></image>
|
||||
</up-popup>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
getElRect
|
||||
} from '@/utils/util.js'
|
||||
import {
|
||||
ref,
|
||||
onMounted,
|
||||
getCurrentInstance,
|
||||
reactive,
|
||||
computed
|
||||
} from 'vue'
|
||||
let show = ref(false)
|
||||
function reset(){
|
||||
ctx.clearRect(0,0,posterData.width,posterData.height)
|
||||
show.value=false
|
||||
qrcodeData.val=''
|
||||
qrcodeData.result=''
|
||||
posterData.result=''
|
||||
}
|
||||
const qrcodeData = reactive({
|
||||
val: '',
|
||||
result: '',
|
||||
size: 80
|
||||
})
|
||||
|
||||
let posterData = reactive({
|
||||
width: 0,
|
||||
height: 0,
|
||||
result: ''
|
||||
})
|
||||
const ctx = uni.createCanvasContext('myCanvas')
|
||||
|
||||
function qrcodeResult(e) {
|
||||
console.log(e);
|
||||
qrcodeData.result = e
|
||||
console.log(posterData);
|
||||
const gap = 10
|
||||
show.value = true
|
||||
ctx.setFillStyle('#fff')
|
||||
ctx.fillRect(0, 0, posterData.width, posterData.height)
|
||||
uni.downloadFile({
|
||||
url: posterData.bigImg,
|
||||
success(res) {
|
||||
if (res.statusCode == 200) {
|
||||
uni.getImageInfo({
|
||||
src: res.tempFilePath,
|
||||
success(imageInfo) {
|
||||
console.log(imageInfo);
|
||||
const bili = imageInfo.width / imageInfo.height
|
||||
const width = posterData.width - gap * 2
|
||||
console.log(width);
|
||||
console.log(width / bili);
|
||||
ctx.drawImage(res.tempFilePath, gap, gap, width, width / bili, 0, 0)
|
||||
ctx.drawImage(e, posterData.width - qrcodeData.size - gap, posterData.height -
|
||||
gap - qrcodeData.size, qrcodeData.size, qrcodeData.size)
|
||||
ctx.setFillStyle('#000')
|
||||
ctx.setFontSize(14);
|
||||
ctx.fillText(posterData.title, gap, posterData.height - gap - 20)
|
||||
ctx.setFillStyle('#999')
|
||||
ctx.setFontSize(12);
|
||||
ctx.fillText(posterData.tips, gap, posterData.height - gap)
|
||||
ctx.draw()
|
||||
setTimeout(() => {
|
||||
uni.canvasToTempFilePath({
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: posterData.width,
|
||||
height: posterData.height,
|
||||
destWidth: posterData.width,
|
||||
destHeight: posterData.height,
|
||||
canvasId: 'myCanvas',
|
||||
quality: 1,
|
||||
success: function(res) {
|
||||
// 在H5平台下,tempFilePath 为 base64
|
||||
console.log(res.tempFilePath)
|
||||
posterData.result = res.tempFilePath
|
||||
}
|
||||
})
|
||||
}, 600)
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '封面图下载失败'
|
||||
})
|
||||
}
|
||||
console.log(res);
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
show.value = true
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
bigImg: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
function make(data) {
|
||||
uni.showLoading({
|
||||
title: '二维码生成中……'
|
||||
})
|
||||
Object.assign(posterData, data)
|
||||
qrcodeData.val = data.qrcode
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getElRect('myCanvas').then(res => {
|
||||
Object.assign(posterData, res)
|
||||
})
|
||||
})
|
||||
|
||||
function hide() {
|
||||
show.value = false
|
||||
}
|
||||
|
||||
|
||||
let canvasConfig = reactive({
|
||||
width: '',
|
||||
height: ''
|
||||
})
|
||||
|
||||
const canvasStyle = computed(() => {
|
||||
return {
|
||||
width: '',
|
||||
height: ''
|
||||
}
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
make
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.qrcode {
|
||||
position: fixed;
|
||||
top: -9999px;
|
||||
left: -9999px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.u-popup {
|
||||
position: fixed !important;
|
||||
}
|
||||
|
||||
::v-deep .u-popup {
|
||||
position: fixed !important;
|
||||
}
|
||||
|
||||
.poster-box {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 9999;
|
||||
background-color: rgba(0, 0, 0, .5);
|
||||
transform: translateY(-100%);
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: all .3s ease-in-out;
|
||||
padding: 30rpx;
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
&.show {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
<video class="u-flex-1 video" :show-fullscreen-btn="false" @controlstoggle="controlstoggles" v-if="showVideo"
|
||||
@waiting="waiting()" object-fit="cover"
|
||||
@pause="onpause"
|
||||
@play="videoPlay('myVideo'+item.courseDetailsId,item.courseDetailsId)" :play-strategy="2"
|
||||
:show-loading="true" codec="software" :muted="false" :show-center-play-btn="true" :loop="false"
|
||||
:enable-progress-gesture="false" :poster="item.titleImg" :ref="'myVideo'+item.courseDetailsId"
|
||||
@@ -11,7 +12,7 @@
|
||||
<image class="poster" v-else @click="!item.videoUrl?popupShow('pay'):''" :src="item.titleImg" mode="aspectFill">
|
||||
</image>
|
||||
|
||||
<view class="info" v-if="!isCommand">
|
||||
<view class="info" v-if="!isCommand" :style="infoStyle">
|
||||
<text class="color-fff" v-if="item.courseDetailsName">{{item.courseDetailsName}}</text>
|
||||
<view v-if="item.content" v-html="item.content"></view>
|
||||
<view class="u-m-t-20 color-fff" @click="popupShow('show')">
|
||||
@@ -21,7 +22,7 @@
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<view class="info" v-if="isCommand">
|
||||
<view class="info" v-if="isCommand" :style="infoStyle">
|
||||
<text class="color-fff" v-if="item.courseDetailsName">{{item.courseDetailsName}}</text>
|
||||
<view v-if="item.content" v-html="item.content"></view>
|
||||
<view class="u-m-t-20 color-fff" @click="toDetail">
|
||||
@@ -31,7 +32,7 @@
|
||||
</view>
|
||||
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="right" :style="rightStyle">
|
||||
<view class="love u-flex u-flex-xy-center u-flex-col u-m-b-40 u-text-center" @click="dianzanClick">
|
||||
<up-icon name="heart-fill" v-if="item.isGood==1" color="red" size="30"></up-icon>
|
||||
<up-icon name="heart-fill" v-else color="#ffffff" size="30"></up-icon>
|
||||
@@ -69,6 +70,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
rightStyle:{
|
||||
type:Object,
|
||||
default:()=>{
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
infoStyle:{
|
||||
type:Object,
|
||||
default:()=>{
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
isCommand: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
@@ -106,6 +123,10 @@
|
||||
playSpeeds: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
showControls:{
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
})
|
||||
let autoplay = ref(props.item.videoUrl ? true : false)
|
||||
@@ -115,6 +136,7 @@
|
||||
])
|
||||
|
||||
function controlstoggles(e) {
|
||||
console.log(e);
|
||||
emits('controlstoggles', e)
|
||||
}
|
||||
|
||||
@@ -130,7 +152,20 @@
|
||||
}
|
||||
|
||||
function videoPlay() {
|
||||
|
||||
// #ifdef H5
|
||||
emits('controlstoggles', {
|
||||
detail:{show:true}
|
||||
})
|
||||
// #endif
|
||||
|
||||
}
|
||||
|
||||
function onpause(){
|
||||
// #ifdef H5
|
||||
emits('controlstoggles', {
|
||||
detail:{show:false}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
|
||||
function ended() {
|
||||
@@ -211,6 +246,7 @@
|
||||
video = null
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -279,6 +315,7 @@
|
||||
color: #ffffff;
|
||||
font-size: 15px;
|
||||
z-index: 9999;
|
||||
transition: all .3s ease-in-out;
|
||||
}
|
||||
|
||||
.u-flex-y-center {
|
||||
@@ -293,6 +330,7 @@
|
||||
}
|
||||
|
||||
.right {
|
||||
transition: all .3s ease-in-out;
|
||||
position: absolute !important;
|
||||
right: 20rpx;
|
||||
/* #ifdef H5 */
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
<template>
|
||||
<!-- #ifdef H5 -->
|
||||
<view class=" w-full box" style="width: 100vw;">
|
||||
<swiper @longpress="popupShow('speed')"
|
||||
:style="{height:wHeight+'px'}"
|
||||
v-if="videoList.length" @change="swiperChange" :current="current"
|
||||
:circular="true" vertical class="u-flex-1" @transition="transition" :indicator-dots="false"
|
||||
:autoplay="false" :interval="0" :duration="200">
|
||||
<swiper @longpress="popupShow('speed')" :style="{height:wHeight+'px'}" v-if="videoList.length"
|
||||
@change="swiperChange" :current="current" :circular="true" vertical class="u-flex-1"
|
||||
@transition="transition" :indicator-dots="false" :autoplay="false" :interval="0" :duration="200">
|
||||
<swiper-item v-for="(item,index) in videoList" :key="index">
|
||||
<list-item-vue :total="list.length" :item="item"
|
||||
:isCommand="isCommand"
|
||||
:current="current" :isCollect="isCollect"
|
||||
@toDetail="toDetail(item,index)"
|
||||
@controlstoggles="controlstoggles" :playSpeeds="playSpeeds" :index="index" :nowIndex="nowIndex"
|
||||
@dianzanClick="dianzanClick(item,index)" @share="share(item)" @zhuijuClick="zhuijuClick(item)"
|
||||
@popupShow="popupShow"></list-item-vue>
|
||||
<list-item-vue :total="list.length" :item="item" :isCommand="isCommand"
|
||||
:rightStyle="rightStyle" :infoStyle="infoStyle"
|
||||
:showControls="control.showControls" :current="current" :isCollect="isCollect"
|
||||
@toDetail="toDetail(item,index)" @controlstoggles="controlstoggles" :playSpeeds="playSpeeds"
|
||||
:index="index" :nowIndex="nowIndex" @dianzanClick="dianzanClick(item,index)" @share="share(item)"
|
||||
@zhuijuClick="zhuijuClick(item)" @popupShow="popupShow"></list-item-vue>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
@@ -25,8 +22,8 @@
|
||||
<cell v-for="(item,index) in list" :key="item.courseDetailsId" :ref="setRefList(index)">
|
||||
<view class="swipers-items" :style="boxStyle" @longpress="popupShow('speed')">
|
||||
<list-item-vue :total="list.length" :item="item" :current="current" :isCollect="isCollect"
|
||||
:isCommand="isCommand"
|
||||
@toDetail="toDetail(item,index)"
|
||||
:rightStyle="rightStyle" :infoStyle="infoStyle"
|
||||
:isCommand="isCommand" :showControls="control.showControls" @toDetail="toDetail(item,index)"
|
||||
@itemMounted="itemMounted" @controlstoggles="controlstoggles" :index="index" :instance="instance"
|
||||
:nowIndex="nowIndex" @appear="appear($event,item,index)" :playSpeeds="playSpeeds"
|
||||
@disappear="disappear(item,index)" @dianzanClick="dianzanClick(item,index)" @share="share(item)"
|
||||
@@ -150,8 +147,7 @@
|
||||
</view>
|
||||
</up-popup>
|
||||
|
||||
|
||||
|
||||
<my-poster ref="refPoster"></my-poster>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -177,6 +173,9 @@
|
||||
onMounted,
|
||||
getCurrentInstance
|
||||
} from 'vue';
|
||||
|
||||
const refPoster = ref(null)
|
||||
|
||||
const props = defineProps({
|
||||
list: {
|
||||
type: Array,
|
||||
@@ -184,13 +183,13 @@
|
||||
[]
|
||||
}
|
||||
},
|
||||
isCommand:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
isCommand: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
isTabbar:{
|
||||
type:Boolean,
|
||||
default:false
|
||||
isTabbar: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
info: {
|
||||
tpye: Object,
|
||||
@@ -209,11 +208,14 @@
|
||||
showBack: true,
|
||||
showControls: true
|
||||
})
|
||||
|
||||
const customStyle=computed(()=>{
|
||||
// #ifdef APP
|
||||
control.showControls=false
|
||||
// #endif
|
||||
|
||||
const customStyle = computed(() => {
|
||||
// #ifdef H5
|
||||
return {
|
||||
bottom:props.isTabbar?'50px':'0'
|
||||
bottom: props.isTabbar ? '50px' : '0'
|
||||
}
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
@@ -223,6 +225,7 @@
|
||||
|
||||
function controlstoggles(e) {
|
||||
control.showControls = e.detail.show
|
||||
console.log(control.showControls );
|
||||
control.showBack = control.showControls
|
||||
console.log(control);
|
||||
}
|
||||
@@ -243,8 +246,9 @@
|
||||
}],
|
||||
active: 1
|
||||
})
|
||||
|
||||
const $mountedComponents={}
|
||||
|
||||
const $mountedComponents = {}
|
||||
|
||||
function itemMounted(index) {
|
||||
// $mountedComponents[index]=true
|
||||
}
|
||||
@@ -293,9 +297,9 @@
|
||||
|
||||
let cacheIndex = null
|
||||
|
||||
function appear(isFirst,item, index) {
|
||||
if(isFirst){
|
||||
$mountedComponents[index]=true
|
||||
function appear(isFirst, item, index) {
|
||||
if (isFirst) {
|
||||
$mountedComponents[index] = true
|
||||
}
|
||||
if (!initing) {
|
||||
cacheIndex = index
|
||||
@@ -353,7 +357,7 @@
|
||||
function goListPosition(index) {
|
||||
console.log('goListPosition:' + index)
|
||||
const el = refList.value[index]
|
||||
if($mountedComponents[props.list.length-1]){
|
||||
if ($mountedComponents[props.list.length - 1]) {
|
||||
domModule.scrollToElement(el, {
|
||||
animated: false
|
||||
})
|
||||
@@ -361,10 +365,10 @@
|
||||
const item = props.list[index]
|
||||
setVideoList(item)
|
||||
insertHistory()
|
||||
}else{
|
||||
setTimeout(()=>{
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
goListPosition(index)
|
||||
},30)
|
||||
}, 30)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -383,7 +387,7 @@
|
||||
function popupShow(key = 'show') {
|
||||
popup[key] = true
|
||||
}
|
||||
|
||||
|
||||
|
||||
let jinbiBili = ref(0)
|
||||
let wHeight = ref(0)
|
||||
@@ -400,10 +404,10 @@
|
||||
watch(() => props.collect, (newval) => {
|
||||
isCollect.value = newval
|
||||
})
|
||||
|
||||
function toDetail(item,index){
|
||||
|
||||
function toDetail(item, index) {
|
||||
uni.navigateTo({
|
||||
url:'/pages/video/detail?courseId='+item.courseId
|
||||
url: '/pages/video/detail?courseId=' + item.courseId
|
||||
})
|
||||
}
|
||||
|
||||
@@ -510,8 +514,27 @@
|
||||
const urls = returnShareUrl() + '/me/detail/detail?id=' + item.courseId + '&courseDetailsId=' + item
|
||||
.courseDetailsId + '&invitation=' + uni.getStorageSync('invitationCode') + '&qdCode=' + this.qdCode;
|
||||
console.log(urls);
|
||||
posterData.img = item.titleImg
|
||||
posterData.show = true
|
||||
// #ifdef H5
|
||||
refPoster.value.make({
|
||||
qrcode: urls,
|
||||
title: props.info.title,
|
||||
bigImg: item.titleImg,
|
||||
tips: '长按或扫描识别二维码观看'
|
||||
})
|
||||
// #endif
|
||||
|
||||
// #ifndef H5
|
||||
uni.setClipboardData({
|
||||
data: urls,
|
||||
success() {
|
||||
uni.showToast({
|
||||
title: '邀请链接已复制到剪贴板',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
|
||||
}
|
||||
|
||||
function posterHide() {
|
||||
@@ -610,7 +633,30 @@
|
||||
const nowDanjiPrice = computed(() => {
|
||||
return videoList.value[current.value].price
|
||||
})
|
||||
|
||||
const rightStyle=computed(()=>{
|
||||
// #ifdef H5
|
||||
return {
|
||||
transform: `translateX(${!control.showControls?'0':60}px)`
|
||||
}
|
||||
// #endif
|
||||
// #ifdef APP
|
||||
return {
|
||||
transform: `translateX(${control.showControls?'0':60}px)`
|
||||
}
|
||||
// #endif
|
||||
})
|
||||
const infoStyle=computed(()=>{
|
||||
// #ifdef H5
|
||||
return {
|
||||
transform: `translateX(${!control.showControls?0:'-110%'})`
|
||||
}
|
||||
// #endif
|
||||
// #ifdef APP
|
||||
return {
|
||||
transform: `translateX(${control.showControls?0:'-110%'})`
|
||||
}
|
||||
// #endif
|
||||
})
|
||||
function loadmore() {
|
||||
console.log('loadmore');
|
||||
}
|
||||
@@ -810,6 +856,13 @@
|
||||
height: 56rpx;
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
position: fixed;
|
||||
top: -9999px;
|
||||
left: -9999px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.speed-list {
|
||||
align-items: center;
|
||||
background-color: #eeeeef;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,205 +0,0 @@
|
||||
<template xlang="wxml" minapp="mpvue">
|
||||
<view class="tki-qrcode">
|
||||
<canvas class="tki-qrcode-canvas" :canvas-id="cid" :style="{width:cpSize+'px',height:cpSize+'px'}" />
|
||||
<image v-if="show" :src="result" :style="{width:cpSize+'px',height:cpSize+'px'}" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import QRCode from "./qrcode.js"
|
||||
let qrcode
|
||||
export default {
|
||||
name: "tki-qrcode",
|
||||
props: {
|
||||
cid: {
|
||||
type: String,
|
||||
default: 'tki-qrcode-canvas'
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
unit: {
|
||||
type: String,
|
||||
default: 'upx'
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
val: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
background: {
|
||||
type: String,
|
||||
default: '#ffffff'
|
||||
},
|
||||
foreground: {
|
||||
type: String,
|
||||
default: '#000000'
|
||||
},
|
||||
pdground: {
|
||||
type: String,
|
||||
default: '#000000'
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
iconSize: {
|
||||
type: Number,
|
||||
default: 40
|
||||
},
|
||||
lv: {
|
||||
type: Number,
|
||||
default: 3
|
||||
},
|
||||
onval: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
loadMake: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
usingComponents: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
showLoading: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
loadingText: {
|
||||
type: String,
|
||||
default: '二维码生成中'
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
result: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
_makeCode() {
|
||||
let that = this
|
||||
if (!this._empty(this.val)) {
|
||||
qrcode = new QRCode({
|
||||
context: that, // 上下文环境
|
||||
canvasId: that.cid, // canvas-id
|
||||
usingComponents: that.usingComponents, // 是否是自定义组件
|
||||
// loadingText: that.loadingText, // loading文字
|
||||
text: that.val, // 生成内容
|
||||
size: that.cpSize, // 二维码大小
|
||||
background: that.background, // 背景色
|
||||
foreground: that.foreground, // 前景色
|
||||
pdground: that.pdground, // 定位角点颜色
|
||||
correctLevel: that.lv, // 容错级别
|
||||
image: that.icon, // 二维码图标
|
||||
imageSize: that.iconSize, // 二维码图标大小
|
||||
cbResult: function(res) { // 生成二维码的回调
|
||||
that._result(res)
|
||||
},
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '二维码内容不能为空',
|
||||
icon: 'none',
|
||||
duration: 2000
|
||||
});
|
||||
}
|
||||
},
|
||||
_clearCode() {
|
||||
this._result('')
|
||||
qrcode.clear()
|
||||
},
|
||||
_saveCode() {
|
||||
let that = this;
|
||||
if (this.result != "") {
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: that.result,
|
||||
success: function() {
|
||||
// uni.showToast({
|
||||
// title: '二维码保存成功',
|
||||
// icon: 'success',
|
||||
// duration: 2000
|
||||
// });
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
_result(res) {
|
||||
this.result = res;
|
||||
this.$emit('result', res)
|
||||
},
|
||||
_empty(v) {
|
||||
let tp = typeof v,
|
||||
rt = false;
|
||||
if (tp == "number" && String(v) == "") {
|
||||
rt = true
|
||||
} else if (tp == "undefined") {
|
||||
rt = true
|
||||
} else if (tp == "object") {
|
||||
if (JSON.stringify(v) == "{}" || JSON.stringify(v) == "[]" || v == null) rt = true
|
||||
} else if (tp == "string") {
|
||||
if (v == "" || v == "undefined" || v == "null" || v == "{}" || v == "[]") rt = true
|
||||
} else if (tp == "function") {
|
||||
rt = false
|
||||
}
|
||||
return rt
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
size: function(n, o) {
|
||||
if (n != o && !this._empty(n)) {
|
||||
this.cSize = n
|
||||
if (!this._empty(this.val)) {
|
||||
setTimeout(() => {
|
||||
this._makeCode()
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
},
|
||||
val: function(n, o) {
|
||||
if (this.onval) {
|
||||
if (n != o && !this._empty(n)) {
|
||||
setTimeout(() => {
|
||||
this._makeCode()
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
cpSize() {
|
||||
if (this.unit == "upx") {
|
||||
return uni.upx2px(this.size)
|
||||
} else {
|
||||
return this.size
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted: function() {
|
||||
if (this.loadMake) {
|
||||
if (!this._empty(this.val)) {
|
||||
setTimeout(() => {
|
||||
this._makeCode()
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.tki-qrcode {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tki-qrcode-canvas {
|
||||
position: fixed;
|
||||
top: -99999upx;
|
||||
left: -99999upx;
|
||||
z-index: -99999;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user