Skip to content

Instantly share code, notes, and snippets.

@DCdafan
Forked from syrxw/svg.vue
Created November 22, 2018 08:27
Show Gist options
  • Save DCdafan/67c2bc70f389ee4f7d7041c0970f3f85 to your computer and use it in GitHub Desktop.
Save DCdafan/67c2bc70f389ee4f7d7041c0970f3f85 to your computer and use it in GitHub Desktop.
vue+svg 实现缩放
<template>
<svg width="800px" height="800px" version="1.1"
xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 800">
<g class="port_output" style="pointer-events: all;">
<rect fill="#fff" stroke-width="1.5"
:x="selectedItem.x" :y="selectedItem.y"
:width="selectedItem.width" :height="selectedItem.height"
:transform="transform"
style="vector-effect: non-scaling-stroke"
class="port" @click="pointClick" stroke-dasharray="none" stroke="#000"></rect>
<!--<rect x="200" y="200" width="100" height="100" class="port" @click="pointClick"></rect>-->
<!--<rect x="400" y="200" width="100" transform="scale(1.5,1.5)" height="100" class="port" @click="pointClick"></rect>-->
</g>
<path :d="item" stroke="red" stroke-width="2" fill="none" v-for="(item,index) in listData"
:key="index"></path>
<path :d="pathPosition" stroke="blue" stroke-width="1" fill="none"></path>
<g class="selected">
<circle :cx="itemPosition.cw.value.x" :cy="itemPosition.cw.value.y" r="2.5"
stroke="blue" fill="white"></circle>
<circle :cx="itemPosition.ce.value.x" :cy="itemPosition.ce.value.y" r="2.5"
stroke="blue" fill="white"></circle>
<rect style="cursor:nw-resize"
:x="itemPosition.nw.value.x - 2.5" :y="itemPosition.nw.value.y - 2.5"
stroke="blue" fill="white"
width="5" height="5"
class="port"
@mousedown="shapeScale($event,type='nw')"
></rect>
<rect style="cursor:ne-resize"
:x="itemPosition.ne.value.x - 2.5" :y="itemPosition.ne.value.y - 2.5"
stroke="blue" fill="white"
width="5" height="5"
class="port"
@mousedown="shapeScale($event,type='ne')"
></rect>
<rect style="cursor:sw-resize"
:x="itemPosition.sw.value.x - 2.5" :y="itemPosition.sw.value.y - 2.5"
stroke="blue" fill="white"
width="5" height="5"
class="port"
@mousedown="shapeScale($event,type='sw')"
></rect>
<rect style="cursor:se-resize"
:x="itemPosition.se.value.x - 2.5" :y="itemPosition.se.value.y - 2.5"
stroke="blue" fill="white"
width="5" height="5"
class="port"
@mousedown="shapeScale($event,type='se')"
></rect>
<rect :x="itemPosition.c.value.x - 2.5" :y="itemPosition.c.value.y - 2.5"
stroke="blue" fill="white"
width="5" height="5"
class="port"
@mousedown="shapeScale"
></rect>
</g>
</svg>
</template>
<script>
import * as d3 from 'd3';
export default {
name: 'home',
data() {
return {
listData: {
'001': 'M1,2L30,40',
},
clickPoint: {
x: '',
y: ''
},
itemPosition: {
nw: {
name: '',
value: {
x: '',
y: ''
}
},
sw: {
name: '',
value: {
x: '',
y: ''
}
},
ne: {
name: '',
value: {
x: '',
y: ''
}
},
se: {
name: '',
value: {
x: '',
y: ''
}
},
cw: {
name: '',
value: {
x: '0',
y: '0'
}
},
ce: {
name: '',
value: {
x: '0',
y: '0'
}
},
c: {
name: '',
value: {
x: '',
y: ''
}
}
},
pathPosition: "",
selectedItem: {
target:null,
width:150,
height:150,
x:500,
y:100,
translateX:'',
translateY:''
},
scaleValue: {
x: 1,
y: 1
},
transform:''
}
},
computed: {
},
mounted() {
},
methods: {
pointClick(e) {
this.selectedItem.target = e.target;
this.drawSelectPoint()
},
drawSelectPoint(){
const pos = this.selectedItem.target.getBoundingClientRect()
// console.log(this.selectedItem.getBBox())
//左上角
this.itemPosition.nw = {
name: 'nw',
value: {
x: pos.left,
y: pos.top
}
}
//左下角
this.itemPosition.sw = {
name: 'sw',
value: {
x: pos.left,
y: pos.top + pos.height
}
}
//右上角
this.itemPosition.ne = {
name: 'ne',
value: {
x: pos.left + pos.width,
y: pos.top
}
}
//右下角
this.itemPosition.se = {
name: 'se',
value: {
x: pos.left + pos.width,
y: pos.top + pos.height
}
}
//左中角
this.itemPosition.cw = {
name: 'cw',
value: {
x: pos.left,
y: pos.top + (pos.height / 2)
}
}
//右中角
this.itemPosition.ce = {
name: 'ce',
value: {
x: pos.left + pos.width,
y: pos.top + (pos.height / 2)
}
}
//中心点
this.itemPosition.c = {
name: 'c',
value: {
x: pos.left + (pos.width / 2),
y: pos.top + (pos.height / 2)
}
}
this.drawSelectLine()
},
drawSelectLine(){
const path = d3.path()
path.moveTo(this.itemPosition.nw.value.x, this.itemPosition.nw.value.y)
path.lineTo(this.itemPosition.ne.value.x, this.itemPosition.ne.value.y)
path.lineTo(this.itemPosition.se.value.x, this.itemPosition.se.value.y)
path.lineTo(this.itemPosition.sw.value.x, this.itemPosition.sw.value.y)
path.lineTo(this.itemPosition.nw.value.x, this.itemPosition.nw.value.y)
this.pathPosition = path.toString()
},
pointDown(e) {
this.clickPoint.x = e.offsetX
this.clickPoint.y = e.offsetY
document.onmousemove = (e) => {
this.drawLine(this.clickPoint.x, this.clickPoint.y, e.offsetX, e.offsetY, '002')
};
document.onmouseup = () => {
document.onmousemove = null;
document.onmouseup = null;
};
},
drawLine(x1, y1, x2, y2, id) {
const path = d3.path()
path.moveTo(x1, y1)
path.bezierCurveTo(x2, y1, x1, y2, x2, y2);
// path.lineTo(x2,y2)
this.$set(this.listData, id, path.toString())
console.log(this.listData)
},
shapeScale(e,type) {
const target = this.selectedItem.target.getBoundingClientRect()
this.selectedItem.width = target.width
this.selectedItem.height = target.height
if(type === 'nw'){
const tx = this.selectedItem.x + this.selectedItem.width
const ty = this.selectedItem.y + this.selectedItem.height
this.scaleFunc(e,tx,ty,()=>{
this.selectedItem.x = this.selectedItem.translateX - this.selectedItem.width
this.selectedItem.y = this.selectedItem.translateY - this.selectedItem.height
})
}
if(type === 'ne'){
const tx = this.selectedItem.x
const ty = this.selectedItem.y + this.selectedItem.height
this.scaleFunc(e,tx,ty,()=>{
this.selectedItem.x = this.selectedItem.translateX
this.selectedItem.y = this.selectedItem.translateY - this.selectedItem.height
})
}
if(type === 'sw'){
const tx = this.selectedItem.x + this.selectedItem.width
const ty = this.selectedItem.y
this.scaleFunc(e,tx,ty,()=>{
this.selectedItem.x = this.selectedItem.translateX - this.selectedItem.width
this.selectedItem.y = this.selectedItem.translateY
})
}
if(type === 'se'){
const tx = this.selectedItem.x
const ty = this.selectedItem.y
this.scaleFunc(e,tx,ty,()=>{})
}
},
scaleFunc(e,tx,ty,upcall){
this.selectedItem.translateX = tx
this.selectedItem.translateY = ty
const pos_x = e.clientX - this.selectedItem.translateX
const pos_y = e.clientY - this.selectedItem.translateY
document.onmousemove = (e) => {
const move_x = e.clientX - this.selectedItem.translateX
const move_y = e.clientY - this.selectedItem.translateY
this.scaleValue = {
x: move_x / pos_x,
y: move_y / pos_y
}
this.transform = `translate(${this.selectedItem.translateX},${this.selectedItem.translateY}) scale(${this.scaleValue.x},${this.scaleValue.y}) translate(-${this.selectedItem.translateX},-${this.selectedItem.translateY})`
this.drawSelectPoint()
};
document.onmouseup = () => {
document.onmousemove = null;
document.onmouseup = null;
this.selectedItem.width = this.selectedItem.width * this.scaleValue.x
this.selectedItem.height = this.selectedItem.height * this.scaleValue.y
this.transform = ''
upcall()
};
}
}
}
</script>
<style>
:not(svg), :not(foreignObject) > svg {
transform-origin: 0px 0px 0px;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment