欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript前端實(shí)現(xiàn)拼圖分割效果

 更新時(shí)間:2024年10月24日 10:05:15   作者:前端大C  
這篇文章主要為大家詳細(xì)介紹了如何通過(guò)JavaScript前端實(shí)現(xiàn)拼圖分割效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

第一步

找到一張模板圖,如下:

這是一張通過(guò)RGBA的B通道區(qū)分的模板圖,每個(gè)碎片的B通道,對(duì)應(yīng)序號(hào)分別是0,10,20,30,40,……

即序號(hào)的10倍等于B通道的值。

第二步

找到一張需要切分的圖,如下:

確保兩張圖的尺寸一致,不一致會(huì)導(dǎo)致壓縮變形既。

第三步

上代碼,微信小程序: ts代碼:

// components/cut-img/index.ts
Component({

  /**
   * 組件的屬性列表
   */
  properties: {
    temp: {
      type: String,
      value: getApp().imgPrefix('/model/test/temp5-3.png')
    },
    img: {
      type: String,
      value: getApp().imgPrefix('/model/test/test.jpg')
    },
    size: {
      type: Number,
      value: 15
    },
  },

  /**
   * 組件的初始數(shù)據(jù)
   */
  data: {

  },

  lifetimes: {
    ready() {
      // 通過(guò) SelectorQuery 獲取 Canvas 節(jié)點(diǎn)
      setTimeout(() => {
        const query = wx.createSelectorQuery().in(this)
        query.select('#canvas')
          .fields({
            node: true,
            size: true,
          })
          .exec(this.init.bind(this))
      }, 1000);
    },
  },

  /**
   * 組件的方法列表
   */
  methods: {
    /**
     * 初始化
     */
    init(res: any) {
      const canvas = this.canvas = res[0]?.node
      if (!canvas) {
        return false
      }
      this.ctx = canvas.getContext('2d')

      this.setTemp()

      return false
    },
    /**
     * 設(shè)置temp 圖片上圖
     */
    setTemp() {
      const ctx = this.ctx
      const canvas = this.canvas

      const img = canvas.createImage()
      ctx.clearRect(0, 0, canvas.width, canvas.height)
      img.onload = () => {
        this.width = canvas.width = img.width
        this.height = canvas.height = img.height
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height)

        this.tempData = ctx.getImageData(0, 0, canvas.width, canvas.height);
        this.setImg()
      }
      img.src = this.data.temp
    },
    /**
     * 設(shè)置img 圖片上圖
     */
    setImg() {
      const ctx = this.ctx
      const canvas = this.canvas
      const img = canvas.createImage()
      ctx.clearRect(0, 0, canvas.width, canvas.height)
      img.onload = () => {
        ctx.drawImage(img, 0, 0, canvas.width, canvas.height)

        this.imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
  
        const size = this.data.size
        const list: any[] = []
        for(let i = 0; i < size; i++) {
          this.cut(i, list)
        }
        console.log('>>> list', list)
        // this.triggerEvent('success', list)
      }
      img.src = this.data.img
    },
    /**
     * 裁剪
     * @param index 序號(hào)
     * @param list 存儲(chǔ)列表
     */
    cut(index: number, list: any[]) {
      const ctx = this.ctx
      const canvas = this.canvas
      const newData = ctx.createImageData(this.width, this.height);
      for (let i = 0; i < newData.data.length; i += 4) {
        const temp = this.tempData.data.slice(i, i + 4)
        if (Math.abs(temp[2] - index * 10) < 2 && temp[3] > 10) {
          newData.data[i + 0] = this.imgData.data[i + 0]
          newData.data[i + 1] = this.imgData.data[i + 1]
          newData.data[i + 2] = this.imgData.data[i + 2]
          newData.data[i + 3] = this.imgData.data[i + 3]
        } else {
          newData.data[i + 0] = 0
          newData.data[i + 1] = 0
          newData.data[i + 2] = 0
          newData.data[i + 3] = 0
        }
      }
      // ctx.putImageData(newData, 0, 0)

      let minX = newData.width;
      let minY = newData.height;
      let maxX = -1;
      let maxY = -1;

      // 遍歷所有像素,查找非透明像素的位置
      for (let y = 0; y < newData.height; y++) {
        for (let x = 0; x < newData.width; x++) {
          const pixelIndex = (y * newData.width + x) * 4;
          if (newData.data[pixelIndex + 3] > 0) { // Alpha通道大于0表示非透明
            minX = Math.min(minX, x);
            maxX = Math.max(maxX, x);
            minY = Math.min(minY, y);
            maxY = Math.max(maxY, y);
          }
        }
      }
      const width = maxX - minX + 1
      const height = maxY - minY + 1
      canvas.width = width
      canvas.height = height
      // 創(chuàng)建新的圖像數(shù)據(jù)對(duì)象用于裁剪后的圖像
      const croppedImage = ctx.createImageData(width, height);

      // 復(fù)制非透明像素到新的圖像數(shù)據(jù)中
      for (let y = minY; y <= maxY; y++) {
        for (let x = minX; x <= maxX; x++) {
          const srcIndex = ((y * newData.width) + x) * 4;
          const destIndex = ((y - minY) * (maxX - minX + 1) + (x - minX)) * 4;
          croppedImage.data.set(newData.data.subarray(srcIndex, srcIndex + 4), destIndex);
        }
      }

      // 清除畫(huà)布并繪制裁剪后的圖像
      ctx.clearRect(0, 0, width, height);
      ctx.putImageData(croppedImage, 0, 0);
      const dataUrl = canvas.toDataURL('image/png');
      list.push({
        x: minX,
        y: minY,
        width,
        height,
        dataUrl
      })
    },
  }
})

wxml代碼:

<!--components/cut-img/index.wxml-->
<view style="display: none;">
  <canvas type="2d" id="canvas"></canvas>
</view>

步驟總結(jié)

1、獲取canvas

2、先渲染模板,拿到模板圖的imgdata

3、再渲染需要切換的目標(biāo)圖,拿到目標(biāo)圖的imgdata

4、根據(jù)切分的數(shù)量,循環(huán)切分

4.1、創(chuàng)建一個(gè)空的imgdata,根據(jù)序號(hào)對(duì)應(yīng)的B通道,把對(duì)應(yīng)的切片數(shù)據(jù)存入imgdata

4.2、計(jì)算非空白區(qū)域的位置和尺寸,裁剪圖片數(shù)據(jù)

4.3、裁剪后的數(shù)據(jù)放回canvas,導(dǎo)出dataURL

4.4、保存對(duì)應(yīng)的x、y、width、height、dataURL

5、返回list

到此這篇關(guān)于JavaScript前端實(shí)現(xiàn)拼圖分割效果的文章就介紹到這了,更多相關(guān)JavaScript拼圖分割內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論