template部分
- <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部分
- <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部分
- <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>
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |