封装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>
相关推荐
kimnoic6 小时前
Python数据库学习心得:SQLite、MySQL、PostgreSQL优缺点
开发语言·python
必须得开心呀7 小时前
python编写带界面的软件,需要安装哪些插件
开发语言·python
刘发财8 小时前
前端如何生成10000页PDF文件?
前端·javascript·开源
A接拉起0078 小时前
2026 年 JavaScript 开发者需要了解的知识
前端·javascript·后端
_馒头8 小时前
pixiJs游戏开发实践 - 跳棋小游戏
javascript·vue.js
沫璃染墨9 小时前
《Qt从零入门系列(十三):QSS样式表详解——从选择器与层叠规则到控件美化实战》
开发语言·css·c++·qt·ui·qt6.3·qss
三*一9 小时前
优化修整算法
前端·javascript·算法
达子6669 小时前
RUST 图解 第 3 章:通用编程概念(Common Programming Concepts)
开发语言·算法·rust
道尔柯南10 小时前
C++ 面向对象编程入门:类和对象(上)
开发语言·c++·算法
楠楠子呀10 小时前
英语、西语、阿语客户各开一个口:多语言获客的分流方案
开发语言·javascript·ecmascript·跨境电商·whatsapp·营销工具