模拟weshop实现,图层选择工具

703 阅读11分钟

模拟模拟weshop实现,图层选择工具,如下图所示:

image.png

接下来我会从算法返回的图层分割数据开始梳理具体实现过程,所以先看一下图层分割的数据结构(json比较长无法全部展示出来,只保留了一条数据)

{
    "height": 987,
    "width": 987,
    "masks_list": [
        {
            "index_list":[
                217629,
                3,
                981,
                7,
                982,
                4,
                13699,
                6,
                979,
                11,
                975,
                18,
                968,
                23,
                963,
                26,
                960,
                29,
                957,
                32,
                954,
                34,
                952,
                37,
                949,
                40,
                946,
                42,
                944,
                44,
                942,
                46,
                940,
                48,
                938,
                49,
                937,
                50,
                936,
                51,
                935,
                51,
                936,
                50,
                937,
                48,
                938,
                48,
                939,
                48,
                939,
                47,
                940,
                47,
                940,
                46,
                942,
                45,
                942,
                45,
                942,
                44,
                944,
                44,
                943,
                45,
                943,
                45,
                943,
                46,
                941,
                49,
                940,
                50,
                938,
                52,
                937,
                55,
                933,
                58,
                930,
                59,
                929,
                60,
                928,
                63,
                925,
                64,
                113,
                5,
                806,
                66,
                109,
                9,
                804,
                67,
                107,
                11,
                803,
                69,
                104,
                13,
                802,
                73,
                14,
                10,
                74,
                17,
                800,
                98,
                72,
                19,
                798,
                100,
                70,
                22,
                796,
                100,
                68,
                26,
                794,
                100,
                23,
                1,
                43,
                31,
                790,
                99,
                23,
                2,
                42,
                34,
                788,
                98,
                22,
                3,
                42,
                37,
                786,
                98,
                20,
                4,
                41,
                40,
                785,
                97,
                19,
                6,
                40,
                42,
                784,
                96,
                18,
                7,
                39,
                44,
                784,
                95,
                17,
                9,
                36,
                48,
                783,
                94,
                16,
                10,
                34,
                51,
                783,
                93,
                15,
                12,
                32,
                53,
                783,
                92,
                15,
                13,
                30,
                55,
                783,
                91,
                14,
                15,
                28,
                56,
                785,
                90,
                12,
                17,
                26,
                58,
                785,
                89,
                11,
                19,
                25,
                59,
                786,
                87,
                10,
                20,
                25,
                59,
                788,
                85,
                9,
                22,
                23,
                61,
                788,
                84,
                8,
                23,
                23,
                62,
                788,
                84,
                6,
                25,
                22,
                62,
                789,
                85,
                1,
                28,
                22,
                63,
                789,
                113,
                22,
                64,
                789,
                112,
                22,
                64,
                790,
                111,
                22,
                65,
                790,
                110,
                22,
                65,
                791,
                109,
                22,
                66,
                792,
                107,
                21,
                68,
                792,
                105,
                22,
                68,
                793,
                104,
                21,
                70,
                793,
                103,
                20,
                72,
                793,
                102,
                20,
                72,
                794,
                101,
                19,
                74,
                795,
                99,
                18,
                76,
                795,
                97,
                19,
                76,
                796,
                96,
                18,
                78,
                797,
                94,
                17,
                79,
                799,
                91,
                18,
                80,
                799,
                90,
                18,
                81,
                799,
                89,
                17,
                82,
                801,
                86,
                18,
                83,
                801,
                85,
                18,
                83,
                802,
                83,
                18,
                85,
                803,
                80,
                19,
                85,
                804,
                78,
                20,
                86,
                805,
                75,
                21,
                86,
                806,
                73,
                21,
                88,
                807,
                71,
                21,
                89,
                807,
                69,
                22,
                89,
                809,
                66,
                23,
                90,
                809,
                64,
                23,
                91,
                811,
                61,
                24,
                92,
                811,
                59,
                25,
                92,
                812,
                58,
                24,
                93,
                813,
                56,
                25,
                94,
                813,
                55,
                24,
                95,
                813,
                54,
                25,
                96,
                812,
                53,
                25,
                97,
                813,
                52,
                24,
                98,
                813,
                52,
                23,
                100,
                813,
                50,
                23,
                101,
                813,
                50,
                22,
                103,
                812,
                50,
                21,
                104,
                813,
                48,
                20,
                107,
                812,
                48,
                18,
                109,
                812,
                47,
                18,
                110,
                813,
                46,
                17,
                112,
                812,
                45,
                17,
                113,
                812,
                45,
                16,
                114,
                813,
                44,
                16,
                115,
                812,
                43,
                16,
                116,
                813,
                42,
                16,
                117,
                812,
                42,
                15,
                118,
                812,
                42,
                15,
                118,
                813,
                41,
                14,
                120,
                812,
                41,
                14,
                120,
                812,
                41,
                14,
                120,
                813,
                41,
                12,
                122,
                812,
                41,
                12,
                122,
                812,
                42,
                10,
                124,
                812,
                41,
                10,
                124,
                812,
                42,
                8,
                126,
                811,
                42,
                8,
                126,
                812,
                42,
                6,
                128,
                811,
                42,
                6,
                128,
                812,
                42,
                4,
                130,
                811,
                42,
                4,
                130,
                811,
                177,
                811,
                176,
                811,
                177,
                811,
                176,
                811,
                176,
                811,
                177,
                810,
                177,
                811,
                176,
                811,
                127,
                3,
                46,
                812,
                125,
                7,
                43,
                812,
                124,
                9,
                43,
                812,
                122,
                11,
                42,
                812,
                122,
                12,
                42,
                811,
                121,
                13,
                42,
                812,
                120,
                14,
                42,
                811,
                120,
                14,
                42,
                812,
                118,
                16,
                41,
                812,
                118,
                17,
                40,
                812,
                118,
                18,
                39,
                813,
                117,
                19,
                39,
                812,
                116,
                21,
                38,
                812,
                116,
                21,
                38,
                813,
                115,
                22,
                37,
                813,
                115,
                22,
                37,
                813,
                114,
                24,
                36,
                814,
                113,
                24,
                35,
                815,
                113,
                25,
                34,
                816,
                111,
                26,
                34,
                816,
                111,
                26,
                34,
                817,
                110,
                27,
                32,
                818,
                110,
                27,
                31,
                819,
                109,
                29,
                26,
                823,
                109,
                30,
                21,
                826,
                110,
                31,
                15,
                830,
                110,
                33,
                7,
                837,
                110,
                877,
                110,
                876,
                110,
                877,
                110,
                877,
                109,
                877,
                110,
                877,
                109,
                877,
                110,
                876,
                110,
                876,
                111,
                876,
                110,
                876,
                111,
                876,
                110,
                876,
                110,
                876,
                111,
                874,
                112,
                874,
                112,
                874,
                112,
                875,
                111,
                876,
                109,
                877,
                109,
                877,
                107,
                879,
                104,
                882,
                103,
                883,
                103,
                882,
                105,
                882,
                105,
                881,
                106,
                881,
                106,
                880,
                107,
                879,
                108,
                877,
                109,
                877,
                110,
                876,
                110,
                877,
                109,
                878,
                108,
                878,
                108,
                878,
                109,
                878,
                108,
                877,
                110,
                876,
                110,
                877,
                110,
                876,
                111,
                876,
                111,
                876,
                111,
                875,
                113,
                874,
                115,
                871,
                119,
                867,
                122,
                865,
                122,
                865,
                123,
                863,
                124,
                863,
                125,
                862,
                126,
                860,
                127,
                859,
                129,
                858,
                129,
                857,
                130,
                857,
                130,
                857,
                130,
                856,
                131,
                856,
                131,
                855,
                132,
                855,
                132,
                854,
                133,
                854,
                133,
                854,
                133,
                854,
                133,
                854,
                133,
                853,
                135,
                852,
                135,
                852,
                134,
                853,
                134,
                852,
                135,
                852,
                135,
                852,
                135,
                851,
                136,
                850,
                136,
                851,
                136,
                851,
                136,
                850,
                137,
                850,
                137,
                850,
                137,
                850,
                137,
                850,
                136,
                850,
                137,
                850,
                137,
                849,
                138,
                849,
                138,
                849,
                137,
                849,
                138,
                849,
                138,
                848,
                139,
                848,
                139,
                848,
                138,
                849,
                138,
                849,
                138,
                848,
                139,
                848,
                139,
                847,
                140,
                847,
                140,
                846,
                140,
                847,
                140,
                846,
                141,
                846,
                141,
                846,
                140,
                846,
                141,
                846,
                141,
                846,
                141,
                845,
                142,
                845,
                141,
                846,
                141,
                846,
                141,
                845,
                142,
                845,
                141,
                846,
                141,
                846,
                141,
                845,
                142,
                845,
                142,
                845,
                141,
                846,
                141,
                846,
                141,
                845,
                142,
                844,
                142,
                844,
                143,
                844,
                143,
                844,
                142,
                845,
                142,
                845,
                142,
                845,
                142,
                844,
                143,
                844,
                143,
                843,
                143,
                844,
                143,
                843,
                144,
                843,
                144,
                843,
                143,
                844,
                143,
                844,
                143,
                843,
                144,
                843,
                144,
                843,
                143,
                844,
                143,
                843,
                144,
                843,
                143,
                843,
                144,
                843,
                144,
                842,
                145,
                842,
                145,
                842,
                144,
                842,
                145,
                842,
                145,
                841,
                146,
                841,
                145,
                841,
                146,
                841,
                146,
                841,
                145,
                842,
                145,
                841,
                146,
                841,
                146,
                841,
                145,
                842,
                145,
                841,
                146,
                841,
                146,
                841,
                146,
                842,
                144,
                843,
                144,
                844,
                143,
                846,
                141,
                848,
                138,
                851,
                136,
                852,
                135,
                854,
                132,
                857,
                130,
                859,
                128,
                860,
                126,
                863,
                124,
                866,
                121,
                867,
                120,
                869,
                118,
                871,
                115,
                874,
                113,
                876,
                111,
                878,
                109,
                880,
                106,
                883,
                104,
                887,
                100,
                891,
                95,
                894,
                93,
                895,
                92,
                896,
                91,
                898,
                88,
                901,
                86,
                902,
                85,
                903,
                84,
                904,
                82,
                910,
                77,
                912,
                75,
                915,
                71,
                920,
                67,
                923,
                64,
                927,
                60,
                929,
                57,
                934,
                53,
                937,
                50,
                942,
                44,
                946,
                41,
                952,
                34,
                959,
                28,
                963,
                23,
                971,
                15
              ],
            "masks_url": null
        }
        
    ]
}

第一步:数据解读

数据中的index_list是实现本功能的重点,它代表的是非透明区域的索引及偏移量。 如下图,图中的蓝色区域即非透明区域,这个图可以划分为(987*987)974169个点的集合,集合中点按照从左上角到右下角的顺序排列。

image.png

  • index_list[0]对应的数字(即217629)代表第217629点是非透明区域的起点
  • index_list[1]对应的数字(即3)代表217629,217630,217631这三个点都是非透明的
  • index_list[2]对应的数字(即981)代表217632,217633....(217632+980)这些个点都是透明的
  • 之后的点的逻辑都与index_list[1]和index_list[2]相同

第二步:处理数据

以下为处理方法,重点部分在注释写明

/****
item:masks_list的子集
_width:被分割的原始图片的宽度
_height:被分割的原始图片的高度
分割后的每个图层默认与被分割的原始图片尺寸相同
***/
const indexList2image = (item, _width, _height) => {
      let canvas = document.createElement("canvas");
      let instance = canvas.getContext("2d");
      canvas.width = _width;
      canvas.height = _height;
      let _rgbaData =
        (function (e) {
          let width = _width;
          let height = _height;
          let points = Array(width * height).fill(!1); // 创建一个(width * height)个点的集合
          let pos = 0;
          let isShow = !1;
          /**
            通过遍历index_list将points中非透明的点设置为1透明的点设置为0
            index_list[0]是第一个非透明的点此前的点均为0(start)
            index_list[1]是非透明点的点数字(例如为3则 start~start+3-1)设置为1
            index_list[2]是透明点的点数字(例如为4则 start+3 ~ start+3+4-1)设置为0
            ...
            最后的得到的points结构为[0,0,.....1,1,1.....,0,0]
            **/
          for (let t of e.index_list) {
            for (let e = 0; e < t; e++) {
              points[pos + e] = Number(isShow);
            }
            pos += t;
            isShow = !isShow;
          }

          let rgbaData = Array(height); //  将rgbaData设置高度长度的数组
          /**
            rgbaData的每一个元素是从points取的rowIndex对应每一行的点的数据
            结构大致为[[0,0,0,....],[0,0,0,....1,1,1...],.....]
            **/
          for (let rowIndex = 0; rowIndex < height; rowIndex++) {
            rgbaData[rowIndex] = points.slice(
              rowIndex * width,
              (rowIndex + 1) * width
            );
          }
          return rgbaData;
        })(item || []) || [];
      for (let y = 0; y < _rgbaData.length; y++) {
        let col = _rgbaData[y];
        for (let x = 0; x < col.length; x++) {
          let s = _rgbaData[y][x];
          if (1 === s && instance) {
            // 值为1的点填充颜色
            (instance.fillStyle = "#2352D8"), instance.fillRect(x, y, 1, 1);
          }
        }
      }
      // canvas当前层的图片
      // 也个可以通过canvas.toDataURL('image/png')直接返回base64图片
      // matrix即上边生成的二维数组
      return { canvas: canvas, matrix: _rgbaData };
    };

