Downgraded svg.js as many plugins did not support v3.x
Now rooms can be moved and resized.
This commit is contained in:
parent
fb7f43ed23
commit
b80991280a
12 changed files with 6266 additions and 7226 deletions
24
hal-core/resources/web/css/svg.select.css
vendored
24
hal-core/resources/web/css/svg.select.css
vendored
|
|
@ -1,24 +1,4 @@
|
|||
|
||||
|
||||
.selection_border {
|
||||
fill: none;
|
||||
stroke: black;
|
||||
stroke-width:1;
|
||||
}
|
||||
|
||||
.selection_handle_shear {
|
||||
fill: white;
|
||||
stroke: black;
|
||||
stroke-width:1;
|
||||
}
|
||||
|
||||
.selection_handle_rot {
|
||||
fill: white;
|
||||
stroke: black;
|
||||
stroke-width:1;
|
||||
}
|
||||
|
||||
/* .svg_select_points_lt{
|
||||
.svg_select_points_lt{
|
||||
cursor: nw-resize;
|
||||
}
|
||||
.svg_select_points_rt{
|
||||
|
|
@ -61,4 +41,4 @@
|
|||
stroke-opacity:0.8;
|
||||
fill-opacity:0.1;
|
||||
pointer-events:none; /* This ons is needed if you want to deselect or drag the shape*/
|
||||
/*} */
|
||||
}
|
||||
370
hal-core/resources/web/js/lib/svg.draggable.js
vendored
370
hal-core/resources/web/js/lib/svg.draggable.js
vendored
|
|
@ -1,177 +1,235 @@
|
|||
/*!
|
||||
* @svgdotjs/svg.draggable.js - An extension for svg.js which allows to drag elements with your mouse
|
||||
* @version 3.0.2
|
||||
/*! svg.draggable.js - v2.2.2 - 2019-01-08
|
||||
* https://github.com/svgdotjs/svg.draggable.js
|
||||
*
|
||||
* @copyright Wout Fierens
|
||||
* @license MIT
|
||||
*
|
||||
* BUILT: Tue Feb 19 2019 17:12:16 GMT+0100 (GMT+01:00)
|
||||
*/;
|
||||
(function (svg_js) {
|
||||
'use strict';
|
||||
* Copyright (c) 2019 Wout Fierens; Licensed MIT */
|
||||
;(function() {
|
||||
|
||||
function _classCallCheck(instance, Constructor) {
|
||||
if (!(instance instanceof Constructor)) {
|
||||
throw new TypeError("Cannot call a class as a function");
|
||||
}
|
||||
// creates handler, saves it
|
||||
function DragHandler(el){
|
||||
el.remember('_draggable', this)
|
||||
this.el = el
|
||||
}
|
||||
|
||||
function _defineProperties(target, props) {
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var descriptor = props[i];
|
||||
descriptor.enumerable = descriptor.enumerable || false;
|
||||
descriptor.configurable = true;
|
||||
if ("value" in descriptor) descriptor.writable = true;
|
||||
Object.defineProperty(target, descriptor.key, descriptor);
|
||||
}
|
||||
|
||||
// Sets new parameter, starts dragging
|
||||
DragHandler.prototype.init = function(constraint, val){
|
||||
var _this = this
|
||||
this.constraint = constraint
|
||||
this.value = val
|
||||
this.el.on('mousedown.drag', function(e){ _this.start(e) })
|
||||
this.el.on('touchstart.drag', function(e){ _this.start(e) })
|
||||
}
|
||||
|
||||
function _createClass(Constructor, protoProps, staticProps) {
|
||||
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
||||
if (staticProps) _defineProperties(Constructor, staticProps);
|
||||
return Constructor;
|
||||
// transforms one point from screen to user coords
|
||||
DragHandler.prototype.transformPoint = function(event, offset){
|
||||
event = event || window.event
|
||||
var touches = event.changedTouches && event.changedTouches[0] || event
|
||||
this.p.x = touches.clientX - (offset || 0)
|
||||
this.p.y = touches.clientY
|
||||
return this.p.matrixTransform(this.m)
|
||||
}
|
||||
|
||||
var getCoordsFromEvent = function getCoordsFromEvent(ev) {
|
||||
if (ev.changedTouches) {
|
||||
ev = ev.changedTouches[0];
|
||||
// gets elements bounding box with special handling of groups, nested and use
|
||||
DragHandler.prototype.getBBox = function(){
|
||||
|
||||
var box = this.el.bbox()
|
||||
|
||||
if(this.el instanceof SVG.Nested) box = this.el.rbox()
|
||||
|
||||
if (this.el instanceof SVG.G || this.el instanceof SVG.Use || this.el instanceof SVG.Nested) {
|
||||
box.x = this.el.x()
|
||||
box.y = this.el.y()
|
||||
}
|
||||
|
||||
return {
|
||||
x: ev.clientX,
|
||||
y: ev.clientY
|
||||
};
|
||||
}; // Creates handler, saves it
|
||||
return box
|
||||
}
|
||||
|
||||
// start dragging
|
||||
DragHandler.prototype.start = function(e){
|
||||
|
||||
var DragHandler =
|
||||
/*#__PURE__*/
|
||||
function () {
|
||||
function DragHandler(el) {
|
||||
_classCallCheck(this, DragHandler);
|
||||
|
||||
el.remember('_draggable', this);
|
||||
this.el = el;
|
||||
this.drag = this.drag.bind(this);
|
||||
this.startDrag = this.startDrag.bind(this);
|
||||
this.endDrag = this.endDrag.bind(this);
|
||||
} // Enables or disabled drag based on input
|
||||
|
||||
|
||||
_createClass(DragHandler, [{
|
||||
key: "init",
|
||||
value: function init(enabled) {
|
||||
if (enabled) {
|
||||
this.el.on('mousedown.drag', this.startDrag);
|
||||
this.el.on('touchstart.drag', this.startDrag);
|
||||
} else {
|
||||
this.el.off('mousedown.drag');
|
||||
this.el.off('touchstart.drag');
|
||||
}
|
||||
} // Start dragging
|
||||
|
||||
}, {
|
||||
key: "startDrag",
|
||||
value: function startDrag(ev) {
|
||||
var isMouse = !ev.type.indexOf('mouse'); // Check for left button
|
||||
|
||||
if (isMouse && (ev.which || ev.buttons) !== 1) {
|
||||
return;
|
||||
} // Fire beforedrag event
|
||||
|
||||
|
||||
if (this.el.dispatch('beforedrag', {
|
||||
event: ev,
|
||||
handler: this
|
||||
}).defaultPrevented) {
|
||||
return;
|
||||
} // Prevent browser drag behavior as soon as possible
|
||||
|
||||
|
||||
ev.preventDefault(); // Prevent propagation to a parent that might also have dragging enabled
|
||||
|
||||
ev.stopPropagation(); // Make sure that start events are unbound so that one element
|
||||
// is only dragged by one input only
|
||||
|
||||
this.init(false);
|
||||
this.box = this.el.bbox();
|
||||
this.lastClick = this.el.point(getCoordsFromEvent(ev)); // We consider the drag done, when a touch is canceled, too
|
||||
|
||||
var eventMove = (isMouse ? 'mousemove' : 'touchmove') + '.drag';
|
||||
var eventEnd = (isMouse ? 'mouseup' : 'touchcancel.drag touchend') + '.drag'; // Bind drag and end events to window
|
||||
|
||||
svg_js.on(window, eventMove, this.drag);
|
||||
svg_js.on(window, eventEnd, this.endDrag); // Fire dragstart event
|
||||
|
||||
this.el.fire('dragstart', {
|
||||
event: ev,
|
||||
handler: this,
|
||||
box: this.box
|
||||
});
|
||||
} // While dragging
|
||||
|
||||
}, {
|
||||
key: "drag",
|
||||
value: function drag(ev) {
|
||||
var box = this.box,
|
||||
lastClick = this.lastClick;
|
||||
var currentClick = this.el.point(getCoordsFromEvent(ev));
|
||||
var x = box.x + (currentClick.x - lastClick.x);
|
||||
var y = box.y + (currentClick.y - lastClick.y);
|
||||
var newBox = new svg_js.Box(x, y, box.w, box.h);
|
||||
if (this.el.dispatch('dragmove', {
|
||||
event: ev,
|
||||
handler: this,
|
||||
box: newBox
|
||||
}).defaultPrevented) return;
|
||||
this.move(x, y);
|
||||
return newBox;
|
||||
// check for left button
|
||||
if(e.type == 'click'|| e.type == 'mousedown' || e.type == 'mousemove'){
|
||||
if((e.which || e.buttons) != 1){
|
||||
return
|
||||
}
|
||||
}, {
|
||||
key: "move",
|
||||
value: function move(x, y) {
|
||||
// Svg elements bbox depends on their content even though they have
|
||||
// x, y, width and height - strange!
|
||||
// Thats why we handle them the same as groups
|
||||
if (this.el.type === 'svg') {
|
||||
svg_js.G.prototype.move.call(this.el, x, y);
|
||||
} else {
|
||||
this.el.move(x, y);
|
||||
}
|
||||
|
||||
var _this = this
|
||||
|
||||
// fire beforedrag event
|
||||
this.el.fire('beforedrag', { event: e, handler: this })
|
||||
if(this.el.event().defaultPrevented) return;
|
||||
|
||||
// prevent browser drag behavior as soon as possible
|
||||
e.preventDefault();
|
||||
|
||||
// prevent propagation to a parent that might also have dragging enabled
|
||||
e.stopPropagation();
|
||||
|
||||
// search for parent on the fly to make sure we can call
|
||||
// draggable() even when element is not in the dom currently
|
||||
this.parent = this.parent || this.el.parent(SVG.Nested) || this.el.parent(SVG.Doc)
|
||||
this.p = this.parent.node.createSVGPoint()
|
||||
|
||||
// save current transformation matrix
|
||||
this.m = this.el.node.getScreenCTM().inverse()
|
||||
|
||||
var box = this.getBBox()
|
||||
|
||||
var anchorOffset;
|
||||
|
||||
// fix text-anchor in text-element (#37)
|
||||
if(this.el instanceof SVG.Text){
|
||||
anchorOffset = this.el.node.getComputedTextLength();
|
||||
|
||||
switch(this.el.attr('text-anchor')){
|
||||
case 'middle':
|
||||
anchorOffset /= 2;
|
||||
break
|
||||
case 'start':
|
||||
anchorOffset = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.startPoints = {
|
||||
// We take absolute coordinates since we are just using a delta here
|
||||
point: this.transformPoint(e, anchorOffset),
|
||||
box: box,
|
||||
transform: this.el.transform()
|
||||
}
|
||||
|
||||
// add drag and end events to window
|
||||
SVG.on(window, 'mousemove.drag', function(e){ _this.drag(e) })
|
||||
SVG.on(window, 'touchmove.drag', function(e){ _this.drag(e) })
|
||||
SVG.on(window, 'mouseup.drag', function(e){ _this.end(e) })
|
||||
SVG.on(window, 'touchend.drag', function(e){ _this.end(e) })
|
||||
|
||||
// fire dragstart event
|
||||
this.el.fire('dragstart', {event: e, p: this.startPoints.point, m: this.m, handler: this})
|
||||
}
|
||||
|
||||
// while dragging
|
||||
DragHandler.prototype.drag = function(e){
|
||||
|
||||
var box = this.getBBox()
|
||||
, p = this.transformPoint(e)
|
||||
, x = this.startPoints.box.x + p.x - this.startPoints.point.x
|
||||
, y = this.startPoints.box.y + p.y - this.startPoints.point.y
|
||||
, c = this.constraint
|
||||
, gx = p.x - this.startPoints.point.x
|
||||
, gy = p.y - this.startPoints.point.y
|
||||
|
||||
this.el.fire('dragmove', {
|
||||
event: e
|
||||
, p: p
|
||||
, m: this.m
|
||||
, handler: this
|
||||
})
|
||||
|
||||
if(this.el.event().defaultPrevented) return p
|
||||
|
||||
// move the element to its new position, if possible by constraint
|
||||
if (typeof c == 'function') {
|
||||
|
||||
var coord = c.call(this.el, x, y, this.m)
|
||||
|
||||
// bool, just show us if movement is allowed or not
|
||||
if (typeof coord == 'boolean') {
|
||||
coord = {
|
||||
x: coord,
|
||||
y: coord
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "endDrag",
|
||||
value: function endDrag(ev) {
|
||||
// final drag
|
||||
var box = this.drag(ev); // fire dragend event
|
||||
|
||||
this.el.fire('dragend', {
|
||||
event: ev,
|
||||
handler: this,
|
||||
box: box
|
||||
}); // unbind events
|
||||
|
||||
svg_js.off(window, 'mousemove.drag');
|
||||
svg_js.off(window, 'touchmove.drag');
|
||||
svg_js.off(window, 'mouseup.drag');
|
||||
svg_js.off(window, 'touchend.drag'); // Rebind initial Events
|
||||
|
||||
this.init(true);
|
||||
// if true, we just move. If !false its a number and we move it there
|
||||
if (coord.x === true) {
|
||||
this.el.x(x)
|
||||
} else if (coord.x !== false) {
|
||||
this.el.x(coord.x)
|
||||
}
|
||||
}]);
|
||||
|
||||
return DragHandler;
|
||||
}();
|
||||
if (coord.y === true) {
|
||||
this.el.y(y)
|
||||
} else if (coord.y !== false) {
|
||||
this.el.y(coord.y)
|
||||
}
|
||||
|
||||
svg_js.extend(svg_js.Element, {
|
||||
draggable: function draggable() {
|
||||
var enable = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
|
||||
var dragHandler = this.remember('_draggable') || new DragHandler(this);
|
||||
dragHandler.init(enable);
|
||||
return this;
|
||||
} else if (typeof c == 'object') {
|
||||
|
||||
// keep element within constrained box
|
||||
if (c.minX != null && x < c.minX) {
|
||||
x = c.minX
|
||||
gx = x - this.startPoints.box.x
|
||||
} else if (c.maxX != null && x > c.maxX - box.width) {
|
||||
x = c.maxX - box.width
|
||||
gx = x - this.startPoints.box.x
|
||||
} if (c.minY != null && y < c.minY) {
|
||||
y = c.minY
|
||||
gy = y - this.startPoints.box.y
|
||||
} else if (c.maxY != null && y > c.maxY - box.height) {
|
||||
y = c.maxY - box.height
|
||||
gy = y - this.startPoints.box.y
|
||||
}
|
||||
|
||||
if (c.snapToGrid != null) {
|
||||
x = x - (x % c.snapToGrid)
|
||||
y = y - (y % c.snapToGrid)
|
||||
gx = gx - (gx % c.snapToGrid)
|
||||
gy = gy - (gy % c.snapToGrid)
|
||||
}
|
||||
|
||||
if(this.el instanceof SVG.G)
|
||||
this.el.matrix(this.startPoints.transform).transform({x:gx, y: gy}, true)
|
||||
else
|
||||
this.el.move(x, y)
|
||||
}
|
||||
});
|
||||
|
||||
}(SVG));
|
||||
//# sourceMappingURL=svg.draggable.js.map
|
||||
// so we can use it in the end-method, too
|
||||
return p
|
||||
}
|
||||
|
||||
DragHandler.prototype.end = function(e){
|
||||
|
||||
// final drag
|
||||
var p = this.drag(e);
|
||||
|
||||
// fire dragend event
|
||||
this.el.fire('dragend', { event: e, p: p, m: this.m, handler: this })
|
||||
|
||||
// unbind events
|
||||
SVG.off(window, 'mousemove.drag')
|
||||
SVG.off(window, 'touchmove.drag')
|
||||
SVG.off(window, 'mouseup.drag')
|
||||
SVG.off(window, 'touchend.drag')
|
||||
|
||||
}
|
||||
|
||||
SVG.extend(SVG.Element, {
|
||||
// Make element draggable
|
||||
// Constraint might be an object (as described in readme.md) or a function in the form "function (x, y)" that gets called before every move.
|
||||
// The function can return a boolean or an object of the form {x, y}, to which the element will be moved. "False" skips moving, true moves to raw x, y.
|
||||
draggable: function(value, constraint) {
|
||||
|
||||
// Check the parameters and reassign if needed
|
||||
if (typeof value == 'function' || typeof value == 'object') {
|
||||
constraint = value
|
||||
value = true
|
||||
}
|
||||
|
||||
var dragHandler = this.remember('_draggable') || new DragHandler(this)
|
||||
|
||||
// When no parameter is given, value is true
|
||||
value = typeof value === 'undefined' ? true : value
|
||||
|
||||
if(value) dragHandler.init(constraint || {}, value)
|
||||
else {
|
||||
this.off('mousedown.drag')
|
||||
this.off('touchstart.drag')
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}).call(this);
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
/*! @svgdotjs/svg.draggable.js v3.0.2 MIT*/;
|
||||
!function(s){"use strict";function a(t,e){for(var i=0;i<e.length;i++){var n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}var h=function(t){return t.changedTouches&&(t=t.changedTouches[0]),{x:t.clientX,y:t.clientY}},e=function(){function e(t){!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,e),t.remember("_draggable",this),this.el=t,this.drag=this.drag.bind(this),this.startDrag=this.startDrag.bind(this),this.endDrag=this.endDrag.bind(this)}var t,i,n;return t=e,(i=[{key:"init",value:function(t){t?(this.el.on("mousedown.drag",this.startDrag),this.el.on("touchstart.drag",this.startDrag)):(this.el.off("mousedown.drag"),this.el.off("touchstart.drag"))}},{key:"startDrag",value:function(t){var e=!t.type.indexOf("mouse");if(!(e&&1!==(t.which||t.buttons)||this.el.dispatch("beforedrag",{event:t,handler:this}).defaultPrevented)){t.preventDefault(),t.stopPropagation(),this.init(!1),this.box=this.el.bbox(),this.lastClick=this.el.point(h(t));var i=(e?"mousemove":"touchmove")+".drag",n=(e?"mouseup":"touchcancel.drag touchend")+".drag";s.on(window,i,this.drag),s.on(window,n,this.endDrag),this.el.fire("dragstart",{event:t,handler:this,box:this.box})}}},{key:"drag",value:function(t){var e=this.box,i=this.lastClick,n=this.el.point(h(t)),a=e.x+(n.x-i.x),r=e.y+(n.y-i.y),o=new s.Box(a,r,e.w,e.h);if(!this.el.dispatch("dragmove",{event:t,handler:this,box:o}).defaultPrevented)return this.move(a,r),o}},{key:"move",value:function(t,e){"svg"===this.el.type?s.G.prototype.move.call(this.el,t,e):this.el.move(t,e)}},{key:"endDrag",value:function(t){var e=this.drag(t);this.el.fire("dragend",{event:t,handler:this,box:e}),s.off(window,"mousemove.drag"),s.off(window,"touchmove.drag"),s.off(window,"mouseup.drag"),s.off(window,"touchend.drag"),this.init(!0)}}])&&a(t.prototype,i),n&&a(t,n),e}();s.extend(s.Element,{draggable:function(){var t=!(0<arguments.length&&void 0!==arguments[0])||arguments[0];return(this.remember("_draggable")||new e(this)).init(t),this}})}(SVG);
|
||||
//# sourceMappingURL=svg.draggable.min.js.map
|
||||
/*! svg.draggable.js - v2.2.2 - 2019-01-08
|
||||
* https://github.com/svgdotjs/svg.draggable.js
|
||||
* Copyright (c) 2019 Wout Fierens; Licensed MIT */
|
||||
(function(){function a(a){a.remember("_draggable",this),this.el=a}a.prototype.init=function(a,b){var c=this;this.constraint=a,this.value=b,this.el.on("mousedown.drag",function(a){c.start(a)}),this.el.on("touchstart.drag",function(a){c.start(a)})},a.prototype.transformPoint=function(a,b){a=a||window.event;var c=a.changedTouches&&a.changedTouches[0]||a;return this.p.x=c.clientX-(b||0),this.p.y=c.clientY,this.p.matrixTransform(this.m)},a.prototype.getBBox=function(){var a=this.el.bbox();return this.el instanceof SVG.Nested&&(a=this.el.rbox()),(this.el instanceof SVG.G||this.el instanceof SVG.Use||this.el instanceof SVG.Nested)&&(a.x=this.el.x(),a.y=this.el.y()),a},a.prototype.start=function(a){if("click"!=a.type&&"mousedown"!=a.type&&"mousemove"!=a.type||1==(a.which||a.buttons)){var b=this;if(this.el.fire("beforedrag",{event:a,handler:this}),!this.el.event().defaultPrevented){a.preventDefault(),a.stopPropagation(),this.parent=this.parent||this.el.parent(SVG.Nested)||this.el.parent(SVG.Doc),this.p=this.parent.node.createSVGPoint(),this.m=this.el.node.getScreenCTM().inverse();var c,d=this.getBBox();if(this.el instanceof SVG.Text)switch(c=this.el.node.getComputedTextLength(),this.el.attr("text-anchor")){case"middle":c/=2;break;case"start":c=0}this.startPoints={point:this.transformPoint(a,c),box:d,transform:this.el.transform()},SVG.on(window,"mousemove.drag",function(a){b.drag(a)}),SVG.on(window,"touchmove.drag",function(a){b.drag(a)}),SVG.on(window,"mouseup.drag",function(a){b.end(a)}),SVG.on(window,"touchend.drag",function(a){b.end(a)}),this.el.fire("dragstart",{event:a,p:this.startPoints.point,m:this.m,handler:this})}}},a.prototype.drag=function(a){var b=this.getBBox(),c=this.transformPoint(a),d=this.startPoints.box.x+c.x-this.startPoints.point.x,e=this.startPoints.box.y+c.y-this.startPoints.point.y,f=this.constraint,g=c.x-this.startPoints.point.x,h=c.y-this.startPoints.point.y;if(this.el.fire("dragmove",{event:a,p:c,m:this.m,handler:this}),this.el.event().defaultPrevented)return c;if("function"==typeof f){var i=f.call(this.el,d,e,this.m);"boolean"==typeof i&&(i={x:i,y:i}),i.x===!0?this.el.x(d):i.x!==!1&&this.el.x(i.x),i.y===!0?this.el.y(e):i.y!==!1&&this.el.y(i.y)}else"object"==typeof f&&(null!=f.minX&&d<f.minX?(d=f.minX,g=d-this.startPoints.box.x):null!=f.maxX&&d>f.maxX-b.width&&(d=f.maxX-b.width,g=d-this.startPoints.box.x),null!=f.minY&&e<f.minY?(e=f.minY,h=e-this.startPoints.box.y):null!=f.maxY&&e>f.maxY-b.height&&(e=f.maxY-b.height,h=e-this.startPoints.box.y),null!=f.snapToGrid&&(d-=d%f.snapToGrid,e-=e%f.snapToGrid,g-=g%f.snapToGrid,h-=h%f.snapToGrid),this.el instanceof SVG.G?this.el.matrix(this.startPoints.transform).transform({x:g,y:h},!0):this.el.move(d,e));return c},a.prototype.end=function(a){var b=this.drag(a);this.el.fire("dragend",{event:a,p:b,m:this.m,handler:this}),SVG.off(window,"mousemove.drag"),SVG.off(window,"touchmove.drag"),SVG.off(window,"mouseup.drag"),SVG.off(window,"touchend.drag")},SVG.extend(SVG.Element,{draggable:function(b,c){("function"==typeof b||"object"==typeof b)&&(c=b,b=!0);var d=this.remember("_draggable")||new a(this);return b="undefined"==typeof b?!0:b,b?d.init(c||{},b):(this.off("mousedown.drag"),this.off("touchstart.drag")),this}})}).call(this);
|
||||
12396
hal-core/resources/web/js/lib/svg.js
vendored
12396
hal-core/resources/web/js/lib/svg.js
vendored
File diff suppressed because it is too large
Load diff
16
hal-core/resources/web/js/lib/svg.min.js
vendored
16
hal-core/resources/web/js/lib/svg.min.js
vendored
File diff suppressed because one or more lines are too long
21
hal-core/resources/web/js/lib/svg.resize.LICENSE.txt
Normal file
21
hal-core/resources/web/js/lib/svg.resize.LICENSE.txt
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Ulrich-Matthias Schäfer
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
511
hal-core/resources/web/js/lib/svg.resize.js
vendored
Normal file
511
hal-core/resources/web/js/lib/svg.resize.js
vendored
Normal file
|
|
@ -0,0 +1,511 @@
|
|||
/*!
|
||||
* svg.resize.js - An extension for svg.js which allows to resize elements which are selected
|
||||
* @version 1.4.3
|
||||
* https://github.com/svgdotjs/svg.resize.js
|
||||
*
|
||||
* @copyright [object Object]
|
||||
* @license MIT
|
||||
*/;
|
||||
;(function() {
|
||||
"use strict";
|
||||
|
||||
;(function () {
|
||||
|
||||
function ResizeHandler(el) {
|
||||
|
||||
el.remember('_resizeHandler', this);
|
||||
|
||||
this.el = el;
|
||||
this.parameters = {};
|
||||
this.lastUpdateCall = null;
|
||||
this.p = el.doc().node.createSVGPoint();
|
||||
}
|
||||
|
||||
ResizeHandler.prototype.transformPoint = function(x, y, m){
|
||||
|
||||
this.p.x = x - (this.offset.x - window.pageXOffset);
|
||||
this.p.y = y - (this.offset.y - window.pageYOffset);
|
||||
|
||||
return this.p.matrixTransform(m || this.m);
|
||||
|
||||
};
|
||||
|
||||
ResizeHandler.prototype._extractPosition = function(event) {
|
||||
// Extract a position from a mouse/touch event.
|
||||
// Returns { x: .., y: .. }
|
||||
return {
|
||||
x: event.clientX != null ? event.clientX : event.touches[0].clientX,
|
||||
y: event.clientY != null ? event.clientY : event.touches[0].clientY
|
||||
}
|
||||
};
|
||||
|
||||
ResizeHandler.prototype.init = function (options) {
|
||||
|
||||
var _this = this;
|
||||
|
||||
this.stop();
|
||||
|
||||
if (options === 'stop') {
|
||||
return;
|
||||
}
|
||||
|
||||
this.options = {};
|
||||
|
||||
// Merge options and defaults
|
||||
for (var i in this.el.resize.defaults) {
|
||||
this.options[i] = this.el.resize.defaults[i];
|
||||
if (typeof options[i] !== 'undefined') {
|
||||
this.options[i] = options[i];
|
||||
}
|
||||
}
|
||||
|
||||
// We listen to all these events which are specifying different edges
|
||||
this.el.on('lt.resize', function(e){ _this.resize(e || window.event); }); // Left-Top
|
||||
this.el.on('rt.resize', function(e){ _this.resize(e || window.event); }); // Right-Top
|
||||
this.el.on('rb.resize', function(e){ _this.resize(e || window.event); }); // Right-Bottom
|
||||
this.el.on('lb.resize', function(e){ _this.resize(e || window.event); }); // Left-Bottom
|
||||
|
||||
this.el.on('t.resize', function(e){ _this.resize(e || window.event); }); // Top
|
||||
this.el.on('r.resize', function(e){ _this.resize(e || window.event); }); // Right
|
||||
this.el.on('b.resize', function(e){ _this.resize(e || window.event); }); // Bottom
|
||||
this.el.on('l.resize', function(e){ _this.resize(e || window.event); }); // Left
|
||||
|
||||
this.el.on('rot.resize', function(e){ _this.resize(e || window.event); }); // Rotation
|
||||
|
||||
this.el.on('point.resize', function(e){ _this.resize(e || window.event); }); // Point-Moving
|
||||
|
||||
// This call ensures, that the plugin reacts to a change of snapToGrid immediately
|
||||
this.update();
|
||||
|
||||
};
|
||||
|
||||
ResizeHandler.prototype.stop = function(){
|
||||
this.el.off('lt.resize');
|
||||
this.el.off('rt.resize');
|
||||
this.el.off('rb.resize');
|
||||
this.el.off('lb.resize');
|
||||
|
||||
this.el.off('t.resize');
|
||||
this.el.off('r.resize');
|
||||
this.el.off('b.resize');
|
||||
this.el.off('l.resize');
|
||||
|
||||
this.el.off('rot.resize');
|
||||
|
||||
this.el.off('point.resize');
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
ResizeHandler.prototype.resize = function (event) {
|
||||
|
||||
var _this = this;
|
||||
|
||||
this.m = this.el.node.getScreenCTM().inverse();
|
||||
this.offset = { x: window.pageXOffset, y: window.pageYOffset };
|
||||
|
||||
var txPt = this._extractPosition(event.detail.event);
|
||||
this.parameters = {
|
||||
type: this.el.type, // the type of element
|
||||
p: this.transformPoint(txPt.x, txPt.y),
|
||||
x: event.detail.x, // x-position of the mouse when resizing started
|
||||
y: event.detail.y, // y-position of the mouse when resizing started
|
||||
box: this.el.bbox(), // The bounding-box of the element
|
||||
rotation: this.el.transform().rotation // The current rotation of the element
|
||||
};
|
||||
|
||||
this.resizeLimits = this.options.resizeLimits || this.resize.defaults.resizeLimits;
|
||||
|
||||
// Add font-size parameter if the element type is text
|
||||
if (this.el.type === "text") {
|
||||
this.parameters.fontSize = this.el.attr()["font-size"];
|
||||
}
|
||||
|
||||
// the i-param in the event holds the index of the point which is moved, when using `deepSelect`
|
||||
if (event.detail.i !== undefined) {
|
||||
|
||||
// get the point array
|
||||
var array = this.el.array().valueOf();
|
||||
|
||||
// Save the index and the point which is moved
|
||||
this.parameters.i = event.detail.i;
|
||||
this.parameters.pointCoords = [array[event.detail.i][0], array[event.detail.i][1]];
|
||||
}
|
||||
|
||||
this._resizeLeft = function (snap, resizeFont, checkAspectRatio, checkAspectRatioReverse, updateOnlyChanges) {
|
||||
if (this.parameters.box.width - snap[0] >= this.resizeLimits.width) {
|
||||
if (checkAspectRatio) {
|
||||
snap = this.checkAspectRatio(snap, checkAspectRatioReverse);
|
||||
}
|
||||
|
||||
if (this.parameters.type === "text") {
|
||||
if (resizeFont) {
|
||||
this.el.move(this.parameters.box.x + snap[0], this.parameters.box.y);
|
||||
this.el.attr("font-size", this.parameters.fontSize - snap[0]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.el.width(this.parameters.box.width - snap[0]);
|
||||
|
||||
if (updateOnlyChanges) {
|
||||
this.el.x(this.parameters.box.x + snap[0]);
|
||||
} else {
|
||||
this.el.move(this.parameters.box.x + snap[0], this.parameters.box.y);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this._resizeRight = function (snap, resizeFont, checkAspectRatio, checkAspectRatioReverse) {
|
||||
if (this.parameters.box.width + snap[0] >= this.resizeLimits.width) {
|
||||
if (checkAspectRatio) {
|
||||
snap = this.checkAspectRatio(snap, checkAspectRatioReverse);
|
||||
}
|
||||
|
||||
if (this.parameters.type === "text") {
|
||||
if (resizeFont) {
|
||||
this.el.move(this.parameters.box.x - snap[0], this.parameters.box.y);
|
||||
this.el.attr("font-size", this.parameters.fontSize + snap[0]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this.el.x(this.parameters.box.x).width(this.parameters.box.width + snap[0]);
|
||||
}
|
||||
};
|
||||
|
||||
this._resizeTop = function (snap, checkAspectRatio, checkAspectRatioReverse, updateOnlyChanges) {
|
||||
if (this.parameters.box.height - snap[1] >= this.resizeLimits.height) {
|
||||
if (checkAspectRatio) {
|
||||
snap = this.checkAspectRatio(snap, checkAspectRatioReverse);
|
||||
}
|
||||
|
||||
// Disable the font-resizing if it is not from the corner of bounding-box
|
||||
if (this.parameters.type === "text") {
|
||||
return;
|
||||
}
|
||||
|
||||
this.el.height(this.parameters.box.height - snap[1]);
|
||||
|
||||
if (updateOnlyChanges) {
|
||||
this.el.y(this.parameters.box.y + snap[1])
|
||||
} else {
|
||||
this.el.move(this.parameters.box.x, this.parameters.box.y + snap[1]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this._resizeBottom = function (snap, checkAspectRatio, checkAspectRatioReverse) {
|
||||
if (this.parameters.box.height + snap[1] >= this.resizeLimits.height) {
|
||||
if (checkAspectRatio) {
|
||||
snap = this.checkAspectRatio(snap, checkAspectRatioReverse);
|
||||
}
|
||||
|
||||
if (this.parameters.type === "text") {
|
||||
return;
|
||||
}
|
||||
|
||||
this.el.y(this.parameters.box.y).height(this.parameters.box.height + snap[1]);
|
||||
}
|
||||
};
|
||||
|
||||
// Lets check which edge of the bounding-box was clicked and resize the this.el according to this
|
||||
switch (event.type) {
|
||||
|
||||
// Left-Top-Edge
|
||||
case 'lt':
|
||||
// We build a calculating function for every case which gives us the new position of the this.el
|
||||
this.calc = function (diffX, diffY) {
|
||||
// The procedure is always the same
|
||||
// First we snap the edge to the given grid (snapping to 1px grid is normal resizing)
|
||||
var snap = this.snapToGrid(diffX, diffY);
|
||||
|
||||
this._resizeTop(snap, true, false, true);
|
||||
this._resizeLeft(snap, true, true, false, true);
|
||||
};
|
||||
break;
|
||||
|
||||
// Right-Top
|
||||
case 'rt':
|
||||
// s.a.
|
||||
this.calc = function (diffX, diffY) {
|
||||
var snap = this.snapToGrid(diffX, diffY, 1 << 1);
|
||||
|
||||
this._resizeTop(snap, true, true, true);
|
||||
this._resizeRight(snap, true, true, true);
|
||||
};
|
||||
break;
|
||||
|
||||
// Right-Bottom
|
||||
case 'rb':
|
||||
// s.a.
|
||||
this.calc = function (diffX, diffY) {
|
||||
var snap = this.snapToGrid(diffX, diffY, 0);
|
||||
|
||||
this._resizeBottom(snap, true);
|
||||
this._resizeRight(snap, true, true);
|
||||
};
|
||||
break;
|
||||
|
||||
// Left-Bottom
|
||||
case 'lb':
|
||||
// s.a.
|
||||
this.calc = function (diffX, diffY) {
|
||||
var snap = this.snapToGrid(diffX, diffY, 1);
|
||||
|
||||
this._resizeBottom(snap, true, true);
|
||||
this._resizeLeft(snap, true, true, true, true);
|
||||
};
|
||||
break;
|
||||
|
||||
// Top
|
||||
case 't':
|
||||
// s.a.
|
||||
this.calc = function (diffX, diffY) {
|
||||
var snap = this.snapToGrid(diffX, diffY, 1 << 1);
|
||||
|
||||
this._resizeTop(snap);
|
||||
};
|
||||
break;
|
||||
|
||||
// Right
|
||||
case 'r':
|
||||
// s.a.
|
||||
this.calc = function (diffX, diffY) {
|
||||
var snap = this.snapToGrid(diffX, diffY, 0);
|
||||
|
||||
this._resizeRight(snap);
|
||||
};
|
||||
break;
|
||||
|
||||
// Bottom
|
||||
case 'b':
|
||||
// s.a.
|
||||
this.calc = function (diffX, diffY) {
|
||||
var snap = this.snapToGrid(diffX, diffY, 0);
|
||||
|
||||
this._resizeBottom(snap);
|
||||
};
|
||||
break;
|
||||
|
||||
// Left
|
||||
case 'l':
|
||||
// s.a.
|
||||
this.calc = function (diffX, diffY) {
|
||||
var snap = this.snapToGrid(diffX, diffY, 1);
|
||||
|
||||
this._resizeLeft(snap);
|
||||
};
|
||||
break;
|
||||
|
||||
// Rotation
|
||||
case 'rot':
|
||||
// s.a.
|
||||
this.calc = function (diffX, diffY) {
|
||||
|
||||
// yes this is kinda stupid but we need the mouse coords back...
|
||||
var current = {x: diffX + this.parameters.p.x, y: diffY + this.parameters.p.y};
|
||||
|
||||
// start minus middle
|
||||
var sAngle = Math.atan2((this.parameters.p.y - this.parameters.box.y - this.parameters.box.height / 2), (this.parameters.p.x - this.parameters.box.x - this.parameters.box.width / 2));
|
||||
|
||||
// end minus middle
|
||||
var pAngle = Math.atan2((current.y - this.parameters.box.y - this.parameters.box.height / 2), (current.x - this.parameters.box.x - this.parameters.box.width / 2));
|
||||
|
||||
var angle = this.parameters.rotation + (pAngle - sAngle) * 180 / Math.PI + this.options.snapToAngle / 2;
|
||||
|
||||
// We have to move the element to the center of the box first and change the rotation afterwards
|
||||
// because rotation always works around a rotation-center, which is changed when moving the element
|
||||
// We also set the new rotation center to the center of the box.
|
||||
this.el.center(this.parameters.box.cx, this.parameters.box.cy).rotate(angle - (angle % this.options.snapToAngle), this.parameters.box.cx, this.parameters.box.cy);
|
||||
};
|
||||
break;
|
||||
|
||||
// Moving one single Point (needed when an element is deepSelected which means you can move every single point of the object)
|
||||
case 'point':
|
||||
this.calc = function (diffX, diffY) {
|
||||
|
||||
// Snapping the point to the grid
|
||||
var snap = this.snapToGrid(diffX, diffY, this.parameters.pointCoords[0], this.parameters.pointCoords[1]);
|
||||
|
||||
// Get the point array
|
||||
var array = this.el.array().valueOf();
|
||||
|
||||
// Changing the moved point in the array
|
||||
array[this.parameters.i][0] = this.parameters.pointCoords[0] + snap[0];
|
||||
array[this.parameters.i][1] = this.parameters.pointCoords[1] + snap[1];
|
||||
|
||||
// And plot the new this.el
|
||||
this.el.plot(array);
|
||||
};
|
||||
}
|
||||
|
||||
this.el.fire('resizestart', {dx: this.parameters.x, dy: this.parameters.y, event: event});
|
||||
// When resizing started, we have to register events for...
|
||||
// Touches.
|
||||
SVG.on(window, 'touchmove.resize', function(e) {
|
||||
_this.update(e || window.event);
|
||||
});
|
||||
SVG.on(window, 'touchend.resize', function() {
|
||||
_this.done();
|
||||
});
|
||||
// Mouse.
|
||||
SVG.on(window, 'mousemove.resize', function (e) {
|
||||
_this.update(e || window.event);
|
||||
});
|
||||
SVG.on(window, 'mouseup.resize', function () {
|
||||
_this.done();
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// The update-function redraws the element every time the mouse is moving
|
||||
ResizeHandler.prototype.update = function (event) {
|
||||
|
||||
if (!event) {
|
||||
if (this.lastUpdateCall) {
|
||||
this.calc(this.lastUpdateCall[0], this.lastUpdateCall[1]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate the difference between the mouseposition at start and now
|
||||
var txPt = this._extractPosition(event);
|
||||
var p = this.transformPoint(txPt.x, txPt.y);
|
||||
|
||||
var diffX = p.x - this.parameters.p.x,
|
||||
diffY = p.y - this.parameters.p.y;
|
||||
|
||||
this.lastUpdateCall = [diffX, diffY];
|
||||
|
||||
// Calculate the new position and height / width of the element
|
||||
this.calc(diffX, diffY);
|
||||
|
||||
// Emit an event to say we have changed.
|
||||
this.el.fire('resizing', {dx: diffX, dy: diffY, event: event});
|
||||
};
|
||||
|
||||
// Is called on mouseup.
|
||||
// Removes the update-function from the mousemove event
|
||||
ResizeHandler.prototype.done = function () {
|
||||
this.lastUpdateCall = null;
|
||||
SVG.off(window, 'mousemove.resize');
|
||||
SVG.off(window, 'mouseup.resize');
|
||||
SVG.off(window, 'touchmove.resize');
|
||||
SVG.off(window, 'touchend.resize');
|
||||
this.el.fire('resizedone');
|
||||
};
|
||||
|
||||
// The flag is used to determine whether the resizing is used with a left-Point (first bit) and top-point (second bit)
|
||||
// In this cases the temp-values are calculated differently
|
||||
ResizeHandler.prototype.snapToGrid = function (diffX, diffY, flag, pointCoordsY) {
|
||||
|
||||
var temp;
|
||||
|
||||
// If `pointCoordsY` is given, a single Point has to be snapped (deepSelect). That's why we need a different temp-value
|
||||
if (typeof pointCoordsY !== 'undefined') {
|
||||
// Note that flag = pointCoordsX in this case
|
||||
temp = [(flag + diffX) % this.options.snapToGrid, (pointCoordsY + diffY) % this.options.snapToGrid];
|
||||
} else {
|
||||
// We check if the flag is set and if not we set a default-value (both bits set - which means upper-left-edge)
|
||||
flag = flag == null ? 1 | 1 << 1 : flag;
|
||||
temp = [(this.parameters.box.x + diffX + (flag & 1 ? 0 : this.parameters.box.width)) % this.options.snapToGrid, (this.parameters.box.y + diffY + (flag & (1 << 1) ? 0 : this.parameters.box.height)) % this.options.snapToGrid];
|
||||
}
|
||||
|
||||
if(diffX < 0) {
|
||||
temp[0] -= this.options.snapToGrid;
|
||||
}
|
||||
if(diffY < 0) {
|
||||
temp[1] -= this.options.snapToGrid;
|
||||
}
|
||||
|
||||
diffX -= (Math.abs(temp[0]) < this.options.snapToGrid / 2 ?
|
||||
temp[0] :
|
||||
temp[0] - (diffX < 0 ? -this.options.snapToGrid : this.options.snapToGrid));
|
||||
diffY -= (Math.abs(temp[1]) < this.options.snapToGrid / 2 ?
|
||||
temp[1] :
|
||||
temp[1] - (diffY < 0 ? -this.options.snapToGrid : this.options.snapToGrid));
|
||||
|
||||
return this.constraintToBox(diffX, diffY, flag, pointCoordsY);
|
||||
|
||||
};
|
||||
|
||||
// keep element within constrained box
|
||||
ResizeHandler.prototype.constraintToBox = function (diffX, diffY, flag, pointCoordsY) {
|
||||
//return [diffX, diffY]
|
||||
var c = this.options.constraint || {};
|
||||
var orgX, orgY;
|
||||
|
||||
if (typeof pointCoordsY !== 'undefined') {
|
||||
orgX = flag;
|
||||
orgY = pointCoordsY;
|
||||
} else {
|
||||
orgX = this.parameters.box.x + (flag & 1 ? 0 : this.parameters.box.width);
|
||||
orgY = this.parameters.box.y + (flag & (1<<1) ? 0 : this.parameters.box.height);
|
||||
}
|
||||
|
||||
if (typeof c.minX !== 'undefined' && orgX + diffX < c.minX) {
|
||||
diffX = c.minX - orgX;
|
||||
}
|
||||
|
||||
if (typeof c.maxX !== 'undefined' && orgX + diffX > c.maxX) {
|
||||
diffX = c.maxX - orgX;
|
||||
}
|
||||
|
||||
if (typeof c.minY !== 'undefined' && orgY + diffY < c.minY) {
|
||||
diffY = c.minY - orgY;
|
||||
}
|
||||
|
||||
if (typeof c.maxY !== 'undefined' && orgY + diffY > c.maxY) {
|
||||
diffY = c.maxY - orgY;
|
||||
}
|
||||
|
||||
return [diffX, diffY];
|
||||
};
|
||||
|
||||
ResizeHandler.prototype.checkAspectRatio = function (snap, isReverse) {
|
||||
if (!this.options.saveAspectRatio) {
|
||||
return snap;
|
||||
}
|
||||
|
||||
var updatedSnap = snap.slice();
|
||||
var aspectRatio = this.parameters.box.width / this.parameters.box.height;
|
||||
var newW = this.parameters.box.width + snap[0];
|
||||
var newH = this.parameters.box.height - snap[1];
|
||||
var newAspectRatio = newW / newH;
|
||||
|
||||
if (newAspectRatio < aspectRatio) {
|
||||
// Height is too big. Adapt it
|
||||
updatedSnap[1] = newW / aspectRatio - this.parameters.box.height;
|
||||
isReverse && (updatedSnap[1] = -updatedSnap[1]);
|
||||
} else if (newAspectRatio > aspectRatio) {
|
||||
// Width is too big. Adapt it
|
||||
updatedSnap[0] = this.parameters.box.width - newH * aspectRatio;
|
||||
isReverse && (updatedSnap[0] = -updatedSnap[0]);
|
||||
}
|
||||
|
||||
return updatedSnap;
|
||||
};
|
||||
|
||||
SVG.extend(SVG.Element, {
|
||||
// Resize element with mouse
|
||||
resize: function (options) {
|
||||
|
||||
(this.remember('_resizeHandler') || new ResizeHandler(this)).init(options || {});
|
||||
|
||||
return this;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
SVG.Element.prototype.resize.defaults = {
|
||||
snapToAngle: 0.1, // Specifies the speed the rotation is happening when moving the mouse
|
||||
snapToGrid: 1, // Snaps to a grid of `snapToGrid` Pixels
|
||||
constraint: {}, // keep element within constrained box
|
||||
resizeLimits: { width: 0, height: 0 }, // rect limit size on resize
|
||||
saveAspectRatio: false // Save aspect ratio when resizing using lt, rt, rb or lb points
|
||||
};
|
||||
|
||||
}).call(this);
|
||||
}());
|
||||
1
hal-core/resources/web/js/lib/svg.resize.min.js
vendored
Normal file
1
hal-core/resources/web/js/lib/svg.resize.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
hal-core/resources/web/js/lib/svg.select.js
vendored
2
hal-core/resources/web/js/lib/svg.select.js
vendored
|
|
@ -422,4 +422,4 @@ SVG.Element.prototype.selectize.defaults = {
|
|||
pointFill: "#000", // Point fill color
|
||||
pointStroke: { width: 1, color: "#000" } // Point stroke properties
|
||||
};
|
||||
}());
|
||||
}());
|
||||
100
hal-core/resources/web/js/map.js
vendored
100
hal-core/resources/web/js/map.js
vendored
|
|
@ -13,7 +13,7 @@ $(function(){
|
|||
// Setup map
|
||||
// ------------------------------------------
|
||||
|
||||
svg = SVG("#map").size("100%", "700").viewbox(0, 0, 1000, 700);
|
||||
svg = SVG('map');
|
||||
|
||||
// Initialize events
|
||||
|
||||
|
|
@ -23,11 +23,11 @@ $(function(){
|
|||
$("#button-save").click(function() {
|
||||
saveMap();
|
||||
editMode(false);
|
||||
drawMap();
|
||||
fetchData(drawMap);
|
||||
});
|
||||
$("#button-cancel").click(function() {
|
||||
editMode(false);
|
||||
drawMap();
|
||||
fetchData(drawMap);
|
||||
});
|
||||
|
||||
// Initialize background image uploader
|
||||
|
|
@ -92,14 +92,23 @@ function editMode(enable){
|
|||
editModeEnabled = enable;
|
||||
|
||||
if (editModeEnabled) {
|
||||
$(".edit-mode").show();
|
||||
$(".view-mode").hide();
|
||||
$("#map").css("border-color", "#6eb16e");
|
||||
$('.edit-mode').show();
|
||||
$('.view-mode').hide();
|
||||
$('#map').css('border-color', '#6eb16e');
|
||||
|
||||
svg.select('.draggable').draggable(true);
|
||||
//svg.select('.resizable').on('click', selectEvent, false);
|
||||
svg.select('.resizable').selectize({
|
||||
points: ['rt', 'lb', 'rb'], // Add selection points on the corners
|
||||
rotationPoint: false
|
||||
}).resize()
|
||||
} else {
|
||||
$(".room").selectize(false)
|
||||
$(".edit-mode").hide();
|
||||
$(".view-mode").show();
|
||||
$("#map").css("border-color", "");
|
||||
$('.edit-mode').hide();
|
||||
$('.view-mode').show();
|
||||
$('#map').css('border-color', '');
|
||||
|
||||
svg.select('.draggable').draggable(false);
|
||||
svg.select('resizable').selectize(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,9 +118,12 @@ function beforeDragEvent(e) {
|
|||
}
|
||||
}
|
||||
|
||||
function selectEntity(e) {
|
||||
if (editModeEnabled == false) {
|
||||
e.target.selectize();
|
||||
function selectEvent(e) {
|
||||
if (editModeEnabled == true) {
|
||||
e.target.selectize({
|
||||
points: ['rt', 'lb', 'rb'], // Add selection points on the corners
|
||||
rotationPoint: false
|
||||
}).resize();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -121,11 +133,11 @@ function selectEntity(e) {
|
|||
|
||||
function drawMap() {
|
||||
// Reset map
|
||||
//svg.clear();
|
||||
svg.clear();
|
||||
|
||||
// Background
|
||||
|
||||
if (svg.find(".bg-image").length <= 0) {
|
||||
if (svg.select(".bg-image").length() <= 0) {
|
||||
var bgImage = svg.image("?bgimage").addClass("bg-image")
|
||||
.x(0)
|
||||
.y(0)
|
||||
|
|
@ -137,21 +149,25 @@ function drawMap() {
|
|||
|
||||
if (data.rooms != null) {
|
||||
$.each(data.rooms, function(i, room) {
|
||||
svg.find("#room-" + room.id).remove();
|
||||
svg.select("#room-" + room.id).remove();
|
||||
|
||||
var group = svg.group();
|
||||
|
||||
group.text(room.name).move(5, 5).fill('#999');
|
||||
group.rect(room.map.width, room.map.height).selectize();
|
||||
var rect = group.rect(room.map.width, room.map.height);
|
||||
rect.fill('none').stroke({
|
||||
color: '#000',
|
||||
opacity: 0.6,
|
||||
width: 3
|
||||
});
|
||||
rect.addClass("resizable");
|
||||
|
||||
group.addClass("room")
|
||||
.attr("id", "room-" + room.id)
|
||||
.attr("room-id", room.id)
|
||||
.x(room.map.x)
|
||||
.y(room.map.y);
|
||||
|
||||
group.draggable().on('beforedrag', beforeDragEvent);
|
||||
//group.on('mousedown', selectEntity, false);
|
||||
.y(room.map.y)
|
||||
.addClass("draggable");
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -159,7 +175,7 @@ function drawMap() {
|
|||
|
||||
if (data.sensors != null) {
|
||||
$.each(data.sensors, function(i, sensor) {
|
||||
svg.find("#sensor-" + sensor.id).remove();
|
||||
svg.select("#sensor-" + sensor.id).remove();
|
||||
|
||||
var group = svg.group();
|
||||
group.element('title').words(sensor.name);
|
||||
|
|
@ -171,8 +187,8 @@ function drawMap() {
|
|||
.attr("id", "sensor-" + sensor.id)
|
||||
.attr("sensor-id", sensor.id)
|
||||
.x(sensor.map.x)
|
||||
.y(sensor.map.y);
|
||||
group.draggable().on('beforedrag', beforeDragEvent);
|
||||
.y(sensor.map.y)
|
||||
.addClass("draggable");
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -180,7 +196,7 @@ function drawMap() {
|
|||
|
||||
if (data.events != null) {
|
||||
$.each(data.events, function(i, event) {
|
||||
svg.find("#event-" + event.id).remove();
|
||||
svg.select("#event-" + event.id).remove();
|
||||
|
||||
var group = svg.group();
|
||||
group.element('title').words(event.name);
|
||||
|
|
@ -194,8 +210,8 @@ function drawMap() {
|
|||
.attr("id", "event-" + event.id)
|
||||
.attr("event-id", event.id)
|
||||
.x(event.map.x)
|
||||
.y(event.map.y);
|
||||
group.draggable().on('beforedrag', beforeDragEvent);
|
||||
.y(event.map.y)
|
||||
.addClass("draggable");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -227,27 +243,35 @@ async function fetchData(callback) {
|
|||
}
|
||||
|
||||
function saveMap(){
|
||||
svg.find(".room").each(function(){
|
||||
svg.select(".room").each(function(){
|
||||
saveDevice(this, "room", "room-id");
|
||||
});
|
||||
svg.find(".sensor").each(function(){
|
||||
svg.select(".sensor").each(function(){
|
||||
saveDevice(this, "sensor", "sensor-id");
|
||||
});
|
||||
svg.find(".event").each(function(){
|
||||
svg.select(".event").each(function(){
|
||||
saveDevice(this, "event", "event-id");
|
||||
});
|
||||
}
|
||||
function saveDevice(element, type, id){
|
||||
function saveDevice(element, type, id) {
|
||||
var data = {
|
||||
action: "save",
|
||||
id: element.attr(id),
|
||||
type: type,
|
||||
x: element.x(),
|
||||
y: element.y()
|
||||
};
|
||||
|
||||
var resizable = element.select(".resizable");
|
||||
if (resizable.length() > 0) {
|
||||
data.width = resizable.get(0).width();
|
||||
data.height = resizable.get(0).height();
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
async: false,
|
||||
dataType: "json",
|
||||
url: "/api/map?",
|
||||
data: {
|
||||
action: "save",
|
||||
id: element.attr(id),
|
||||
type: type,
|
||||
x: element.x(),
|
||||
y: element.y()
|
||||
},
|
||||
data: data
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
</style>
|
||||
|
||||
<div class="col-sm-9 col-sm-offset-1 col-md-10 col-md-offset-1">
|
||||
<svg id="map"></svg>
|
||||
<svg id="map" width="100%" height="700" viewBox="0, 0, 1000, 700"></svg>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-1 col-md-1">
|
||||
|
|
@ -43,11 +43,12 @@
|
|||
</div>
|
||||
|
||||
<link href="css/jquery.filer.css" rel="stylesheet">
|
||||
<link href="css/svg.select.min.js" rel="stylesheet">
|
||||
<link href="css/svg.select.min.css" rel="stylesheet">
|
||||
|
||||
<script src="js/lib/jquery.filer.min.js"></script>
|
||||
<script src="js/lib/svg.min.js"></script>
|
||||
<script src="js/lib/svg.select.min.js"></script>
|
||||
<script src="js/lib/svg.resize.min.js"></script>
|
||||
<script src="js/lib/svg.draggable.min.js"></script>
|
||||
<script src="js/map.js"></script>
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import se.hal.HalContext;
|
|||
import se.hal.intf.HalAbstractDevice;
|
||||
import se.hal.intf.HalApiEndpoint;
|
||||
import se.hal.struct.Event;
|
||||
import se.hal.struct.Room;
|
||||
import se.hal.struct.Sensor;
|
||||
import zutil.db.DBConnection;
|
||||
import zutil.log.LogUtil;
|
||||
|
|
@ -35,20 +36,38 @@ public class MapApiEndpoint extends HalApiEndpoint {
|
|||
|
||||
if ("save".equals(request.get("action"))) {
|
||||
int id = Integer.parseInt(request.get("id"));
|
||||
HalAbstractDevice device = null;
|
||||
|
||||
logger.info("Saving Sensor coordinates.");
|
||||
logger.info("Saving map coordinates.");
|
||||
|
||||
if ("sensor".equals(request.get("type")))
|
||||
device = Sensor.getSensor(db, id);
|
||||
else if ("event".equals(request.get("type")))
|
||||
device = Event.getEvent(db, id);
|
||||
switch (request.get("type")) {
|
||||
case "room":
|
||||
Room room = Room.getRoom(db, id);
|
||||
room.setMapCoordinates(
|
||||
Float.parseFloat(request.get("x")),
|
||||
Float.parseFloat(request.get("y")),
|
||||
Float.parseFloat(request.get("width")),
|
||||
Float.parseFloat(request.get("height")));
|
||||
room.save(db);
|
||||
break;
|
||||
|
||||
device.setMapCoordinates(
|
||||
Float.parseFloat(request.get("x")),
|
||||
Float.parseFloat(request.get("y")));
|
||||
device.save(db);
|
||||
case "sensor":
|
||||
Sensor sensor = Sensor.getSensor(db, id);
|
||||
sensor.setMapCoordinates(
|
||||
Float.parseFloat(request.get("x")),
|
||||
Float.parseFloat(request.get("y")));
|
||||
sensor.save(db);
|
||||
break;
|
||||
|
||||
case "event":
|
||||
Event event = Event.getEvent(db, id);
|
||||
event.setMapCoordinates(
|
||||
Float.parseFloat(request.get("x")),
|
||||
Float.parseFloat(request.get("y")));
|
||||
event.save(db);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue