From 7a5bc222fd916a7f12c418880899ddac9086b19b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tjark=20M=C3=BCller?= Date: Thu, 4 May 2023 13:28:58 +0200 Subject: [PATCH 1/3] documented/ solved svg rotation bug --- lib/flippable.html | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/lib/flippable.html b/lib/flippable.html index add8b31..db361eb 100644 --- a/lib/flippable.html +++ b/lib/flippable.html @@ -17,19 +17,27 @@ - + + + - - - - - +
+ + + + + +
+ @@ -46,6 +54,10 @@ via a HTML template that defines the placeholders for front and back views. The style file "css/flipeffect.css" holds reasonable default styles for this kind of templates.

+

+The SVG buttons have to be wrapped in an HTML DOM element which handles events. Otherwise, +the viewbox of the SVG will interfere with the coordinate transformation. +


     <template id="flipTemplate">
         <div class="flipWrapper">

From d45b3e68dd40b40dc706f9bfd5cbd9478ea8b529 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tjark=20M=C3=BCller?= 
Date: Thu, 4 May 2023 13:32:47 +0200
Subject: [PATCH 2/3] fixed rollup

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index a95b291..e7e0d28 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
         "test-eventlistener-hammerjs-destroy": "node ./test/tests/eventlistener/hammerjs-destroy.js",
         "test-eventlistener-interactionmapper": "node ./test/tests/eventlistener/interactionmapper.js",
         "test-eventlistener-interactionmapper-off": "node ./test/tests/eventlistener/interactionmapper-off.js",
-        "build": "rollup --config ./rollup.config.js",
+        "build": "rollup --config --bundleConfigAsCjs ./rollup.config.js",
         "watch": "rollup --watch --config ./rollup.config.js",
         "3rdparty": "gulp",
         "prettier": "gulp prettify",

From a748d05c38eb67ba332bb2f09a9c853e2787509c Mon Sep 17 00:00:00 2001
From: Uwe Oestermeier 
Date: Thu, 1 Jun 2023 18:19:30 +0200
Subject: [PATCH 3/3] Fixed problem with scrolling text in card drawers.

---
 dist/iwmlib.js      | 122 +++++++++++++++++++++++---------------------
 dist/iwmlib.pixi.js | 112 ++++++++++++++++++++--------------------
 lib/scatter.js      | 120 ++++++++++++++++++++++---------------------
 3 files changed, 183 insertions(+), 171 deletions(-)

diff --git a/dist/iwmlib.js b/dist/iwmlib.js
index 1482c31..ba986b3 100644
--- a/dist/iwmlib.js
+++ b/dist/iwmlib.js
@@ -3215,7 +3215,7 @@
             throwVisibility = 44,
             throwDamping = 0.95,
             autoThrow = true,
-            onThrowFinished = null,
+            onThrowFinished = null
         } = {}) {
             this.movableX = movableX;
             this.movableY = movableY;
@@ -3248,7 +3248,7 @@
                     t: t,
                     dt: dt,
                     dx: delta.x / number,
-                    dy: delta.y / number,
+                    dy: delta.y / number
                 };
                 this.velocities.push(velocity);
                 while (this.velocities.length > buffer) {
@@ -3310,7 +3310,7 @@
                 if (nextLength > prevLength) {
                     let factor = nextLength / prevLength;
                     next = Points$1.multiplyScalar(next, 1 / factor);
-                    console.log('Prevent acceleration', factor, this.velocity, next);
+                    // console.log('Prevent acceleration', factor, this.velocity, next)
                 }
                 this.velocity = next;
                 let d = Points$1.multiplyScalar(this.velocity, dt);
@@ -3346,7 +3346,7 @@
             let next = Points$1.multiplyScalar(velocity, this.throwDamping);
             return {
                 x: this.movableX ? next.x : 0,
-                y: this.movableY ? next.y : 0,
+                y: this.movableY ? next.y : 0
             }
         }
 
@@ -3391,7 +3391,7 @@
             scaleCloseBuffer = 0.05,
             maxRotation = Angle.degree2radian(5),
             minInteractionDistance = 0,
-            useLowPassFilter = false,
+            useLowPassFilter = false
         } = {}) {
             if (rotationDegrees != null && rotation != null) {
                 throw new Error('Use rotationDegrees or rotation but not both')
@@ -3406,7 +3406,7 @@
                 throwVisibility,
                 throwDamping,
                 autoThrow,
-                onThrowFinished,
+                onThrowFinished
             });
 
             /**
@@ -3481,7 +3481,7 @@
 
         _callCloseCallbacks() {
             if (this.onClose) {
-                this.onClose.forEach((callback) => callback(this));
+                this.onClose.forEach(callback => callback(this));
             }
         }
 
@@ -3501,6 +3501,9 @@
             let delta = interaction.delta();
 
             if (delta != null) {
+                /* uo: Is this the best place to add velocity? It works with scrollable text in card drawers but
+                has to be tested */
+                this.addVelocity(delta);
                 let rotate = delta.rotate;
                 let zoom = delta.zoom;
                 if (this.maxRotation != null) {
@@ -3519,9 +3522,10 @@
                     zoomDelta *= ratio;
                     zoom = 1 + zoomDelta;
                 }
-
                 this.transform(delta, zoom, rotate, delta.about);
-                this.addVelocity(delta); // uo: reverted commit fa0256d782dd498c6d3e51321260ca375ca9f855
+                /* uo: This is too late an dangerous. transform sometimes modifies delta
+                this.addVelocity(delta) // uo: reverted commit fa0256d782dd498c6d3e51321260ca375ca9f855
+                */
 
                 if (zoom != 1) this.interactionAnchor = delta.about;
             }