第三步:遍历图层分割中的masks_list就可以得到所有图层对应的图片及matrix即layers

第四步:将layers布局到页面中,可以通过canvas也和使用div

我使用的canvas以为后期处理一些细节操作比较方便,比如通过画笔精修。但是用div应该更简单布局应该更简单,但是上边的canvas直接到出base64图片;

<div id="layer-box" style="width: 500px; height: 500px; position: relative">
  <img
    style="width: 100%; height: 100%; position: absolute"
    src="原始图base64"
  />
</div>
const layers = res.masks_list.map((child) =>
  indexList2image(child, 987, 987)
);
const box = document.querySelector("#layer-box");
const baseStyle = "width:100%;height:100%;position: absolute;";
layers.forEach((ele) => {
  const image = document.createElement("img");
  image.src = ele.canvas;
  image.style = `${baseStyle}opacity:0`;
  image.className = "layer";
  box.append(image);
});
box.addEventListener("mousemove", (e, index) => {
  const { clientX, clientY, offset } = e;
  const x = parseInt((res.width / box.offsetWidth) * clientX);
  const y = parseInt((res.height / box.offsetHeight) * clientY);
  box.querySelectorAll(".layer")[0].style = `${baseStyle}opacity:0`;
  if (layers.find((item) => item.matrix[y][x])) {
    box.querySelectorAll(".layer")[0].style = `${baseStyle}opacity:1`;
  }
});

第五步:监听mousemove事件,通过clientX, clientY获取对应的坐标

const { clientX, clientY } = e;
const x = parseInt(
(res.width / (box.offsetWidth - box.offsetLeft)) * clientX
);
const y = parseInt(
(res.height / (box.offsetHeight - box.offsetTop)) * clientY
);
const allLayers = box.querySelectorAll(".layer");
const index = layers.findIndex((item) => item.matrix?.[y]?.[x]);
allLayers.forEach((ele, i) => {
if (i === index) {
  ele.style = `${baseStyle}opacity:1`;
} else {
  ele.style = `${baseStyle}opacity:0`;
}
});

根据坐标(x,y)layers中查找matrix[y][x]为1的索引值,将对索引img透明度设置为1其他为0

实现效果如下