Limit zoom handler to bounds.
authorAlexandre Segura <mex.zktk@gmail.com>
Tue, 14 Mar 2017 14:10:16 +0100
changeset 428 722d8e9e2f6e
parent 427 2a9ce7ec3a29
child 429 5dca2c00a4f8
Limit zoom handler to bounds.
src_js/iconolab-bundle/src/components/editor/ZoomThumbnail.vue
--- a/src_js/iconolab-bundle/src/components/editor/ZoomThumbnail.vue	Tue Mar 14 13:41:38 2017 +0100
+++ b/src_js/iconolab-bundle/src/components/editor/ZoomThumbnail.vue	Tue Mar 14 14:10:16 2017 +0100
@@ -18,6 +18,52 @@
 
     import Snap from 'snapsvg'
 
+    // See http://svg.dabbles.info/snaptut-drag-limit
+    Snap.plugin( function( Snap, Element, Paper, global ) {
+
+        Element.prototype.limitDrag = function( params ) {
+
+            var onMove = function(dx, dy) {
+                limitMoveDrag.apply(this, arguments);
+                params.onMove.apply(this, arguments);
+            }
+
+            this.data('minx', params.minx); this.data('miny', params.miny);
+            this.data('maxx', params.maxx); this.data('maxy', params.maxy);
+            this.data('x', params.x); this.data('y', params.y);
+            this.data('ibb', this.getBBox());
+            this.data('ot', this.transform().local);
+
+            this.drag(onMove, limitStartDrag);
+
+            return this;
+        };
+
+        function limitMoveDrag( dx, dy ) {
+            var tdx, tdy;
+            var sInvMatrix = this.transform().globalMatrix.invert();
+            sInvMatrix.e = sInvMatrix.f = 0;
+            tdx = sInvMatrix.x( dx,dy ); tdy = sInvMatrix.y( dx,dy );
+
+            this.data('x', +this.data('ox') + tdx);
+            this.data('y', +this.data('oy') + tdy);
+            if (this.data('x') > this.data('maxx') - this.data('ibb').width) {
+                this.data('x', this.data('maxx') - this.data('ibb').width)
+            };
+            if (this.data('y') > this.data('maxy') - this.data('ibb').height) {
+                this.data('y', this.data('maxy') - this.data('ibb').height)
+            };
+            if (this.data('x') < this.data('minx')) { this.data('x', this.data('minx')) };
+            if (this.data('y') < this.data('miny')) { this.data('y', this.data('miny')) };
+
+            this.transform( this.data('ot') + "t" + [ this.data('x'), this.data('y') ]);
+        };
+
+        function limitStartDrag( x, y, ev ) {
+            this.data('ox', this.data('x')); this.data('oy', this.data('y'));
+        };
+    });
+
     export default {
         props: [
             'image',
@@ -71,8 +117,6 @@
             var img = new Image();
             img.onload = (e) => {
 
-                var self = this;
-
                 svg.attr({
                     viewBox: [0, 0, img.width, img.height]
                 });
@@ -83,33 +127,19 @@
                     loaded: true
                 });
 
-                var events = {
-                    onMove: function (dx, dy, x, y) {
+                var self = this;
 
-                        var snapInvMatrix = this.transform().diffMatrix.invert();
-                        snapInvMatrix.e = snapInvMatrix.f = 0;
-                        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);
-
+                handler.limitDrag({
+                    x: 0, y: 0,
+                    minx: -(img.width / 2), miny: -(img.height / 2),
+                    maxx: (img.width / 2), maxy: (img.height / 2),
+                    onMove: function() {
                         self.$emit('change', {
                             x: this.getBBox().x * (self.imageWidth / self.thumbnailWidth),
                             y: this.getBBox().y * (self.imageHeight / self.thumbnailHeight),
                         });
-
-                    },
-                    onStart: function () {
-                        this.data('origTransform', this.transform().local);
-                        self.$emit('dragstart');
-                    },
-                    onEnd: function () {
-                        self.$emit('dragend');
                     }
-                }
-
-                handler.drag(events.onMove, events.onStart, events.onEnd);
+                });
             }
 
             img.src = this.image;