美文网首页
js+svg+canvas实现用多张小图拼合成一个固定的形状

js+svg+canvas实现用多张小图拼合成一个固定的形状

作者: 菜蚴菜 | 来源:发表于2021-01-09 17:41 被阅读0次

实现思路:

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>



相关文章

网友评论

      本文标题:js+svg+canvas实现用多张小图拼合成一个固定的形状

      本文链接:https://www.haomeiwen.com/subject/nyncaktx.html