上代码
<template>
<el-carousel
id="elCarousel"
:*interval*="2000"
*arrow*="always"
*indicator-position*="none"
*height*="100%"
\>
<el-carousel-item :*name*="'item' + index" *v-for*="(item, index) in picture" :*key*="index">
<canvas *v-MosaicCanvas*="index" *class*="MosaicCanvas" />
</el-carousel-item>
</el-carousel>
</template>
<script>
import Mosaic from 'image-mosaic'
export default {
data() {
return {
picture: [],
canvasWidth: '',
canvasHeight: ''
}
},
directives: {
MosaicCanvas: {
//不是轮播图 可以直接拿到数据渲染
//因为是轮播图 不确定元素个数 所以得给每个canvas手动加马赛克
//如果是拿到数据 直接转 渲染不出来 因为后面有方法是异步的 会白屏 看不到效果
inserted: function (el, binding, vnode) {
//这里的el就是canvas ,binding.value 就是轮播图的第几个
vnode.context.setMosaicImg(el, binding.value || 0)
}
}
},
mounted() {
this.init()
//拿到父盒子的宽高 让canvas 拉满
const elCarousel = document.getElementById('elCarousel')
this.canvasWidth = elCarousel.clientWidth
this.canvasHeight = elCarousel.clientHeight
},
methods: {
init() {
//请求接口拿到图片列表
this.picture = data
},
//加马赛克
setMosaicImg(el, index) {
const src = this.picture[index]
this.drawImageToCanvas(el, src).then(ctx => {
const mosaic = new Mosaic(ctx)
const MouseEvents = {
init() {
//马赛克在canvas上的位置
//Y轴方向起点
const ctxY1 = Number.parseInt(ctx.canvas.clientHeight * 0.33)
//Y轴方向终点
const ctxY2 = Number.parseInt(ctx.canvas.clientHeight * 0.66)
//X轴全部都马塞克
const ctxW = Number.parseInt(ctx.canvas.clientWidth)
//隔20个像素打个马赛克
for (let i = ctxY1; i + 20 <= ctxY2; i = i + 20) {
for (let j = 0; j + 20 <= ctxW; j = j + 20) {
console.log(j, i, ctxW)
mosaic.drawTileByPoint(j, i)
}
}
}
}
MouseEvents.init()
})
},
drawImageToCanvas(el, src) {
return new Promise(reslove => {
const canvas = el
const ctx = canvas.getContext('2d')
const image = new Image()
// 解决跨域问题
image.setAttribute('crossOrigin', 'anonymous')
const _this = this
image.onload = function () {
//拿到父盒子的宽高 填满父盒子
//不这样做 即使canvas设置100% 渲染区域还是之前的图片大小
canvas.width = _this.canvasWidth
canvas.height = _this.canvasHeight
ctx.drawImage(this, 0, 0, _this.canvasWidth, _this.canvasHeight)
const quality = 1
// 这里的dataurl就是base64类型
// 使用toDataUrl将图片转换成jpeg的格式,不要把图片压缩成png,因为压缩成png后base64的字符串可能比不转换前的长!
const dataurl = canvas.toDataURL('image/jpeg', quality)
reslove(ctx)
}
image.src = src
})
}
}
}
</script>