实现思路:
1、把要实现的形状用黑白图片表示出来,有内容的部分用黑色表示,无内容的部分用白色表示
2、把图片矩阵化有有内容的部分为1,无内容的部分为0
3、横竖向取点,在取到的点值为0的地方忽略,在取到点值为1的地方用canvas画制一个小图
实现代码如下:
<div>
<canvas id="myCanvas" ref="myCanvas" width="500" height="500"></canvas>
<div class="content">
<div>{{objNum}}</div>
<svg
style="width:700;height:700;"
xmlns="http://www.w3.org/2000/svg"
id="mySVG"
viewBox="0 0 100% 100%"
preserveAspectRatio="xMidYMid meet"
class="content-svg"
>
<g v-for="(items,pIndex) in pointArr" :key="pIndex" v-show="pointArr.length>0">
<image
v-for="(item,cIndex) in items"
v-show="item.value"
:key="cIndex"
:xlink:href="item.img"
width="20"
height="20"
:x="imgW/numX*cIndex-10+100"
:y="imgH/numY*pIndex-10+100"
border-radius="10"
class="content-img"
@click="clickMe(item.text)"
>
<animate
attributeName="x"
:from="imgW/numX*cIndex-10+100+Math.ceil((Math.random()-0.5)*200)"
:to="imgW/numX*cIndex-10+100"
begin="0s"
dur="2s"
repeatCount="1"
></animate>
<animate
attributeName="y"
:from="imgH/numY*pIndex-10+100+Math.ceil((Math.random()-0.5)*200)"
:to="imgH/numY*pIndex-10+100"
begin="0s"
dur="2s"
repeatCount="1"
></animate>
</image>
</g>
</svg>
</div>
</div>
</template>
<script>
import Img from '@/assets/images/famile-img.png'
export default {
data() {
return {
interX: null, // 横向取的点的间隔
interY: null, // 竖向取的点的间隔
numX: null, // 向取的点数
numY: null, // 竖向取点数
pointArr: null,
imgH: null, //图片尺寸
imgW: null,
objNum: 0,
imgArr: [
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1556433873348&di=0d931a485759b5a4794001e8bf77f73c&imgtype=0&src=http%3A%2F%2Fimages.liqucn.com%2Fimg%2Fh1%2Fh991%2Fimg201712091149430_info400X400.jpg',
'https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1653076728,1302620582&fm=26&gp=0.jpg',
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1556433873342&di=ba26166345046a4be8fb122cf319a218&imgtype=0&src=http%3A%2F%2Fwww.ghost64.com%2Fqqtupian%2FzixunImg%2Flocal%2F2016%2F11%2F11%2F14788536543189.jpg',
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1556433873347&di=2370672ce0a164a139e1ff0352606bfe&imgtype=0&src=http%3A%2F%2Fimage.biaobaiju.com%2Fuploads%2F20180302%2F13%2F1519967960-ItxVyYfSXW.jpg'
]
}
},
created() {},
mounted() {
// 读取图片的0 1 信息 按照一定的间隔获取图片点的信息
this.getImgArr()
},
computed: {},
methods: {
clickMe(v) {
alert(v)
},
getImgArr() {
const mycanvas = this.$refs.myCanvas
const ctx = mycanvas.getContext('2d')
const img = new Image()
img.src = Img
let arr = []
let that = this
img.onload = function() {
that.imgH = 500 //图片尺寸
that.imgW = 500
ctx.drawImage(img, 0, 0, that.imgW, that.imgH)
//获取图像二进制数据 无论图片大小是多少 一共4万条数据,每行100
const imgData = ctx.getImageData(0, 0, that.imgW, that.imgH).data
let widthNum = Math.sqrt(imgData.length)
let heightNum = Math.sqrt(imgData.length)
console.log(imgData)
console.log(
'imgData:' +
imgData.length +
'widthNum:' +
widthNum +
'heightNum:' +
heightNum
)
// console.log(heightNum)
that.numX = 20 // 向取的点数
that.numY = 20 // 竖向取点数
that.interX = Math.ceil(widthNum / that.numX) // 横向取的点的间隔
that.interY = Math.ceil(heightNum / that.numY) // 竖向取的点的间隔
// const numY = Math.ceil(heightNum / (this.interY * 100));
console.log('that.interX:' + that.interX + 'that.interY:' + that.interY)
// 处理点生成新的对象
for (let i = 0; i < that.numY; i++) {
let start = i * widthNum * that.interY
let end = i * widthNum * that.interY + 2 * widthNum
console.log('start:' + start + 'end:' + end)
let oItem = imgData.slice(start, end)
let item = []
for (let j = 0; j < that.numX; j++) {
//把图片地址填入其中
let posX = oItem[j * that.interX * 2]
let width = Math.ceil((Math.random() - 0.8) * 20 + 20)
let itemObj = {
value: posX,
img:
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1557036084&di=7abc651f7e30c56b99f3da36e9c83109&imgtype=jpg&er=1&src=http%3A%2F%2Fimg.mp.itc.cn%2Fupload%2F20170212%2Fdc91917690c246b0a2cd1ad039b1267a_th.jpg',
text: '点击了我',
width: width
}
if (posX && that.imgArr.length - 1 > that.objNum) {
itemObj.img = that.imgArr[that.objNum]
that.objNum++
}
item.push(itemObj)
}
arr.push(item)
}
that.pointArr = arr
}
}
},
watch: {}
}
</script>
<style lang="scss">
#myCanvas {
margin-top: -500px;
visibility: hidden;
}
.content {
width: 700px;
height: 700px;
margin: 0 auto;
}
.content-img {
border-radius: 10px;
}
</style>
网友评论