封装svg图片展示及操作组件——svgComponent——js技能提升

template部分

js 复制代码
<template>
  <div class="canvas-wrapper" ref="canvasWrapper">
    <svg
        :viewBox="computedViewBox"
        ref="svgCanvas"
        xmlns="http://www.w3.org/2000/svg"
        xmlns:xlink="http://www.w3.org/1999/xlink"
        class="schematic-svg"
        @mousedown="startDrag"
        @mousemove="onDrag"
        @mouseup="endDrag"
        @wheel="onScroll"
        v-html="svgContent"
        preserveAspectRatio="xMinYMin meet"
    >
    </svg>
  </div>
</template>


this.klFile = "data:image/svg+xml;base64," + data[0].kl_svg
<svg-component v-if="klFile !== null" :svg-base64="klFile" view-box="0 0 2000 2000"></svg-component>

script部分

js 复制代码
<script>
export default {
  name:'SvgComponent',
  props: {
    svgBase64: {
      type: String,
      required: true
    },
    viewBox: {
      type: String,
      required: true
    },
  },
  data() {
    return {
      computedViewBox: this.viewBox, // 用于动态修改的 viewBox
      dragging: false,
      startX: 0,
      startY: 0,
      viewBoxX: 0,
      viewBoxY: 0,
      svgContent: "", // 存储解码后的 SVG 内容
    };
  },
  watch: {
    svgBase64() {
      // 响应 props 变化并重新渲染 SVG
      this.decodeSvgBase64();
    },
  },
  mounted() {
    this.decodeSvgBase64();
  },
  methods: {
    decodeSvgBase64() {
      // 解码 Base64 数据
      // 检查并移除可能存在的 Base64 数据头
      let base64String = this.svgBase64;
      const prefix = "data:image/svg+xml;base64,";

      if (base64String.startsWith(prefix)) {
        base64String = base64String.replace(prefix, "");
      }

      // 尝试解码 Base64 数据
      const decodedData = atob(base64String);

      this.svgContent = decodedData; // 将解码后的内容赋值给 svgContent
    },
    startDrag(event) {
      this.dragging = true;
      this.startX = event.clientX;
      this.startY = event.clientY;
    },
    onDrag(event) {
      if (this.dragging) {
        const dx = this.startX - event.clientX;
        const dy = this.startY - event.clientY;
        this.viewBoxX += dx;
        this.viewBoxY += dy;
        this.updateViewBox();
        this.startX = event.clientX;
        this.startY = event.clientY;
      }
    },
    endDrag() {
      this.dragging = false;
    },
    onScroll(event) {
      event.preventDefault();
      const zoomAmount = 1.1;
      const [x, y, w, h] = this.computedViewBox.split(" ").map(Number);

      // Zoom in or out
      if (event.deltaY < 0) {
        // Zoom in
        this.computedViewBox = `${x + w * (1 - 1 / zoomAmount) / 2} ${y + h * (1 - 1 / zoomAmount) / 2} ${w / zoomAmount} ${h / zoomAmount}`;
      } else {
        // Zoom out
        this.computedViewBox = `${x - w * (zoomAmount - 1) / 2} ${y - h * (zoomAmount - 1) / 2} ${w * zoomAmount} ${h * zoomAmount}`;
      }
    },
    updateViewBox() {
      const [x, y, w, h] = this.viewBox.split(" ").map(Number);
      this.computedViewBox = `${this.viewBoxX} ${this.viewBoxY} ${w} ${h}`;
    }
  },
};
</script>

css部分

css 复制代码
<style scoped>
.canvas-wrapper {
  border-radius: 10px;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  overflow: hidden;
}

.schematic-svg {
  width: 100%;
  height: 100%;
}
</style>
相关推荐
执笔论英雄3 小时前
Slime异步原理(单例设计模式)4
开发语言·python·设计模式
e***74955 小时前
Modbus报文详解
服务器·开发语言·php
lly2024065 小时前
ASP 发送电子邮件详解
开发语言
小徐敲java5 小时前
python使用s7协议与plc进行数据通讯(HslCommunication模拟)
开发语言·python
likuolei5 小时前
XSL-FO 软件
java·开发语言·前端·数据库
6***37945 小时前
PHP在电商中的BigCommerce
开发语言·php
正一品程序员5 小时前
vue项目引入GoogleMap API进行网格区域圈选
前端·javascript·vue.js
Dev7z5 小时前
基于Matlab的多制式条形码识别与图形界面(GUI)系统设计与实现
开发语言·matlab
合作小小程序员小小店5 小时前
桌面开发,在线%信息管理%系统,基于vs2022,c#,winform,sql server数据。
开发语言·数据库·sql·microsoft·c#
FL16238631295 小时前
ONNX RuntimeC++ 静态库下载安装和使用教程
开发语言·c++