diff --git a/lib/Modeler.js b/lib/Modeler.js
index 9f786aa0..d51a88f3 100644
--- a/lib/Modeler.js
+++ b/lib/Modeler.js
@@ -4,6 +4,7 @@ var bpmnModule = require('./di').defaultModule,
Viewer = require('./Viewer');
require('./draw/BpmnRenderer');
+require('./feature/zoomscroll/Service');
require('diagram-js/lib/features/dnd/Visuals');
require('diagram-js/lib/features/selection/Visuals');
@@ -27,7 +28,7 @@ Modeler.prototype.createDiagram = function() {
return new Diagram({
canvas: { container: this.container },
modules: [ bpmnModule ],
- components: [ 'selectionVisuals', 'dragVisuals' ]
+ components: [ 'selectionVisuals', 'dragVisuals', 'zoomScroll' ]
});
};
diff --git a/lib/Viewer.js b/lib/Viewer.js
index 622bf73f..3e45d63d 100644
--- a/lib/Viewer.js
+++ b/lib/Viewer.js
@@ -10,6 +10,8 @@ var Importer = require('./import/Importer'),
var bpmnModule = require('./di').defaultModule;
require('./draw/BpmnRenderer');
+require('./feature/zoomscroll/Service');
+
require('diagram-js/lib/features/selection/Visuals');
@@ -56,12 +58,11 @@ function Viewer(options) {
var logoData = fs.readFileSync('resources/bpmnjs.png', 'base64');
- var a = $('').css({
+ var a = $('').css({
position: 'absolute',
bottom: 15,
right: 15,
- 'z-index': 100,
- opacity: 0.8
+ zIndex: 100
});
var logo = $('').attr('src', 'data:image/png;base64,' + logoData).appendTo(a);
@@ -163,7 +164,7 @@ Viewer.prototype.createDiagram = function() {
return new Diagram({
canvas: { container: this.container },
modules: [ bpmnModule ],
- components: [ 'selectionVisuals' ]
+ components: [ 'selectionVisuals', 'zoomScroll' ]
});
};
diff --git a/lib/feature/zoomscroll/Service.js b/lib/feature/zoomscroll/Service.js
new file mode 100644
index 00000000..581c0284
--- /dev/null
+++ b/lib/feature/zoomscroll/Service.js
@@ -0,0 +1,64 @@
+var mousewheel = require('./mousewheel');
+
+var bpmnModule = require('../../di').defaultModule;
+
+function ZoomScroll(events, canvas) {
+
+ var RANGE = { min: 0.2, max: 4 };
+
+ var ZOOM_OFFSET = 5;
+ var SCROLL_OFFSET = 50;
+
+ function cap(scale) {
+ return Math.max(RANGE.min, Math.min(RANGE.max, scale));
+ }
+
+ function zoom(direction, position) {
+
+ var currentZoom = canvas.zoom();
+ var factor = 1 + (direction / ZOOM_OFFSET);
+
+ canvas.zoom(cap(currentZoom * factor), position);
+ }
+
+
+ function initMouseWheel(element) {
+
+ mousewheel(element).on('mousewheel', function(event) {
+
+ var shift = event.shiftKey,
+ ctrl = event.ctrlKey;
+
+ var x = event.deltaX,
+ y = event.deltaY;
+
+ if (shift || ctrl) {
+ var delta = {};
+
+ if (ctrl) {
+ delta.dx = SCROLL_OFFSET * x;
+ } else {
+ delta.dy = SCROLL_OFFSET * x;
+ }
+
+ canvas.scroll(delta);
+ } else {
+ zoom(y, { x: event.offsetX, y: event.offsetY });
+ }
+
+ event.preventDefault();
+ });
+ }
+
+ events.on('canvas.init', function(e) {
+ initMouseWheel(e.paper.node);
+ });
+
+ // API
+ this.zoom = zoom;
+}
+
+
+bpmnModule.type('zoomScroll', [ 'eventBus', 'canvas', ZoomScroll ]);
+
+module.exports = ZoomScroll;
\ No newline at end of file
diff --git a/lib/feature/zoomscroll/mousewheel.js b/lib/feature/zoomscroll/mousewheel.js
new file mode 100644
index 00000000..1200e2ec
--- /dev/null
+++ b/lib/feature/zoomscroll/mousewheel.js
@@ -0,0 +1,8 @@
+var $ = require('jquery');
+
+// init mouse wheel plugin
+require('jquery-mousewheel')($);
+
+module.exports = function(element) {
+ return $(element);
+};
\ No newline at end of file
diff --git a/package.json b/package.json
index e37b423c..d5a4de70 100644
--- a/package.json
+++ b/package.json
@@ -66,6 +66,7 @@
"peerDependencies": {
"lodash": "~2.4.0",
"didi": "~0.0.4",
- "jquery": "~2.1.0"
+ "jquery": "~2.1.0",
+ "jquery-mousewheel": "^3.1.11"
}
}
diff --git a/resources/bpmnjs.png b/resources/bpmnjs.png
index 380704ac..2bc56c71 100644
Binary files a/resources/bpmnjs.png and b/resources/bpmnjs.png differ