@@ -3632,11 +3636,11 @@
                 if (this.scale < this.minScale + this.scaleCloseThreshold - this.scaleCloseBuffer) {
                     this.zoom(this.minScale, {
                         animate: 0.2,
-                        onComplete: this.close.bind(this),
+                        onComplete: this.close.bind(this)
                     });
                 } else if (this.scale < this.minScale + this.scaleCloseThreshold) {
                     this.zoom(this.minScale + this.scaleCloseThreshold, {
-                        animate: 0.4,
+                        animate: 0.4
                     });
                 }
         }
@@ -3658,12 +3662,12 @@
                         x: '+=' + d.x,
                         y: '+=' + d.y,
                         /* scale: scale, uo: not defined, why was this here? */
-                        onUpdate: (e) => {
+                        onUpdate: e => {
                             let p = this.position;
                             let dx = p.x - startPos.x;
                             let dy = p.x - startPos.y;
                             this.onMoved(dx, dy);
-                        },
+                        }
                     });
                 } else {
                     this._move(d);
@@ -3692,7 +3696,7 @@
                         scale: scale,
                         delay: delay,
                         onComplete: onComplete,
-                        onUpdate: this.onZoomed.bind(this),
+                        onUpdate: this.onZoomed.bind(this)
                     });
                 } else {
                     this.scale = scale;
@@ -3710,7 +3714,7 @@
         transform(translate, zoom, rotate, anchor) {
             let delta = {
                 x: this.movableX ? translate.x : 0,
-                y: this.movableY ? translate.y : 0,
+                y: this.movableY ? translate.y : 0
             };
             if (this.resizable) var vzoom = zoom;
             if (!this.translatable) delta = { x: 0, y: 0 };
@@ -3725,9 +3729,9 @@
                         rotate: 0,
                         about: anchor,
                         fast: false,
-                        type: UPDATE,
+                        type: UPDATE
                     });
-                    this.onTransform.forEach(function (f) {
+                    this.onTransform.forEach(function(f) {
                         f(event);
                     });
                 }
@@ -3756,9 +3760,9 @@
                     translate: delta,
                     scale: newScale,
                     rotate: rotate,
-                    about: anchor,
+                    about: anchor
                 });
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event);
                 });
             }
@@ -3824,7 +3828,7 @@
                 if (this.scale > this.maxScale) zoom = 1 - amount;
                 if (zoom != 1) {
                     this.transform({ x: 0, y: 0 }, zoom, 0, this.zoomAnchor);
-                    requestAnimationFrame((dt) => {
+                    requestAnimationFrame(dt => {
                         this.animateZoomBounce(dt);
                     });
                     return
@@ -3881,9 +3885,9 @@
                     rotate: 0,
                     about: null,
                     fast: false,
-                    type: START,
+                    type: START
                 });
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event);
                 });
             }
@@ -3899,13 +3903,13 @@
         }
 
         onEnd(event, interaction) {
-            console.log('Scatter.onEnd', this.dragging);
+            //console.log('Scatter.onEnd', this.dragging)
             if (interaction.isFinished()) {
                 this.endGesture(interaction);
                 this.dragging = false;
                 for (let key of interaction.ended.keys()) {
                     if (interaction.isTap(key)) {
-                        console.log('Scatter.isTap');
+                        //console.log('Scatter.isTap')
                         let point = interaction.ended.get(key);
                         this.onTap(event, interaction, point);
                     }
@@ -3917,9 +3921,9 @@
                         rotate: 0,
                         about: null,
                         fast: false,
-                        type: END,
+                        type: END
                     });
-                    this.onTransform.forEach(function (f) {
+                    this.onTransform.forEach(function(f) {
                         f(event);
                     });
                 }
@@ -3933,7 +3937,7 @@
         //onTap(event, interaction, point) {}
 
         onTap(event, interaction, point) {
-            console.log('AbstractScatter.onTap', this.tapDelegate, interaction);
+            //console.log('AbstractScatter.onTap', this.tapDelegate, interaction)
             if (this.tapDelegate) {
                 Events.stop(event);
                 this.tapDelegate.tap(event, 'scatter');
@@ -3947,9 +3951,9 @@
                     translate: delta,
                     scale: this.scale,
                     about: this.currentAbout,
-                    type: null,
+                    type: null
                 });
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event);
                 });
             }
@@ -3961,9 +3965,9 @@
                     scale: this.scale,
                     about: this.currentAbout,
                     fast: false,
-                    type: null,
+                    type: null
                 });
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event);
                 });
             }
@@ -3975,9 +3979,9 @@
                     translate: { x: dx, y: dy },
                     about: about,
                     fast: true,
-                    type: null,
+                    type: null
                 });
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event);
                 });
             }
@@ -3988,9 +3992,9 @@
                 let event = new ScatterEvent(this, {
                     scale: this.scale,
                     fast: false,
-                    type: null,
+                    type: null
                 });
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event);
                 });
             }
@@ -4004,9 +4008,9 @@
                     scale: this.scale,
                     about: about,
                     fast: false,
-                    type: null,
+                    type: null
                 });
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event);
                 });
             }
@@ -4038,7 +4042,7 @@
                 useCapture = true,
                 capturePointerEvents = true,
                 touchAction = 'none',
