美文网首页
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