|
1 <template> |
|
2 <div class="wrapper"> |
|
3 <svg ref="svg" v-bind:width="thumbnailWidth" v-bind:height="thumbnailHeight"> |
|
4 <image xmlns:xlink="http://www.w3.org/1999/xlink" |
|
5 x="0" y="0" |
|
6 v-bind:width="thumbnailWidth" v-bind:height="thumbnailHeight" |
|
7 v-bind:xlink:href="image"></image> |
|
8 <rect ref="handler" |
|
9 class="move-handler" |
|
10 v-bind:x="x" v-bind:y="y" |
|
11 v-bind:width="width" v-bind:height="height" |
|
12 style="fill: black; opacity: 0.4"></rect> |
|
13 </svg> |
|
14 </div> |
|
15 </template> |
|
16 |
|
17 <script> |
|
18 |
|
19 import Snap from 'snapsvg' |
|
20 |
|
21 export default { |
|
22 props: [ |
|
23 'image', |
|
24 'viewport', |
|
25 'viewBox', |
|
26 'imageWidth', |
|
27 'imageHeight', |
|
28 ], |
|
29 data() { |
|
30 return { |
|
31 thumbnailWidth: 0, |
|
32 thumbnailHeight: 0, |
|
33 loaded: false |
|
34 } |
|
35 }, |
|
36 computed: { |
|
37 x: function() { |
|
38 return this.viewBox[0] * this.getRatioX(); |
|
39 }, |
|
40 y: function() { |
|
41 return this.viewBox[1] * this.getRatioY(); |
|
42 }, |
|
43 width: function() { |
|
44 return this.viewBox[2] * this.getRatioX(); |
|
45 }, |
|
46 height: function() { |
|
47 return this.viewBox[3] * this.getRatioY(); |
|
48 } |
|
49 }, |
|
50 methods: { |
|
51 reset: function() { |
|
52 var handler = new Snap(this.$refs.handler); |
|
53 handler.node.removeAttribute('transform'); |
|
54 }, |
|
55 getRatioX: function() { |
|
56 if (this.imageWidth === 0) { return 0; } |
|
57 |
|
58 return this.thumbnailWidth / this.imageWidth; |
|
59 }, |
|
60 getRatioY: function() { |
|
61 if (this.imageHeight === 0) { return 0; } |
|
62 |
|
63 return this.thumbnailHeight / this.imageHeight; |
|
64 } |
|
65 }, |
|
66 mounted() { |
|
67 |
|
68 var svg = new Snap(this.$refs.svg); |
|
69 var handler = new Snap(this.$refs.handler); |
|
70 |
|
71 var img = new Image(); |
|
72 img.onload = (e) => { |
|
73 |
|
74 var self = this; |
|
75 |
|
76 svg.attr({ |
|
77 viewBox: [0, 0, img.width, img.height] |
|
78 }); |
|
79 |
|
80 Object.assign(this, { |
|
81 thumbnailWidth: img.width, |
|
82 thumbnailHeight: img.height, |
|
83 loaded: true |
|
84 }); |
|
85 |
|
86 var events = { |
|
87 onMove: function (dx, dy, x, y) { |
|
88 |
|
89 var snapInvMatrix = this.transform().diffMatrix.invert(); |
|
90 snapInvMatrix.e = snapInvMatrix.f = 0; |
|
91 var tdx = snapInvMatrix.x(dx, dy); |
|
92 var tdy = snapInvMatrix.y(dx, dy); |
|
93 |
|
94 var transformValue = this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [tdx, tdy]; |
|
95 this.transform(transformValue); |
|
96 |
|
97 self.$emit('change', { |
|
98 x: this.getBBox().x * (self.imageWidth / self.thumbnailWidth), |
|
99 y: this.getBBox().y * (self.imageHeight / self.thumbnailHeight), |
|
100 }); |
|
101 |
|
102 }, |
|
103 onStart: function () { |
|
104 this.data('origTransform', this.transform().local); |
|
105 self.$emit('dragstart'); |
|
106 }, |
|
107 onEnd: function () { |
|
108 self.$emit('dragend'); |
|
109 } |
|
110 } |
|
111 |
|
112 handler.drag(events.onMove, events.onStart, events.onEnd); |
|
113 } |
|
114 |
|
115 img.src = this.image; |
|
116 } |
|
117 } |
|
118 |
|
119 </script> |
|
120 |
|
121 <style scoped> |
|
122 .wrapper { |
|
123 box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); |
|
124 } |
|
125 .wrapper svg { |
|
126 border: 2px solid black; |
|
127 border-radius: 4px; |
|
128 } |
|
129 .move-handler { |
|
130 cursor: -moz-grab; |
|
131 cursor: -webkit-grab; |
|
132 cursor: grab; |
|
133 } |
|
134 </style> |