-                debugCanvas = null,
+                debugCanvas = null
             } = {}
         ) {
             this.onCapture = null;
@@ -4050,7 +4054,7 @@
                 movement of scatter objects, the touchmove event has to be bound again.
                 */
                 if (Capabilities.isSafari) {
-                    document.addEventListener('touchmove', (event) => this.preventPinch(event), false);
+                    document.addEventListener('touchmove', event => this.preventPinch(event), false);
                     stopEvents = false;
                 } else {
                     stopEvents = true;
@@ -4065,11 +4069,11 @@
             this.delegate = new InteractionMapper$1(element, this, {
                 useCapture,
                 capturePointerEvents,
-                mouseWheelElement: window,
+                mouseWheelElement: window
             });
 
             if (debugCanvas !== null) {
-                requestAnimationFrame((dt) => {
+                requestAnimationFrame(dt => {
                     this.showTouches(dt, debugCanvas);
                 });
             }
@@ -4091,7 +4095,7 @@
                 context.fill();
                 context.stroke();
             }
-            requestAnimationFrame((dt) => {
+            requestAnimationFrame(dt => {
                 this.showTouches(dt, canvas);
             });
         }
@@ -4233,7 +4237,7 @@
                 scaleCloseBuffer = 0.05,
                 useLowPassFilter = false,
                 maxRotation = Angle.degree2radian(15),
-                minInteractionDistance = 200,
+                minInteractionDistance = 200
             } = {}
         ) {
             super({
@@ -4260,7 +4264,7 @@
                 onClose,
                 useLowPassFilter,
                 maxRotation,
-                minInteractionDistance,
+                minInteractionDistance
             });
             if (container == null || width == null || height == null) {
                 throw new Error('Invalid value: null')
@@ -4288,7 +4292,7 @@
                 height: height,
                 scale: startScale,
                 rotation: this.startRotationDegrees,
-                transformOrigin: transformOrigin,
+                transformOrigin: transformOrigin
             };
             this.tapNodes = new Map();
 
@@ -4310,15 +4314,15 @@
                 button.className = 'interactiveElement';
                 this.element.appendChild(button);
 
-                button.addEventListener('pointerdown', (e) => {
+                button.addEventListener('pointerdown', e => {
                     this.startResize(e);
                 });
 
-                button.addEventListener('pointermove', (e) => {
+                button.addEventListener('pointermove', e => {
                     this.resize(e);
                 });
 
-                button.addEventListener('pointerup', (e) => {
+                button.addEventListener('pointerup', e => {
                     this.stopResize(e);
                 });
                 this.resizeButton = button;
@@ -4335,7 +4339,7 @@
                 scale: this.scale,
                 x: this.x,
                 y: this.y,
-                rotation: this.rotation,
+                rotation: this.rotation
             }
         }
 
@@ -4386,7 +4390,7 @@
                 top: rect.top - stage.top,
                 left: rect.left - stage.left,
                 width: rect.width,
-                height: rect.height,
+                height: rect.height
             }
         }
 
@@ -4427,7 +4431,7 @@
         set scale(scale) {
             TweenLite.set(this.element, {
                 scale: scale,
-                transformOrigin: this.transformOrigin,
+                transformOrigin: this.transformOrigin
             });
             this._scale = scale;
         }
@@ -4459,9 +4463,9 @@
         hide() {
             TweenLite.to(this.element, 0.1, {
                 display: 'none',
-                onComplete: (e) => {
+                onComplete: e => {
                     this.element.parentNode.removeChild(this.element);
-                },
+                }
             });
         }
 
@@ -4475,7 +4479,7 @@
                 x: p.x,
                 y: p.y,
                 rotation: rotationDegrees,
-                transformOrigin: this.transformOrigin,
+                transformOrigin: this.transformOrigin
             });
         }
 
@@ -4536,7 +4540,7 @@
 
             let oldPostition = {
                 x: this.element.getBoundingClientRect().left,
-                y: this.element.getBoundingClientRect().top,
+                y: this.element.getBoundingClientRect().top
             };
             this.bringToFront();
 
@@ -4544,7 +4548,7 @@
 
             let newPostition = {
                 x: this.element.getBoundingClientRect().left,
-                y: this.element.getBoundingClientRect().top,
+                y: this.element.getBoundingClientRect().top
             };
 
             let offset = Points$1.subtract(oldPostition, newPostition);
@@ -4589,7 +4593,7 @@
                 )
                     TweenLite.to(this.element, 0, {
                         width: this.element.offsetWidth + resizeW / this.scale,
-                        height: this.element.offsetHeight + resizeH / this.scale,
+                        height: this.element.offsetHeight + resizeH / this.scale
                     });
 
                 this.oldX = e.clientX;
@@ -4606,12 +4610,12 @@
             let event = new CustomEvent('resizeEnded');
             let oldPostition = {
                 x: this.element.getBoundingClientRect().left,
-                y: this.element.getBoundingClientRect().top,
+                y: this.element.getBoundingClientRect().top
             };
             this.element.style.transformOrigin = '50% 50%';
             let newPostition = {
                 x: this.element.getBoundingClientRect().left,
-                y: this.element.getBoundingClientRect().top,
+                y: this.element.getBoundingClientRect().top
             };
             let offset = Points$1.subtract(oldPostition, newPostition);
 
diff --git a/dist/iwmlib.pixi.js b/dist/iwmlib.pixi.js
index 7cdf1fa..4e1ab39 100644
--- a/dist/iwmlib.pixi.js
+++ b/dist/iwmlib.pixi.js
@@ -6778,7 +6778,7 @@
             throwVisibility = 44,
             throwDamping = 0.95,
             autoThrow = true,
-            onThrowFinished = null,
+            onThrowFinished = null
         } = {}) {
             this.movableX = movableX;
             this.movableY = movableY;
@@ -6811,7 +6811,7 @@
                     t: t,
                     dt: dt,
                     dx: delta.x / number,
-                    dy: delta.y / number,
+                    dy: delta.y / number
                 };
                 this.velocities.push(velocity);
                 while (this.velocities.length > buffer) {
@@ -6873,7 +6873,7 @@
                 if (nextLength > prevLength) {
                     let factor = nextLength / prevLength;
                     next = Points.multiplyScalar(next, 1 / factor);
-                    console.log('Prevent acceleration', factor, this.velocity, next);
+                    // console.log('Prevent acceleration', factor, this.velocity, next)
                 }
                 this.velocity = next;
                 let d = Points.multiplyScalar(this.velocity, dt);
@@ -6909,7 +6909,7 @@
             let next = Points.multiplyScalar(velocity, this.throwDamping);
             return {
                 x: this.movableX ? next.x : 0,
-                y: this.movableY ? next.y : 0,
+                y: this.movableY ? next.y : 0
             }
         }
 
