src_js/iconolab-bundle/src/components/editor/ShapeRect.vue
changeset 320 81945eedc63f
child 323 55c024fc7c60
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src_js/iconolab-bundle/src/components/editor/ShapeRect.vue	Wed Feb 15 16:42:06 2017 +0100
@@ -0,0 +1,208 @@
+<template>
+<g ref="g" v-bind:transform="transform">
+    <rect
+        ref="shape"
+        x="0" y="0"
+        v-bind:width="width" v-bind:height="height"
+        fill="#bdc3c7"
+        stroke="#000"
+        v-bind:stroke-width="handlerSize / 5"
+        v-bind:stroke-dasharray="(handlerSize / 5) + ',' + (handlerSize / 5)"
+        style="opacity: 0.6;"
+        class="shape"></rect>
+    <rect
+        ref="topLeft"
+        v-show="width > 0 &amp;&amp; height > 0"
+        v-bind:x="(handlerSize / 2) * -1" v-bind:y="(handlerSize / 2) * -1"
+        v-bind:width="handlerSize" v-bind:height="handlerSize"
+        fill="#ffffff"
+        stroke="#000000" v-bind:stroke-width="handlerSize / 5" class="handler-rect handler-top-left"></rect>
+    <rect
+        ref="bottomRight"
+        v-show="width > 0 &amp;&amp; height > 0"
+        v-bind:x="width - (handlerSize / 2)" v-bind:y="height - (handlerSize / 2)"
+        v-bind:width="handlerSize" v-bind:height="handlerSize"
+        fill="#ffffff"
+        stroke="#000000" v-bind:stroke-width="handlerSize / 5" class="handler-rect handler-bottom-right"></rect>
+</g>
+</template>
+
+<script>
+
+    import Snap from 'snapsvg'
+    import tooltip from './mixins/tooltip'
+    import save from './mixins/save'
+
+    export default {
+        mixins: [ tooltip, save ],
+        props: [
+            'paper',
+            'original-annotation',
+        ],
+        data() {
+            return {
+                transform: 'translate(0, 0)',
+                isResizing: false,
+                x: 0, y: 0,
+                width: 0, height: 0,
+                handlerSize: 60
+            }
+        },
+        mounted() {
+
+            var self = this;
+
+            var groupEvents = {
+                onMove: function(dx, dy) {
+                    if (self.isResizing) { return; }
+
+                    var snapInvMatrix = this.transform().diffMatrix.invert();
+                    var tdx = snapInvMatrix.x(dx, dy);
+                    var tdy = snapInvMatrix.y(dx, dy);
+
+                    var transformValue = this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [tdx, tdy];
+                    this.transform(transformValue);
+                },
+                onStart: function() {
+                    this.data('origTransform', this.transform().local);
+                    self.$emit('drag:start');
+                },
+                onEnd: () => self.$emit('drag:end')
+            }
+
+            var g = new Snap(this.$refs.g);
+            g.drag(groupEvents.onMove, groupEvents.onStart, groupEvents.onEnd);
+        },
+        watch: {
+            x: function (val, oldVal) {
+                this.transform = 'translate(' + this.x + ', ' + this.y + ')';
+            },
+            y: function (val, oldVal) {
+                this.transform = 'translate(' + this.x + ', ' + this.y + ')';
+            },
+        },
+        methods: {
+
+            clear: function() {
+
+                var shape = new Snap(this.$refs.shape);
+                var topLeftHandler = new Snap(this.$refs.topLeft);
+                var bottomRightHandler = new Snap(this.$refs.bottomRight);
+
+                shape.node.removeAttribute('transform');
+                topLeftHandler.node.removeAttribute('transform');
+                bottomRightHandler.node.removeAttribute('transform');
+
+                this.destroyTooltip();
+
+                Object.assign(this, {
+                    transform: 'translate(0, 0)',
+                    x: 0, y: 0,
+                    width: 0, height: 0,
+                });
+            },
+
+            getTooltipTarget: function() {
+                return this.$refs.shape;
+            },
+
+            addResizeHandlers: function() {
+
+                var self = this;
+
+                var shape = new Snap(this.$refs.shape);
+                var topLeftHandler = new Snap(this.$refs.topLeft);
+                var bottomRightHandler = new Snap(this.$refs.bottomRight);
+
+                var handlerEvents = {
+                    onMove: function(dx, dy) {
+
+                        var snapInvMatrix = this.transform().diffMatrix.invert();
+                        snapInvMatrix.e = snapInvMatrix.f = 0;
+                        var tdx = snapInvMatrix.x(dx, dy);
+                        var tdy = snapInvMatrix.y(dx, dy);
+
+                        this.transform( "t" + [ tdx, tdy ] + this.data("origTransform") );
+
+                        // Update shape
+
+                        var newWidth = bottomRightHandler.getBBox().x - topLeftHandler.getBBox().x;
+                        var newHeight = bottomRightHandler.getBBox().y - topLeftHandler.getBBox().y;
+
+                        var attr = {
+                            width: newWidth,
+                            height: newHeight
+                        };
+                        if (this === topLeftHandler) {
+                            attr.transform = shape.data('origTransform') + (shape.data('origTransform') ? "T" : "t") + [tdx, tdy];
+                        }
+
+                        shape.attr(attr);
+                    },
+                    onStart: function() {
+                        self.isResizing = true;
+                        shape.data("origTransform", shape.transform().local);
+                        this.data('origTransform', this.transform().local);
+                    },
+                    onEnd: function() {
+                        self.isResizing = false;
+                    }
+                }
+
+                topLeftHandler.drag(handlerEvents.onMove, handlerEvents.onStart, handlerEvents.onEnd);
+                bottomRightHandler.drag(handlerEvents.onMove, handlerEvents.onStart, handlerEvents.onEnd);
+            },
+
+            fromSVGPath: function(pathString, imageWidth, imageHeight) {
+                var bBox = Snap.path.getBBox(pathString);
+
+                Object.assign(this, {
+                    x: bBox.x, y: bBox.y,
+                    width: bBox.width, height: bBox.height
+                });
+
+                setTimeout(() => {
+                    this.addResizeHandlers();
+                    this.addTooltip();
+                }, 50);
+            },
+
+            toSVGPath: function() {
+
+                var shape = new Snap(this.$refs.shape);
+
+                var shapePath;
+                var bBox = shape.getBBox();
+                var transform = shape.transform();
+
+                if (!transform.global.length) {
+                    shapePath = shape.getBBox().path;
+                } else {
+                    var shapeX = shape.node.getAttribute('x');
+                    var shapeY = shape.node.getAttribute('y');
+                    var transformMatrix = transform.totalMatrix;
+                    var fakeShape = this.paper.rect(transformMatrix.x(shapeX, shapeY),transformMatrix.y(shapeX, shapeY), bBox.width, bBox.height);
+                    shapePath = fakeShape.getBBox().path;
+                    fakeShape.remove();
+                }
+
+                var path = Snap.path.toAbsolute(shapePath).toString();
+
+                return this.$parent.normalizePath(path) + ';RECT';
+            }
+        }
+    }
+
+</script>
+
+<style scoped>
+.shape:hover {
+    cursor: move;
+}
+.handler-top-left:hover {
+    cursor: nw-resize;
+}
+.handler-bottom-right:hover {
+    cursor: se-resize;
+}
+</style>