首页 前端知识 vue TS svg实现图片任意形状剪切

vue TS svg实现图片任意形状剪切

2024-05-13 10:05:46 前端知识 前端哥 220 182 我要收藏

通过svg剪切功能实现图片剪切

这个是原图
在这里插入图片描述
这些事预设好的切割形状,理论上可以开放给用户自己画
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这个是剪切完成的效果

在这里插入图片描述

<template>
  <div class="content">
    <div id="clipContainer" class="img-clip" style="" v-if="!masterMap">
      <div
        class="viewPort"
        @mousedown="shapeMousedown"
        :style="viewPortAttStyle"
      >
        <div class="inner" :style="viewInnerStyle">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            width="100%"
            height="100%"
          >
            <defs>
              <mask id="maskPath_3_clip_clipping">
                <image
                  reswithworks="yes"
                  preserveAspectRatio="none"
                  xmlns:xlink="http://www.w3.org/1999/xlink"
                  :xlink:href="maskPathClip"
                  transform="scale(1 1)"
                  :style="viewPortImageStyle"
                ></image>
              </mask>
            </defs>

            <g mask="url(#maskPath_3_clip_clipping)" transform="scale(1 1)">
              <image
                width="380"
                height="300"
                :xlink:href="imgLink"
                :style="imageStyle"
              ></image>
            </g>
          </svg>
        </div>
        <svg
          xmlns="http://www.w3.org/2000/svg"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          version="1.1"
          width="100%"
          height="100%"
          class="shape-box-controls box-controls"
          v-if="isEdit"
        >
          <g
            fill="#fff"
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="1"
            data-control="tl"
            data-target="imageShape"
            class="shape-box-control box-control"
            style="cursor: nw-resize"
            :style="boxControlsStyle(0)"
            @mousedown="boxControlsDown($event, 0)"
          >
            <path
              d="M20.5,0H2.5A2.5,2.5,0,0,0,0,2.5v18a2.5,2.5,0,0,0,5,0V5H20.5a2.5,2.5,0,1,0,0-5Z"
              transform="translate(0.5 0.5)"
              fill="#fff"
            ></path>
            <path
              d="M21,1a2,2,0,1,1,0,4H5V21a2,2,0,0,1-4,0V3A2,2,0,0,1,3,1H21m0-1H3A3,3,0,0,0,0,3V21a3,3,0,0,0,6,0V6H21a3,3,0,1,0,0-6Z"
              transform="translate(0 0)"
              fill="#afb4c1"
            ></path>
          </g>
          <g
            fill="#fff"
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="1"
            data-control="tr"
            data-target="imageShape"
            class="shape-box-control box-control"
            style="cursor: ne-resize"
            :style="boxControlsStyle(1)"
            @mousedown="boxControlsDown($event, 1)"
          >
            <path
              d="M21,23.5H3A2.5,2.5,0,0,1,.5,21V3a2.5,2.5,0,0,1,5,0V18.5H21a2.5,2.5,0,1,1,0,5Z"
              fill="#fff"
            ></path>
            <path
              d="M21,23a2,2,0,1,0,0-4H5V3A2,2,0,0,0,1,3V21a2,2,0,0,0,2,2H21m0,1H3a3,3,0,0,1-3-3V3A3,3,0,0,1,6,3V18H21a3,3,0,1,1,0,6Z"
              fill="#afb4c1"
            ></path>
          </g>
          <g
            fill="#fff"
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="1"
            data-control="br"
            data-target="imageShape"
            class="shape-box-control box-control"
            style="cursor: se-resize"
            :style="boxControlsStyle(2)"
            @mousedown="boxControlsDown($event, 2)"
          >
            <path
              d="M20.5,0H2.5A2.5,2.5,0,0,0,0,2.5v18a2.5,2.5,0,0,0,5,0V5H20.5a2.5,2.5,0,1,0,0-5Z"
              transform="translate(0.5 0.5)"
              fill="#fff"
            ></path>
            <path
              d="M21,1a2,2,0,1,1,0,4H5V21a2,2,0,0,1-4,0V3A2,2,0,0,1,3,1H21m0-1H3A3,3,0,0,0,0,3V21a3,3,0,0,0,6,0V6H21a3,3,0,1,0,0-6Z"
              transform="translate(0 0)"
              fill="#afb4c1"
            ></path>
          </g>
          <g
            transform="translate(-2.5 160.95761084470345)"
            fill="#fff"
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="1"
            data-control="bl"
            data-target="imageShape"
            class="shape-box-control box-control"
            style="cursor: sw-resize"
            :style="boxControlsStyle(3)"
            @mousedown="boxControlsDown($event, 3)"
          >
            <path
              d="M20.5,23H2.5A2.5,2.5,0,0,1,0,20.5V2.5a2.5,2.5,0,0,1,5,0V18H20.5a2.5,2.5,0,1,1,0,5Z"
              transform="translate(0.5 0.5)"
              fill="#fff"
            ></path>
            <path
              d="M21,23a2,2,0,1,0,0-4H5V3A2,2,0,0,0,1,3V21a2,2,0,0,0,2,2H21m0,1H3a3,3,0,0,1-3-3V3A3,3,0,0,1,6,3V18H21a3,3,0,1,1,0,6Z"
              transform="translate(0 0)"
              fill="#afb4c1"
            ></path>
          </g>
          <g
            fill="#fff"
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="1"
            data-control="mt"
            data-target="imageShape"
            class="shape-box-control box-control"
            style="cursor: n-resize"
            :style="boxControlsStyle(4)"
            @mousedown="boxControlsDown($event, 4)"
          >
            <rect width="5" height="14" rx="2.5" stroke="none"></rect>
            <rect
              x="0.5"
              y="0.5"
              width="4"
              height="13"
              rx="2"
              fill="transparent"
            ></rect>
          </g>
          <g
            fill="#fff"
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="1"
            data-control="mr"
            data-target="imageShape"
            class="shape-box-control box-control"
            style="cursor: e-resize"
            :style="boxControlsStyle(5)"
            @mousedown="boxControlsDown($event, 5)"
          >
            <rect width="5" height="14" rx="2.5" stroke="none"></rect>
            <rect
              x="0.5"
              y="0.5"
              width="4"
              height="13"
              rx="2"
              fill="transparent"
            ></rect>
          </g>
          <g
            fill="#fff"
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="1"
            data-control="mb"
            data-target="imageShape"
            class="shape-box-control box-control"
            style="cursor: s-resize"
            :style="boxControlsStyle(6)"
            @mousedown="boxControlsDown($event, 6)"
          >
            <rect width="5" height="14" rx="2.5" stroke="none"></rect>
            <rect
              x="0.5"
              y="0.5"
              width="4"
              height="13"
              rx="2"
              fill="transparent"
            ></rect>
          </g>
          <g
            fill="#fff"
            stroke-linecap="round"
            stroke-linejoin="round"
            stroke-width="1"
            data-control="ml"
            data-target="imageShape"
            class="shape-box-control box-control"
            style="cursor: w-resize"
            :style="boxControlsStyle(7)"
            @mousedown="boxControlsDown($event, 7)"
          >
            <rect width="5" height="14" rx="2.5" stroke="none"></rect>
            <rect
              x="0.5"
              y="0.5"
              width="4"
              height="13"
              rx="2"
              fill="transparent"
            ></rect>
          </g>
        </svg>
      </div>
      <div
        class="imageBox"
        @mousedown="shapeMousedown"
        :style="imageBoxStyle"
        v-if="isEdit"
      >
        <div class="mask"></div>
        <div style="height: 100%">
          <svg
            xmlns="http://www.w3.org/2000/svg"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            width="100%"
            height="100%"
            style="position: static; transform-origin: center"
            transform=""
          >
            <g transform="scale(1 1)">
              <image
                xmlns:xlink="http://www.w3.org/1999/xlink"
                :xlink:href="imgLink"
                width="380"
                height="300"
              ></image>
            </g>
          </svg>
        </div>
      </div>
    </div>

    <div class="need-loading" v-if="masterMap">
      <div
        class="eleChild"
        style="
          position: absolute;
          opacity: 1;
          z-index: 1;
          transform-origin: left top;
          transform: rotate(0deg) skew(0deg, 0deg);
          width: 380px;
          height: 300px;
        "
      >
        <svg
          xmlns="http://www.w3.org/2000/svg"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          version="1.1"
          width="380"
          height="300"
          viewBox="0 0 380 300"
          xml:space="preserve"
          preserveAspectRatio="none"
          overflow="visible"
        >
          <g transform="translate( )">
            <defs>
              <mask id="maskPath_clip" v-if="false">
                <image
                  imageid=""
                  reswithworks="yes"
                  preserveAspectRatio="none"
                  xmlns:xlink="http://www.w3.org/1999/xlink"
                  :xlink:href="maskPathClip"
                  width="200"
                  height="180"
                  transform="scale(1 1)"
                  style="transform: translate(90px, 60px)"
                ></image>
              </mask>
            </defs>

            <g>
              <g mask="url(#maskPath_clip)">
                <image
                  imageid="AFoIABAEGAAg47fFmAYohJPv1AMw6gc4mwY"
                  crossorigin="anonymous"
                  xmlns:xlink="http://www.w3.org/1999/xlink"
                  :xlink:href="imgLink"
                  width="380"
                  height="300"
                  transform="translate(0px, 0px)"
                ></image>
              </g>
            </g>
          </g>
        </svg>
      </div>
    </div>

    <div class="list">
      <el-button @click="toClip" type="primary" v-if="!isEdit"
        >图片剪切</el-button
      >
      <el-button @click="restore" type="primary" v-if="!isEdit">还原</el-button>
      <el-button @click="save" type="primary" v-if="isEdit">保存</el-button>

      <div class="item" @click="clickItem(1)">
        <svg
          style="
            overflow: visible;
            width: 100px;
            height: 100px;
            background: rgb(160, 160, 160);
            padding: 10px;
          "
        >
          <image
            imageid=""
            reswithworks="yes"
            preserveAspectRatio="none"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTAiIGhlaWdodD0iNTUwIiB2aWV3Qm94PSIwIDAgNTUgNTUiPg0KICA8Y2lyY2xlIGlkPSJfMSIgZGF0YS1uYW1lPSIxIiBjeD0iMjcuNSIgY3k9IjI3LjUiIHI9IjI3LjUiIGZpbGw9IiNmZmYiLz4NCjwvc3ZnPg0K"
            width="100px"
            height="100px"
            transform="scale(1 1)"
          ></image>
        </svg>
      </div>
      <div class="item" @click="clickItem(2)">
        <svg
          style="
            overflow: visible;
            width: 100px;
            height: 100px;
            background: rgb(160, 160, 160);
            padding: 10px;
          "
        >
          <image
            imageid=""
            reswithworks="yes"
            preserveAspectRatio="none"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MDAiIGhlaWdodD0iNTAwIiB2aWV3Qm94PSIwIDAgNTAgNTAiPg0KICA8cmVjdCBpZD0iXzIiIGRhdGEtbmFtZT0iMiIgd2lkdGg9IjUwIiBoZWlnaHQ9IjUwIiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4NCg=="
            width="100px"
            height="100px"
            transform="scale(1 1)"
          ></image>
        </svg>
      </div>
      <div class="item" @click="clickItem(3)">
        <svg
          style="
            overflow: visible;
            width: 100px;
            height: 100px;
            background: rgb(160, 160, 160);
            padding: 10px;
          "
        >
          <image
            imageid=""
            reswithworks="yes"
            preserveAspectRatio="none"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MDAiIGhlaWdodD0iNTAwIiB2aWV3Qm94PSIwIDAgNTAgNTAiPg0KICA8cmVjdCBpZD0iXzMiIGRhdGEtbmFtZT0iMyIgd2lkdGg9IjUwIiBoZWlnaHQ9IjUwIiByeD0iNS4xOTYiIGZpbGw9IiNmZmYiLz4NCjwvc3ZnPg0K"
            width="100px"
            height="100px"
            transform="scale(1 1)"
          ></image>
        </svg>
      </div>
      <div class="item" @click="clickItem(4)">
        <svg
          style="
            overflow: visible;
            width: 100px;
            height: 100px;
            background: rgb(160, 160, 160);
            padding: 10px;
          "
        >
          <image
            imageid=""
            reswithworks="yes"
            preserveAspectRatio="none"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MzYuOTMiIGhlaWdodD0iNDcyLjc4IiB2aWV3Qm94PSIwIDAgNTMuNjkzIDQ3LjI3OCI+DQogIDxwYXRoIGlkPSJfNCIgZGF0YS1uYW1lPSI0IiBkPSJNMzIuNzE4LDE0LjE4OSw4LjgxMSw1NS42QTIuOTM0LDIuOTM0LDAsMCwwLDExLjM1Miw2MEg1OS4xNjdhMi45MzQsMi45MzQsMCwwLDAsMi41NDEtNC40TDM3LjgsMTQuMTg5QTIuOTM1LDIuOTM1LDAsMCwwLDMyLjcxOCwxNC4xODlaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtOC40MTMgLTEyLjcyMikiIGZpbGw9IiNmZmYiLz4NCjwvc3ZnPg0K"
            width="100px"
            height="100px"
            transform="scale(1 1)"
          ></image>
        </svg>
      </div>
      <div class="item" @click="clickItem(5)">
        <svg
          xmlns="http://www.w3.org/2000/svg"
          style="
            overflow: visible;
            width: 100px;
            height: 100px;
            background: rgb(160, 160, 160);
            padding: 10px;
          "
        >
          <image
            reswithworks="yes"
            preserveAspectRatio="none"
            xmlns:xlink="http://www.w3.org/1999/xlink"
            xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NTcuNSIgaGVpZ2h0PSI1MzQuMTIiIHZpZXdCb3g9IjAgMCA1NS43NSA1My40MTIiPg0KICA8cGF0aCBpZD0iXzEzIiBkYXRhLW5hbWU9IjEzIiBkPSJNMzguMzk0LDExLjIxNiw0My45MjksMjIuNDNBMy45NzQsMy45NzQsMCwwLDAsNDYuOTIxLDI0LjZMNTkuMywyNi40YTMuOTc1LDMuOTc1LDAsMCwxLDIuMiw2Ljc4bC04Ljk1NSw4LjcyOUEzLjk3NCwzLjk3NCwwLDAsMCw1MS40LDQ1LjQzbDIuMTE0LDEyLjMyNmEzLjk3NSwzLjk3NSwwLDAsMS01Ljc2OCw0LjE5bC0xMS4wNjktNS44MmEzLjk3OSwzLjk3OSwwLDAsMC0zLjcsMGwtMTEuMDY5LDUuODJhMy45NzUsMy45NzUsMCwwLDEtNS43NjgtNC4xOUwxOC4yNTgsNDUuNDNhMy45NzUsMy45NzUsMCwwLDAtMS4xNDQtMy41MThMOC4xNTksMzMuMTgzYTMuOTc1LDMuOTc1LDAsMCwxLDIuMi02Ljc4bDEyLjM3Ni0xLjhhMy45NzYsMy45NzYsMCwwLDAsMi45OTMtMi4xNzRsNS41MzQtMTEuMjE0QTMuOTc1LDMuOTc1LDAsMCwxLDM4LjM5NCwxMS4yMTZaIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNi45NTQgLTkpIiBmaWxsPSIjZmZmIi8+DQo8L3N2Zz4NCg=="
            width="100px"
            height="100px"
            transform="scale(1 1)"
            fill="rgba(60, 60, 60)"
          ></image>

          <div
            class="clip-shape active"
            style="background-position: 0px -352px"
          ></div>

          <div
            class="clip-shape active"
            style="background-position: 0px -352px"
          ></div>
        </svg>
      </div>
      <el-input v-model="imgLink"></el-input>

      <!-- <div class="item" @click="clickItem(6)">
        <svg
          style="
            overflow: visible;
            width: 100px;
            height: 100px;
            fill: rgba(0, 0, 0, 0);
            padding: 10px;
          "
        ></svg>
      </div> -->
    </div>
  </div>
</template>

转载请注明出处或者链接地址:https://www.qianduange.cn//article/8495.html
标签
评论
会员中心 联系我 留言建议 回顶部
复制成功!