[发布优惠券提货券index报错]
This commit is contained in:
218
components/vue-canvas-poster/canvas-poster.vue
Normal file
218
components/vue-canvas-poster/canvas-poster.vue
Normal file
@@ -0,0 +1,218 @@
|
||||
<script>
|
||||
import Painter from './painter'
|
||||
import { equal } from './util'
|
||||
export default {
|
||||
name: 'VueCanvasPoster',
|
||||
props: {
|
||||
painting: {
|
||||
type: Object,
|
||||
default: function() {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
dirty: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
widthPixels: {
|
||||
type: Number,
|
||||
default: 750
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
painting: {
|
||||
handler(newVal, oldVal) {
|
||||
if (this.isNeedRefresh(newVal, oldVal)) {
|
||||
this.paintCount = 0
|
||||
this.startPaint()
|
||||
}
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
paintCount: 0,
|
||||
painterStyle: '',
|
||||
canvasWidthInPx: 375,
|
||||
canvasHeightInPx: 375,
|
||||
width: 100,
|
||||
height: 100,
|
||||
canvas: null,
|
||||
ctx: null
|
||||
}
|
||||
},
|
||||
render(h) {
|
||||
return h('div', [
|
||||
h('canvas', {
|
||||
ref: 'canvas',
|
||||
class: 'canvas',
|
||||
style: this.painterStyle
|
||||
})
|
||||
])
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.canvas = this.$refs.canvas // 指定canvas
|
||||
this.ctx = this.canvas.getContext('2d') //设置2D渲染区域
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 判断一个 object 是否为 空
|
||||
* @param {object} object
|
||||
*/
|
||||
isEmpty(object) {
|
||||
for (const i in object) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
isNeedRefresh(newVal, oldVal) {
|
||||
if (!newVal || this.isEmpty(newVal) || (this.dirty && equal(newVal, oldVal))) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
// 开始绘画
|
||||
startPaint() {
|
||||
if (this.isEmpty(this.painting)) {
|
||||
return
|
||||
}
|
||||
setStringPrototype(1)
|
||||
// 下载图片
|
||||
this.downloadImages()
|
||||
.then(res => {
|
||||
const { width, height } = res
|
||||
if (!width || !height) {
|
||||
console.error(`You should set width and height correctly for painter, width: ${width}, height: ${height}`)
|
||||
return
|
||||
}
|
||||
this.canvasWidthInPx = width.toPx()
|
||||
if (this.widthPixels) {
|
||||
// 重设宽度,高度
|
||||
setStringPrototype(this.widthPixels / this.canvasWidthInPx)
|
||||
this.canvasWidthInPx = this.widthPixels
|
||||
}
|
||||
this.canvasHeightInPx = height.toPx()
|
||||
this.painterStyle = `width:${this.canvasWidthInPx}px;height:${this.canvasHeightInPx}px;`
|
||||
this.canvas = this.$refs.canvas // 指定canvas
|
||||
this.canvas.width = this.canvasWidthInPx
|
||||
this.canvas.height = this.canvasHeightInPx
|
||||
const ctx = this.canvas.getContext('2d') //设置2D渲染区域
|
||||
const pen = new Painter(ctx, res)
|
||||
pen.paint(() => {
|
||||
var imageBase64 = this.canvas.toDataURL('image/png')
|
||||
this.$emit('success', imageBase64)
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
this.$emit('fail', err)
|
||||
})
|
||||
},
|
||||
// 下载所有图片
|
||||
downloadImages() {
|
||||
return new Promise((resolve) => {
|
||||
let preCount = 0
|
||||
let completeCount = 0
|
||||
const paintCopy = JSON.parse(JSON.stringify(this.painting))
|
||||
if (paintCopy.background) {
|
||||
preCount++
|
||||
this.loadImage(paintCopy.background).then(
|
||||
image => {
|
||||
paintCopy.background = image
|
||||
completeCount++
|
||||
preCount === completeCount && resolve(paintCopy)
|
||||
},
|
||||
err => {
|
||||
completeCount++
|
||||
preCount === completeCount && resolve(paintCopy)
|
||||
console.log(err)
|
||||
}
|
||||
)
|
||||
}
|
||||
if (paintCopy.views) {
|
||||
for (const view of paintCopy.views) {
|
||||
if (view && view.type === 'image' && view.url) {
|
||||
preCount++
|
||||
/* eslint-disable no-loop-func */
|
||||
this.loadImage(view.url).then(
|
||||
image => {
|
||||
completeCount++
|
||||
view.url = image
|
||||
// 获得一下图片信息,供后续裁减使用
|
||||
view.sWidth = image.width
|
||||
view.sHeight = image.height
|
||||
preCount === completeCount && resolve(paintCopy)
|
||||
},
|
||||
err => {
|
||||
completeCount++
|
||||
preCount === completeCount && resolve(paintCopy)
|
||||
console.log(err)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
preCount === 0 && resolve(paintCopy)
|
||||
// if (preCount !== completeCount) {
|
||||
// reject('paintCopy');
|
||||
// }
|
||||
})
|
||||
},
|
||||
// 下载图片
|
||||
loadImage(src) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (src.startsWith('#')) {
|
||||
resolve(src)
|
||||
return
|
||||
}
|
||||
const img = new Image()
|
||||
img.onload = () => resolve(img)
|
||||
img.onerror = () => reject(`下载图片失败 ${src}`)
|
||||
img.crossOrigin = 'anonymous'
|
||||
img.src = src
|
||||
if (img.complete === true) {
|
||||
// Inline XML images may fail to parse, throwing an Error later on
|
||||
setTimeout(() => resolve(img), 500)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
function setStringPrototype(scale) {
|
||||
/* eslint-disable no-extend-native */
|
||||
/**
|
||||
* 是否支持负数
|
||||
* @param {Boolean} minus 是否支持负数
|
||||
*/
|
||||
String.prototype.toPx = function toPx(minus, baseSize) {
|
||||
if (this === '0') {
|
||||
return 0
|
||||
}
|
||||
let reg
|
||||
if (minus) {
|
||||
reg = /^-?[0-9]+([.]{1}[0-9]+){0,1}(px|%)$/g
|
||||
} else {
|
||||
reg = /^[0-9]+([.]{1}[0-9]+){0,1}(px|%)$/g
|
||||
}
|
||||
const results = reg.exec(this)
|
||||
const unit = results[2]
|
||||
const value = parseFloat(this)
|
||||
let res = 0
|
||||
if (unit === 'px') {
|
||||
res = Math.round(value * (scale || 1))
|
||||
} else if (unit === '%') {
|
||||
res = Math.round((value * baseSize) / 100)
|
||||
}
|
||||
return res
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.canvas {
|
||||
position: fixed;
|
||||
top: 2000px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user