@@ -6954,7 +6954,7 @@
             scaleCloseBuffer = 0.05,
             maxRotation = Angle.degree2radian(5),
             minInteractionDistance = 0,
-            useLowPassFilter = false,
+            useLowPassFilter = false
         } = {}) {
             if (rotationDegrees != null && rotation != null) {
                 throw new Error('Use rotationDegrees or rotation but not both')
@@ -6969,7 +6969,7 @@
                 throwVisibility,
                 throwDamping,
                 autoThrow,
-                onThrowFinished,
+                onThrowFinished
             });
 
             /**
@@ -7044,7 +7044,7 @@
 
         _callCloseCallbacks() {
             if (this.onClose) {
-                this.onClose.forEach((callback) => callback(this));
+                this.onClose.forEach(callback => callback(this));
             }
         }
 
@@ -7064,6 +7064,9 @@
             let delta = interaction.delta();
 
             if (delta != null) {
+                /* uo: Is this the best place to add velocity? It works with scrollable text in card drawers but
+                has to be tested */
+                this.addVelocity(delta);
                 let rotate = delta.rotate;
                 let zoom = delta.zoom;
                 if (this.maxRotation != null) {
@@ -7082,9 +7085,10 @@
                     zoomDelta *= ratio;
                     zoom = 1 + zoomDelta;
                 }
-
                 this.transform(delta, zoom, rotate, delta.about);
-                this.addVelocity(delta); // uo: reverted commit fa0256d782dd498c6d3e51321260ca375ca9f855
+                /* uo: This is too late an dangerous. transform sometimes modifies delta
+                this.addVelocity(delta) // uo: reverted commit fa0256d782dd498c6d3e51321260ca375ca9f855
+                */
 
                 if (zoom != 1) this.interactionAnchor = delta.about;
             }
@@ -7195,11 +7199,11 @@
                 if (this.scale < this.minScale + this.scaleCloseThreshold - this.scaleCloseBuffer) {
                     this.zoom(this.minScale, {
                         animate: 0.2,
-                        onComplete: this.close.bind(this),
+                        onComplete: this.close.bind(this)
                     });
                 } else if (this.scale < this.minScale + this.scaleCloseThreshold) {
                     this.zoom(this.minScale + this.scaleCloseThreshold, {
-                        animate: 0.4,
+                        animate: 0.4
                     });
                 }
         }
@@ -7221,12 +7225,12 @@
                         x: '+=' + d.x,
                         y: '+=' + d.y,
                         /* scale: scale, uo: not defined, why was this here? */
-                        onUpdate: (e) => {
+                        onUpdate: e => {
                             let p = this.position;
                             let dx = p.x - startPos.x;
                             let dy = p.x - startPos.y;
                             this.onMoved(dx, dy);
-                        },
+                        }
                     });
                 } else {
                     this._move(d);
@@ -7255,7 +7259,7 @@
                         scale: scale,
                         delay: delay,
                         onComplete: onComplete,
-                        onUpdate: this.onZoomed.bind(this),
+                        onUpdate: this.onZoomed.bind(this)
                     });
                 } else {
                     this.scale = scale;
@@ -7273,7 +7277,7 @@
         transform(translate, zoom, rotate, anchor) {
             let delta = {
                 x: this.movableX ? translate.x : 0,
-                y: this.movableY ? translate.y : 0,
+                y: this.movableY ? translate.y : 0
             };
             if (this.resizable) var vzoom = zoom;
             if (!this.translatable) delta = { x: 0, y: 0 };
@@ -7288,9 +7292,9 @@
                         rotate: 0,
                         about: anchor,
                         fast: false,
-                        type: UPDATE,
+                        type: UPDATE
                     });
-                    this.onTransform.forEach(function (f) {
+                    this.onTransform.forEach(function(f) {
                         f(event);
                     });
                 }
@@ -7319,9 +7323,9 @@
                     translate: delta,
                     scale: newScale,
                     rotate: rotate,
-                    about: anchor,
+                    about: anchor
                 });
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event);
                 });
             }
@@ -7387,7 +7391,7 @@
                 if (this.scale > this.maxScale) zoom = 1 - amount;
                 if (zoom != 1) {
                     this.transform({ x: 0, y: 0 }, zoom, 0, this.zoomAnchor);
-                    requestAnimationFrame((dt) => {
+                    requestAnimationFrame(dt => {
                         this.animateZoomBounce(dt);
                     });
                     return
@@ -7444,9 +7448,9 @@
                     rotate: 0,
                     about: null,
                     fast: false,
-                    type: START,
+                    type: START
                 });
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event);
                 });
             }
@@ -7462,13 +7466,13 @@
         }
 
         onEnd(event, interaction) {
-            console.log('Scatter.onEnd', this.dragging);
+            //console.log('Scatter.onEnd', this.dragging)
             if (interaction.isFinished()) {
                 this.endGesture(interaction);
                 this.dragging = false;
                 for (let key of interaction.ended.keys()) {
                     if (interaction.isTap(key)) {
-                        console.log('Scatter.isTap');
+                        //console.log('Scatter.isTap')
                         let point = interaction.ended.get(key);
                         this.onTap(event, interaction, point);
                     }
@@ -7480,9 +7484,9 @@
                         rotate: 0,
                         about: null,
                         fast: false,
-                        type: END,
+                        type: END
                     });
-                    this.onTransform.forEach(function (f) {
+                    this.onTransform.forEach(function(f) {
                         f(event);
                     });
                 }
@@ -7496,7 +7500,7 @@
         //onTap(event, interaction, point) {}
 
         onTap(event, interaction, point) {
-            console.log('AbstractScatter.onTap', this.tapDelegate, interaction);
+            //console.log('AbstractScatter.onTap', this.tapDelegate, interaction)
             if (this.tapDelegate) {
                 Events$1.stop(event);
                 this.tapDelegate.tap(event, 'scatter');
@@ -7510,9 +7514,9 @@
                     translate: delta,
                     scale: this.scale,
                     about: this.currentAbout,
-                    type: null,
+                    type: null
                 });
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event);
                 });
             }
@@ -7524,9 +7528,9 @@
                     scale: this.scale,
                     about: this.currentAbout,
                     fast: false,
-                    type: null,
+                    type: null
                 });
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event);
                 });
             }
@@ -7538,9 +7542,9 @@
                     translate: { x: dx, y: dy },
                     about: about,
                     fast: true,
-                    type: null,
+                    type: null
                 });
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event);
                 });
             }
@@ -7551,9 +7555,9 @@
                 let event = new ScatterEvent(this, {
                     scale: this.scale,
                     fast: false,
-                    type: null,
+                    type: null
                 });
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event);
                 });
             }
@@ -7567,9 +7571,9 @@
                     scale: this.scale,
                     about: about,
                     fast: false,
-                    type: null,
+                    type: null
                 });
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event);
                 });
             }
@@ -7616,7 +7620,7 @@
                 scaleCloseBuffer = 0.05,
                 useLowPassFilter = false,
                 maxRotation = Angle.degree2radian(15),
-                minInteractionDistance = 200,
+                minInteractionDistance = 200
             } = {}
         ) {
             super({
@@ -7643,7 +7647,7 @@
                 onClose,
                 useLowPassFilter,
                 maxRotation,
-                minInteractionDistance,
+                minInteractionDistance
             });
             if (container == null || width == null || height == null) {
                 throw new Error('Invalid value: null')
@@ -7671,7 +7675,7 @@
                 height: height,
                 scale: startScale,
                 rotation: this.startRotationDegrees,
-                transformOrigin: transformOrigin,
+                transformOrigin: transformOrigin
             };
             this.tapNodes = new Map();
 
@@ -7693,15 +7697,15 @@
                 button.className = 'interactiveElement';
                 this.element.appendChild(button);
 
-                button.addEventListener('pointerdown', (e) => {
+                button.addEventListener('pointerdown', e => {
                     this.startResize(e);
                 });
 
-                button.addEventListener('pointermove', (e) => {
+                button.addEventListener('pointermove', e => {
                     this.resize(e);
                 });
 
-                button.addEventListener('pointerup', (e) => {
+                button.addEventListener('pointerup', e => {
                     this.stopResize(e);
                 });
                 this.resizeButton = button;
@@ -7718,7 +7722,7 @@
                 scale: this.scale,
                 x: this.x,
                 y: this.y,
-                rotation: this.rotation,
+                rotation: this.rotation
             }
         }
 
@@ -7769,7 +7773,7 @@
                 top: rect.top - stage.top,
                 left: rect.left - stage.left,
                 width: rect.width,
-                height: rect.height,
+                height: rect.height
             }
         }
 
@@ -7810,7 +7814,7 @@
         set scale(scale) {
             TweenLite.set(this.element, {
                 scale: scale,
-                transformOrigin: this.transformOrigin,
+                transformOrigin: this.transformOrigin
             });
             this._scale = scale;
         }
@@ -7842,9 +7846,9 @@
         hide() {
             TweenLite.to(this.element, 0.1, {
                 display: 'none',
-                onComplete: (e) => {
+                onComplete: e => {
                     this.element.parentNode.removeChild(this.element);
-                },
+                }
             });
         }
 
@@ -7858,7 +7862,7 @@
                 x: p.x,
                 y: p.y,
                 rotation: rotationDegrees,
-                transformOrigin: this.transformOrigin,
+                transformOrigin: this.transformOrigin
             });
         }
 
@@ -7919,7 +7923,7 @@
 
             let oldPostition = {
                 x: this.element.getBoundingClientRect().left,
-                y: this.element.getBoundingClientRect().top,
+                y: this.element.getBoundingClientRect().top
             };
             this.bringToFront();
 
@@ -7927,7 +7931,7 @@
 
             let newPostition = {
                 x: this.element.getBoundingClientRect().left,
-                y: this.element.getBoundingClientRect().top,
+                y: this.element.getBoundingClientRect().top
             };
 
             let offset = Points.subtract(oldPostition, newPostition);
@@ -7972,7 +7976,7 @@
                 )
                     TweenLite.to(this.element, 0, {
                         width: this.element.offsetWidth + resizeW / this.scale,
-                        height: this.element.offsetHeight + resizeH / this.scale,
+                        height: this.element.offsetHeight + resizeH / this.scale
                     });
 
                 this.oldX = e.clientX;
@@ -7989,12 +7993,12 @@
             let event = new CustomEvent('resizeEnded');
             let oldPostition = {
                 x: this.element.getBoundingClientRect().left,
-                y: this.element.getBoundingClientRect().top,
+                y: this.element.getBoundingClientRect().top
             };
             this.element.style.transformOrigin = '50% 50%';
             let newPostition = {
                 x: this.element.getBoundingClientRect().left,
-                y: this.element.getBoundingClientRect().top,
+                y: this.element.getBoundingClientRect().top
             };
             let offset = Points.subtract(oldPostition, newPostition);
 
diff --git a/lib/scatter.js b/lib/scatter.js
index c75a3d7..efaada1 100644
--- a/lib/scatter.js
+++ b/lib/scatter.js
@@ -95,7 +95,7 @@ class Throwable {
         throwVisibility = 44,
         throwDamping = 0.95,
         autoThrow = true,
-        onThrowFinished = null,
+        onThrowFinished = null
     } = {}) {
         this.movableX = movableX
         this.movableY = movableY
@@ -128,7 +128,7 @@ class Throwable {
                 t: t,
                 dt: dt,
                 dx: delta.x / number,
-                dy: delta.y / number,
+                dy: delta.y / number
             }
             this.velocities.push(velocity)
             while (this.velocities.length > buffer) {
@@ -190,7 +190,7 @@ class Throwable {
             if (nextLength > prevLength) {
                 let factor = nextLength / prevLength
                 next = Points.multiplyScalar(next, 1 / factor)
-                console.log('Prevent acceleration', factor, this.velocity, next)
+                // console.log('Prevent acceleration', factor, this.velocity, next)
             }
             this.velocity = next
             let d = Points.multiplyScalar(this.velocity, dt)
@@ -226,7 +226,7 @@ class Throwable {
         let next = Points.multiplyScalar(velocity, this.throwDamping)
         return {
             x: this.movableX ? next.x : 0,
-            y: this.movableY ? next.y : 0,
+            y: this.movableY ? next.y : 0
         }
     }
 
@@ -271,7 +271,7 @@ export class AbstractScatter extends Throwable {
         scaleCloseBuffer = 0.05,
         maxRotation = Angle.degree2radian(5),
         minInteractionDistance = 0,
-        useLowPassFilter = false,
+        useLowPassFilter = false
     } = {}) {
         if (rotationDegrees != null && rotation != null) {
             throw new Error('Use rotationDegrees or rotation but not both')
@@ -286,7 +286,7 @@ export class AbstractScatter extends Throwable {
             throwVisibility,
             throwDamping,
             autoThrow,
-            onThrowFinished,
+            onThrowFinished
         })
 
         /**
@@ -361,7 +361,7 @@ export class AbstractScatter extends Throwable {
 
     _callCloseCallbacks() {
         if (this.onClose) {
-            this.onClose.forEach((callback) => callback(this))
+            this.onClose.forEach(callback => callback(this))
         }
     }
 
@@ -381,6 +381,9 @@ export class AbstractScatter extends Throwable {
         let delta = interaction.delta()
 
         if (delta != null) {
+            /* uo: Is this the best place to add velocity? It works with scrollable text in card drawers but
+            has to be tested */
+            this.addVelocity(delta)
             let rotate = delta.rotate
             let zoom = delta.zoom
             if (this.maxRotation != null) {
@@ -399,9 +402,10 @@ export class AbstractScatter extends Throwable {
                 zoomDelta *= ratio
                 zoom = 1 + zoomDelta
             }
-
             this.transform(delta, zoom, rotate, delta.about)
+            /* uo: This is too late an dangerous. transform sometimes modifies delta
             this.addVelocity(delta) // uo: reverted commit fa0256d782dd498c6d3e51321260ca375ca9f855
+            */
 
             if (zoom != 1) this.interactionAnchor = delta.about
         }
@@ -512,11 +516,11 @@ export class AbstractScatter extends Throwable {
             if (this.scale < this.minScale + this.scaleCloseThreshold - this.scaleCloseBuffer) {
                 this.zoom(this.minScale, {
                     animate: 0.2,
-                    onComplete: this.close.bind(this),
+                    onComplete: this.close.bind(this)
                 })
             } else if (this.scale < this.minScale + this.scaleCloseThreshold) {
                 this.zoom(this.minScale + this.scaleCloseThreshold, {
-                    animate: 0.4,
+                    animate: 0.4
                 })
             }
     }
@@ -538,12 +542,12 @@ export class AbstractScatter extends Throwable {
                     x: '+=' + d.x,
                     y: '+=' + d.y,
                     /* scale: scale, uo: not defined, why was this here? */
-                    onUpdate: (e) => {
+                    onUpdate: e => {
                         let p = this.position
                         let dx = p.x - startPos.x
                         let dy = p.x - startPos.y
                         this.onMoved(dx, dy)
-                    },
+                    }
                 })
             } else {
                 this._move(d)
@@ -572,7 +576,7 @@ export class AbstractScatter extends Throwable {
                     scale: scale,
                     delay: delay,
                     onComplete: onComplete,
-                    onUpdate: this.onZoomed.bind(this),
+                    onUpdate: this.onZoomed.bind(this)
                 })
             } else {
                 this.scale = scale
@@ -590,7 +594,7 @@ export class AbstractScatter extends Throwable {
     transform(translate, zoom, rotate, anchor) {
         let delta = {
             x: this.movableX ? translate.x : 0,
-            y: this.movableY ? translate.y : 0,
+            y: this.movableY ? translate.y : 0
         }
         if (this.resizable) var vzoom = zoom
         if (!this.translatable) delta = { x: 0, y: 0 }
@@ -605,9 +609,9 @@ export class AbstractScatter extends Throwable {
                     rotate: 0,
                     about: anchor,
                     fast: false,
-                    type: UPDATE,
+                    type: UPDATE
                 })
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event)
                 })
             }
