|
@@ -1,146 +1,120 @@
|
|
|
<template>
|
|
|
- <div class="hmt-w">
|
|
|
- <!--图片预览区域-->
|
|
|
- <div class="preview-w" v-show="strPostSrc">
|
|
|
- <div class="poster" @click="funPreviewImage">
|
|
|
- <img :src="strPostSrc" alt="" ref="poster">
|
|
|
- </div>
|
|
|
- <p class="tips">长按可保存选手海报。分享海报邀请好友投票!</p>
|
|
|
- </div>
|
|
|
+ <div>
|
|
|
+ <Popup position="bottom"
|
|
|
+ :style="{width: '80%', height: '88.5%', left: '10%', bottom: '3%', borderRadius: '10px 10px'}"
|
|
|
+ v-model="showPoster">
|
|
|
+ <img class="poster" :src="strPostSrc" alt="" @click="funPreviewImage">
|
|
|
+ </Popup>
|
|
|
<div class="hide" id="qr-code"></div>
|
|
|
- <canvas class="canvas hide" ref="myCanvas"></canvas>
|
|
|
+ <canvas class="hide" ref="myCanvas"></canvas>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
+ import { Popup, Notify, Toast } from 'vant'
|
|
|
import QRCode from 'qrcodejs2'
|
|
|
+
|
|
|
export default {
|
|
|
name: 'poster',
|
|
|
- components: {},
|
|
|
+ components: {
|
|
|
+ Popup
|
|
|
+ },
|
|
|
+ props: {
|
|
|
+ posterBg: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ },
|
|
|
+ codeParams: {
|
|
|
+ type: Object,
|
|
|
+ default: function () {
|
|
|
+ return {
|
|
|
+ link: '',
|
|
|
+ x: 112,
|
|
|
+ y: 1046,
|
|
|
+ width: 202,
|
|
|
+ height: 202
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
data () {
|
|
|
return {
|
|
|
- no: '',
|
|
|
+ showPoster: false,
|
|
|
strPostSrc: '',
|
|
|
qrcode: null
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
- getQRCode (obj) {
|
|
|
- let vm = this
|
|
|
- vm.qrcode = new QRCode('qr-code', {
|
|
|
- width: 130,
|
|
|
- height: 130,
|
|
|
- text: `${vm.$root.strPageUrl}#/detail/${vm.no}`,
|
|
|
- colorDark: '#000',
|
|
|
- colorLight: '#fff'
|
|
|
+ createQRCode () {
|
|
|
+ const { link } = this.codeParams
|
|
|
+ Toast.loading({
|
|
|
+ message: '海报生成中...',
|
|
|
+ forbidClick: true,
|
|
|
+ duration: 0
|
|
|
})
|
|
|
- let timer = setTimeout(() => {
|
|
|
+ if (!this.qrcode) {
|
|
|
+ this.qrcode = new QRCode('qr-code', {
|
|
|
+ width: 212,
|
|
|
+ height: 212,
|
|
|
+ text: link,
|
|
|
+ colorDark: '#000',
|
|
|
+ colorLight: '#fff'
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ this.qrcode.clear()
|
|
|
+ this.qrcode.makeCode(link)
|
|
|
+ }
|
|
|
+ const timer = setTimeout(() => {
|
|
|
clearTimeout(timer)
|
|
|
- vm.initPoster(obj)
|
|
|
+ this.createPoster()
|
|
|
}, 500)
|
|
|
},
|
|
|
- initPoster (obj) {
|
|
|
- let vm = this
|
|
|
- const { bg, no, name, photo, mask, icon } = obj
|
|
|
- let canvas = vm.$refs.myCanvas
|
|
|
- let ctx = canvas.getContext('2d')
|
|
|
- let canvas2 = document.getElementById('qr-code').getElementsByTagName('canvas')[0]
|
|
|
- let code = {}
|
|
|
+ setImg (params) {
|
|
|
+ const img = new Image()
|
|
|
+ img.crossOrigin = 'anonymous'
|
|
|
+ img.onload = function () {
|
|
|
+ params.ctx.drawImage(img, params.x, params.y, params.width, params.height)
|
|
|
+ params.cb()
|
|
|
+ }
|
|
|
+ img.src = params.src
|
|
|
+ },
|
|
|
+ createPoster () {
|
|
|
+ const vm = this
|
|
|
+ const { x, y, width, height } = this.codeParams
|
|
|
+ const canvas = vm.$refs.myCanvas
|
|
|
+ const ctx = canvas.getContext('2d')
|
|
|
+ const canvas2 = document.getElementById('qr-code').getElementsByTagName('canvas')[0]
|
|
|
+ const code = {}
|
|
|
code.src = canvas2.toDataURL('image/png', 1)
|
|
|
canvas.width = 750
|
|
|
- canvas.height = 1100
|
|
|
-
|
|
|
+ canvas.height = 1334
|
|
|
// 绘制背景
|
|
|
vm.setImg({
|
|
|
ctx,
|
|
|
- src: bg['src'],
|
|
|
+ src: this.posterBg,
|
|
|
x: 0,
|
|
|
y: 0,
|
|
|
width: 750,
|
|
|
- height: 1100,
|
|
|
+ height: 1334,
|
|
|
cb () {
|
|
|
- ctx.fillStyle = '#fff'
|
|
|
- ctx.fillRect(469, 798, 158, 158)
|
|
|
// 绘制二维码
|
|
|
vm.setImg({
|
|
|
ctx,
|
|
|
src: code.src,
|
|
|
- x: 479,
|
|
|
- y: 808,
|
|
|
- width: 138,
|
|
|
- height: 138,
|
|
|
+ x: x,
|
|
|
+ y: y,
|
|
|
+ width: width,
|
|
|
+ height: height,
|
|
|
cb () {
|
|
|
- // 绘制文本
|
|
|
- ctx.font = '500 24px/44px STYuanti-Regular'
|
|
|
- ctx.fillStyle = '#7B4D03'
|
|
|
- ctx.fillText('编号:' + no.toString().padStart(4, '0'), 123, 820)
|
|
|
-
|
|
|
- ctx.font = '700 32px/46px PingFangSC'
|
|
|
- ctx.fillText(name, 123, 870)
|
|
|
- ctx.save()
|
|
|
- ctx.lineWidth = 0
|
|
|
- ctx.strokeStyle = 'rgba(255,255,255,0)'
|
|
|
- ctx.save()
|
|
|
- vm.setImg({
|
|
|
- // 绘制用户图片
|
|
|
- ctx,
|
|
|
- src: photo['src'],
|
|
|
- x: photo['x'],
|
|
|
- y: photo['y'],
|
|
|
- width: photo['width'],
|
|
|
- height: photo['height'],
|
|
|
- cb () {
|
|
|
- ctx.restore()
|
|
|
- vm.setImg({
|
|
|
- ctx,
|
|
|
- src: mask['src'],
|
|
|
- x: mask['x'],
|
|
|
- y: mask['y'],
|
|
|
- width: mask['width'],
|
|
|
- height: mask['height'],
|
|
|
- cb () {
|
|
|
- ctx.restore()
|
|
|
- vm.setImg({
|
|
|
- ctx,
|
|
|
- src: icon['src'],
|
|
|
- x: icon['x'],
|
|
|
- y: icon['y'],
|
|
|
- width: icon['width'],
|
|
|
- height: icon['height'],
|
|
|
- cb () {
|
|
|
- vm.strPostSrc = canvas.toDataURL('image/png', 1)
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
- })
|
|
|
+ vm.strPostSrc = canvas.toDataURL('image/png', 1)
|
|
|
+ vm.showPoster = true
|
|
|
+ Toast.clear()
|
|
|
+ Notify({ type: 'primary', message: '长按图片保存到相册', duration: 3000 })
|
|
|
}
|
|
|
})
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
- setImg (params) {
|
|
|
- let width = params['width']
|
|
|
- let height = params['height']
|
|
|
- let img = new Image()
|
|
|
- if (/^http/.test(params.src)) {
|
|
|
- img.crossOrigin = ''
|
|
|
- }
|
|
|
- img.onload = function () {
|
|
|
- if (/^http/.test(params.src)) {
|
|
|
- width = this['width']
|
|
|
- height = this['height']
|
|
|
- if (width >= height) {
|
|
|
- params.ctx.rotate(-2 * Math.PI / 180)
|
|
|
- params.ctx.translate(-14, 17)
|
|
|
- }
|
|
|
- }
|
|
|
- params.ctx.drawImage(img, params.x, params.y, width, height)
|
|
|
- params.cb()
|
|
|
- }
|
|
|
- img.src = params.src
|
|
|
- },
|
|
|
// 图片预览
|
|
|
funPreviewImage () {
|
|
|
const vm = this
|
|
@@ -157,47 +131,12 @@
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
- .hmt-w {
|
|
|
- width: 100%;
|
|
|
- min-height: 100vh;
|
|
|
- background: #F1CA4F;
|
|
|
- padding-top: 40px;
|
|
|
- }
|
|
|
-
|
|
|
.hide {
|
|
|
display: none;
|
|
|
}
|
|
|
|
|
|
- .preview-w {
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
-
|
|
|
.poster {
|
|
|
- position: relative;
|
|
|
- left: 0;
|
|
|
- top: 0;
|
|
|
- width: 670px;
|
|
|
- height: 1006px;
|
|
|
- margin: 0 auto;
|
|
|
- border-radius: 22px;
|
|
|
- overflow: hidden;
|
|
|
-
|
|
|
- img {
|
|
|
- position: absolute;
|
|
|
- left: 50%;
|
|
|
- top: 50%;
|
|
|
- transform: translate(-50%, -50%);
|
|
|
- display: block;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .tips {
|
|
|
+ display: block;
|
|
|
width: 100%;
|
|
|
- padding: 27px 0 100px;
|
|
|
- font: 400 24px/34px 'STYuanti-SC';
|
|
|
- text-align: center;
|
|
|
- color: #7B4D03;
|
|
|
}
|
|
|
</style>
|