封装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>
相关推荐
李宥小哥16 小时前
SQLite05-常用函数
java·开发语言·jvm
皮卡狮16 小时前
C++面向对象编程的三大核心特性之一:多态
开发语言·c++
zhangx1234_16 小时前
java list介绍
java·开发语言·list
Java面试题总结16 小时前
Go运行时系统解析: runtime包深度指南
开发语言·后端·golang
lly20240616 小时前
jEasyUI 树形菜单加载父/子节点详解
开发语言
lsx20240616 小时前
JSP 自动刷新技术详解
开发语言
我命由我1234516 小时前
Element Plus - Cascader 观察记录(基本使用、动态加载、动态加载下的异常环境)
开发语言·前端·javascript·vue.js·typescript·html5·js
2401_9001515416 小时前
自定义异常类设计
开发语言·c++·算法
qq_5703985716 小时前
vue总结
前端·javascript·vue.js
李斯啦果16 小时前
【C语言】统计对称素数
c语言·开发语言