@@ -636,9 +640,9 @@ export class AbstractScatter extends Throwable {
                 translate: delta,
                 scale: newScale,
                 rotate: rotate,
-                about: anchor,
+                about: anchor
             })
-            this.onTransform.forEach(function (f) {
+            this.onTransform.forEach(function(f) {
                 f(event)
             })
         }
@@ -704,7 +708,7 @@ export class AbstractScatter extends Throwable {
             if (this.scale > this.maxScale) zoom = 1 - amount
             if (zoom != 1) {
                 this.transform({ x: 0, y: 0 }, zoom, 0, this.zoomAnchor)
-                requestAnimationFrame((dt) => {
+                requestAnimationFrame(dt => {
                     this.animateZoomBounce(dt)
                 })
                 return
@@ -761,9 +765,9 @@ export class AbstractScatter extends Throwable {
                 rotate: 0,
                 about: null,
                 fast: false,
-                type: START,
+                type: START
             })
-            this.onTransform.forEach(function (f) {
+            this.onTransform.forEach(function(f) {
                 f(event)
             })
         }
@@ -779,13 +783,13 @@ export class AbstractScatter extends Throwable {
     }
 
     onEnd(event, interaction) {
-        console.log('Scatter.onEnd', this.dragging)
+        //console.log('Scatter.onEnd', this.dragging)
         if (interaction.isFinished()) {
             this.endGesture(interaction)
             this.dragging = false
             for (let key of interaction.ended.keys()) {
                 if (interaction.isTap(key)) {
-                    console.log('Scatter.isTap')
+                    //console.log('Scatter.isTap')
                     let point = interaction.ended.get(key)
                     this.onTap(event, interaction, point)
                 }
@@ -797,9 +801,9 @@ export class AbstractScatter extends Throwable {
                     rotate: 0,
                     about: null,
                     fast: false,
-                    type: END,
+                    type: END
                 })
-                this.onTransform.forEach(function (f) {
+                this.onTransform.forEach(function(f) {
                     f(event)
                 })
             }
@@ -813,7 +817,7 @@ export class AbstractScatter extends Throwable {
     //onTap(event, interaction, point) {}
 
     onTap(event, interaction, point) {
-        console.log('AbstractScatter.onTap', this.tapDelegate, interaction)
+        //console.log('AbstractScatter.onTap', this.tapDelegate, interaction)
         if (this.tapDelegate) {
             Events.stop(event)
             this.tapDelegate.tap(event, 'scatter')
@@ -827,9 +831,9 @@ export class AbstractScatter extends Throwable {
                 translate: delta,
                 scale: this.scale,
                 about: this.currentAbout,
-                type: null,
+                type: null
             })
-            this.onTransform.forEach(function (f) {
+            this.onTransform.forEach(function(f) {
                 f(event)
             })
         }
@@ -841,9 +845,9 @@ export class AbstractScatter extends Throwable {
                 scale: this.scale,
                 about: this.currentAbout,
                 fast: false,
-                type: null,
+                type: null
             })
-            this.onTransform.forEach(function (f) {
+            this.onTransform.forEach(function(f) {
                 f(event)
             })
         }
@@ -855,9 +859,9 @@ export class AbstractScatter extends Throwable {
                 translate: { x: dx, y: dy },
                 about: about,
                 fast: true,
-                type: null,
+                type: null
             })
-            this.onTransform.forEach(function (f) {
+            this.onTransform.forEach(function(f) {
                 f(event)
             })
         }
@@ -868,9 +872,9 @@ export class AbstractScatter extends Throwable {
             let event = new ScatterEvent(this, {
                 scale: this.scale,
                 fast: false,
-                type: null,
+                type: null
             })
-            this.onTransform.forEach(function (f) {
+            this.onTransform.forEach(function(f) {
                 f(event)
             })
         }
@@ -884,9 +888,9 @@ export class AbstractScatter extends Throwable {
                 scale: this.scale,
                 about: about,
                 fast: false,
-                type: null,
+                type: null
             })
-            this.onTransform.forEach(function (f) {
+            this.onTransform.forEach(function(f) {
                 f(event)
             })
         }
@@ -918,7 +922,7 @@ export class DOMScatterContainer {
             useCapture = true,
             capturePointerEvents = true,
             touchAction = 'none',
-            debugCanvas = null,
+            debugCanvas = null
         } = {}
     ) {
         this.onCapture = null
@@ -930,7 +934,7 @@ export class DOMScatterContainer {
             movement of scatter objects, the touchmove event has to be bound again.
             */
             if (Capabilities.isSafari) {
-                document.addEventListener('touchmove', (event) => this.preventPinch(event), false)
+                document.addEventListener('touchmove', event => this.preventPinch(event), false)
                 stopEvents = false
             } else {
                 stopEvents = true
@@ -945,11 +949,11 @@ export class DOMScatterContainer {
         this.delegate = new InteractionMapper(element, this, {
             useCapture,
             capturePointerEvents,
-            mouseWheelElement: window,
+            mouseWheelElement: window
         })
 
         if (debugCanvas !== null) {
-            requestAnimationFrame((dt) => {
+            requestAnimationFrame(dt => {
                 this.showTouches(dt, debugCanvas)
             })
         }
@@ -971,7 +975,7 @@ export class DOMScatterContainer {
             context.fill()
             context.stroke()
         }
-        requestAnimationFrame((dt) => {
+        requestAnimationFrame(dt => {
             this.showTouches(dt, canvas)
         })
     }
@@ -1113,7 +1117,7 @@ export class DOMScatter extends AbstractScatter {
             scaleCloseBuffer = 0.05,
             useLowPassFilter = false,
             maxRotation = Angle.degree2radian(15),
-            minInteractionDistance = 200,
+            minInteractionDistance = 200
         } = {}
     ) {
         super({
@@ -1140,7 +1144,7 @@ export class DOMScatter extends AbstractScatter {
             onClose,
             useLowPassFilter,
             maxRotation,
-            minInteractionDistance,
+            minInteractionDistance
         })
         if (container == null || width == null || height == null) {
             throw new Error('Invalid value: null')
@@ -1168,7 +1172,7 @@ export class DOMScatter extends AbstractScatter {
             height: height,
             scale: startScale,
             rotation: this.startRotationDegrees,
-            transformOrigin: transformOrigin,
+            transformOrigin: transformOrigin
         }
         this.tapNodes = new Map()
 
@@ -1190,15 +1194,15 @@ export class DOMScatter extends AbstractScatter {
             button.className = 'interactiveElement'
             this.element.appendChild(button)
 
-            button.addEventListener('pointerdown', (e) => {
+            button.addEventListener('pointerdown', e => {
                 this.startResize(e)
             })
 
-            button.addEventListener('pointermove', (e) => {
+            button.addEventListener('pointermove', e => {
                 this.resize(e)
             })
 
-            button.addEventListener('pointerup', (e) => {
+            button.addEventListener('pointerup', e => {
                 this.stopResize(e)
             })
             this.resizeButton = button
@@ -1215,7 +1219,7 @@ export class DOMScatter extends AbstractScatter {
             scale: this.scale,
             x: this.x,
             y: this.y,
-            rotation: this.rotation,
+            rotation: this.rotation
         }
     }
 
@@ -1266,7 +1270,7 @@ export class DOMScatter extends AbstractScatter {
             top: rect.top - stage.top,
             left: rect.left - stage.left,
             width: rect.width,
-            height: rect.height,
+            height: rect.height
         }
     }
 
@@ -1307,7 +1311,7 @@ export class DOMScatter extends AbstractScatter {
     set scale(scale) {
         TweenLite.set(this.element, {
             scale: scale,
-            transformOrigin: this.transformOrigin,
+            transformOrigin: this.transformOrigin
         })
         this._scale = scale
     }
@@ -1339,9 +1343,9 @@ export class DOMScatter extends AbstractScatter {
     hide() {
         TweenLite.to(this.element, 0.1, {
             display: 'none',
-            onComplete: (e) => {
+            onComplete: e => {
                 this.element.parentNode.removeChild(this.element)
-            },
+            }
         })
     }
 
@@ -1355,7 +1359,7 @@ export class DOMScatter extends AbstractScatter {
             x: p.x,
             y: p.y,
             rotation: rotationDegrees,
-            transformOrigin: this.transformOrigin,
+            transformOrigin: this.transformOrigin
         })
     }
 
@@ -1416,7 +1420,7 @@ export class DOMScatter extends AbstractScatter {
 
         let oldPostition = {
             x: this.element.getBoundingClientRect().left,
-            y: this.element.getBoundingClientRect().top,
+            y: this.element.getBoundingClientRect().top
         }
         this.bringToFront()
 
@@ -1424,7 +1428,7 @@ export class DOMScatter extends AbstractScatter {
 
         let newPostition = {
             x: this.element.getBoundingClientRect().left,
-            y: this.element.getBoundingClientRect().top,
+            y: this.element.getBoundingClientRect().top
         }
 
         let offset = Points.subtract(oldPostition, newPostition)
@@ -1469,7 +1473,7 @@ export class DOMScatter extends AbstractScatter {
             )
                 TweenLite.to(this.element, 0, {
                     width: this.element.offsetWidth + resizeW / this.scale,
-                    height: this.element.offsetHeight + resizeH / this.scale,
+                    height: this.element.offsetHeight + resizeH / this.scale
                 })
 
             this.oldX = e.clientX
@@ -1486,12 +1490,12 @@ export class DOMScatter extends AbstractScatter {
         let event = new CustomEvent('resizeEnded')
         let oldPostition = {
             x: this.element.getBoundingClientRect().left,
-            y: this.element.getBoundingClientRect().top,
+            y: this.element.getBoundingClientRect().top
         }
         this.element.style.transformOrigin = '50% 50%'
         let newPostition = {
             x: this.element.getBoundingClientRect().left,
-            y: this.element.getBoundingClientRect().top,
+            y: this.element.getBoundingClientRect().top
         }
         let offset = Points.subtract(oldPostition, newPostition)