Vue-konva 除了能繪製圖形外,也能繪製圖片,讓我們以更靈活方式控制圖片。
Version
macOS Catalina 10.15.5
WebStorm 2020.1.3
Vue 2.6.11
Vue-konva 2.1.3
Draw Image
除了使用 <img>
顯示圖片外,我們也可使用 Vue-konva 繪製圖片。
Vue-konva
<template>
<v-stage :config="stageConfig">
<v-layer>
<v-image :config="imageConfig"></v-image>
</v-layer>
</v-stage>
</template>
<script>
let width = window.innerWidth
let height = window.innerHeight
let mounted = function() {
let image = new Image
image.src = 'https://konvajs.org/assets/yoda.jpg'
image.onload = _ => {
this.imageConfig = {
'image': image
}
}
}
export default {
name: 'App',
data: _ => ({
stageConfig: {
width, height
},
imageConfig: {}
}),
mounted
}
</script>
第 2 行
<v-stage :config="stageConfig">
<v-layer>
<v-image :config="imageConfig"></v-image>
</v-layer>
</v-stage>
Vue-konva 提供了 <v-image>
讓我們繪製圖片,依然只要提供繪圖資訊給 config
property 即可。
14 行
let image = new Image
image.src = 'https://konvajs.org/assets/yoda.jpg'
image.onload = _ => {
this.imageConfig = {
'image': image
}
}
要繪製圖片比較特殊,必須使用 Image
Object,但 Image
Object 以 asynchronous 提供 image,必須在 load
event 才能得到完整 image 寫入 imageConfig
side effect。
Promise
<template>
<v-stage :config="stageConfig">
<v-layer>
<v-image :config="imageConfig"></v-image>
</v-layer>
</v-stage>
</template>
<script>
let width = window.innerWidth
let height = window.innerHeight
let toImage = src => new Promise((resolve, reject) => {
let image = new Image
image.src = src
image.onload = _ => resolve({ image })
image.onerror = e => reject(e)
})
let mounted = async function() {
let src = 'https://konvajs.org/assets/yoda.jpg'
toImage(src)
.then(x => this.imageConfig = x)
.catch(console.log)
}
export default {
name: 'App',
data: _ => ({
stageConfig: {
width, height
},
imageConfig: {}
}),
mounted
}
</script>
13 行
let toImage = src => new Promise((resolve, reject) => {
let image = new Image
image.src = src
image.onload = _ => resolve({ image })
image.onerror = e => reject(e)
})
若覺得 Image
Object 使用 event-based API 實現 asynchronous 不舒服,也可自行實作 toImage()
以 Promise 實現。
在 load
event 以 resolve()
回傳 imageConfig
object,並在 error
event 提供 Rejected Promise。
23 行
toImage(src)
.then(x => this.imageConfig = x)
.catch(console.log)
由於 toImage()
回傳 Promise,因此可在 Promise Chain 中寫入 side effect 與 error handling。
Conclusion
- Vue-konva 在繪製圖片時與一般圖形不同,需使用
Image
Object,因此勢必以 code 建立 Image
Object 為 asynchronous,在load
event 才能提供完整 image,除了在load
event 寫入 side effect 外,也可改用 Promise 方式