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

打印 上一主题 下一主题

主题 1016|帖子 1016|积分 3048


template部分

  1. <template>
  2.   <div class="canvas-wrapper" ref="canvasWrapper">
  3.     <svg
  4.         :viewBox="computedViewBox"
  5.         ref="svgCanvas"
  6.         xmlns="http://www.w3.org/2000/svg"
  7.         xmlns:xlink="http://www.w3.org/1999/xlink"
  8.         class="schematic-svg"
  9.         @mousedown="startDrag"
  10.         @mousemove="onDrag"
  11.         @mouseup="endDrag"
  12.         @wheel="onScroll"
  13.         v-html="svgContent"
  14.         preserveAspectRatio="xMinYMin meet"
  15.     >
  16.     </svg>
  17.   </div>
  18. </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部分

  1. <script>
  2. export default {
  3.   name:'SvgComponent',
  4.   props: {
  5.     svgBase64: {
  6.       type: String,
  7.       required: true
  8.     },
  9.     viewBox: {
  10.       type: String,
  11.       required: true
  12.     },
  13.   },
  14.   data() {
  15.     return {
  16.       computedViewBox: this.viewBox, // 用于动态修改的 viewBox
  17.       dragging: false,
  18.       startX: 0,
  19.       startY: 0,
  20.       viewBoxX: 0,
  21.       viewBoxY: 0,
  22.       svgContent: "", // 存储解码后的 SVG 内容
  23.     };
  24.   },
  25.   watch: {
  26.     svgBase64() {
  27.       // 响应 props 变化并重新渲染 SVG
  28.       this.decodeSvgBase64();
  29.     },
  30.   },
  31.   mounted() {
  32.     this.decodeSvgBase64();
  33.   },
  34.   methods: {
  35.     decodeSvgBase64() {
  36.       // 解码 Base64 数据
  37.       // 检查并移除可能存在的 Base64 数据头
  38.       let base64String = this.svgBase64;
  39.       const prefix = "data:image/svg+xml;base64,";
  40.       if (base64String.startsWith(prefix)) {
  41.         base64String = base64String.replace(prefix, "");
  42.       }
  43.       // 尝试解码 Base64 数据
  44.       const decodedData = atob(base64String);
  45.       this.svgContent = decodedData; // 将解码后的内容赋值给 svgContent
  46.     },
  47.     startDrag(event) {
  48.       this.dragging = true;
  49.       this.startX = event.clientX;
  50.       this.startY = event.clientY;
  51.     },
  52.     onDrag(event) {
  53.       if (this.dragging) {
  54.         const dx = this.startX - event.clientX;
  55.         const dy = this.startY - event.clientY;
  56.         this.viewBoxX += dx;
  57.         this.viewBoxY += dy;
  58.         this.updateViewBox();
  59.         this.startX = event.clientX;
  60.         this.startY = event.clientY;
  61.       }
  62.     },
  63.     endDrag() {
  64.       this.dragging = false;
  65.     },
  66.     onScroll(event) {
  67.       event.preventDefault();
  68.       const zoomAmount = 1.1;
  69.       const [x, y, w, h] = this.computedViewBox.split(" ").map(Number);
  70.       // Zoom in or out
  71.       if (event.deltaY < 0) {
  72.         // Zoom in
  73.         this.computedViewBox = `${x + w * (1 - 1 / zoomAmount) / 2} ${y + h * (1 - 1 / zoomAmount) / 2} ${w / zoomAmount} ${h / zoomAmount}`;
  74.       } else {
  75.         // Zoom out
  76.         this.computedViewBox = `${x - w * (zoomAmount - 1) / 2} ${y - h * (zoomAmount - 1) / 2} ${w * zoomAmount} ${h * zoomAmount}`;
  77.       }
  78.     },
  79.     updateViewBox() {
  80.       const [x, y, w, h] = this.viewBox.split(" ").map(Number);
  81.       this.computedViewBox = `${this.viewBoxX} ${this.viewBoxY} ${w} ${h}`;
  82.     }
  83.   },
  84. };
  85. </script>
复制代码
css部分

  1. <style scoped>
  2. .canvas-wrapper {
  3.   border-radius: 10px;
  4.   box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  5.   overflow: hidden;
  6. }
  7. .schematic-svg {
  8.   width: 100%;
  9.   height: 100%;
  10. }
  11. </style>
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

没腿的鸟

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表