302 lines
9.6 KiB
JavaScript
Generated
302 lines
9.6 KiB
JavaScript
Generated
|
|
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing,
|
|
* software distributed under the License is distributed on an
|
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
* KIND, either express or implied. See the License for the
|
|
* specific language governing permissions and limitations
|
|
* under the License.
|
|
*/
|
|
|
|
/**
|
|
* Simple draggable tool, just for demo or testing.
|
|
* Use jquery.
|
|
*/
|
|
(function (global) {
|
|
|
|
var BORDER_WIDTH = 4;
|
|
var $ = global.jQuery;
|
|
|
|
global.draggable = {
|
|
|
|
/**
|
|
* @param {HTMLElement} mainEl
|
|
* @param {module:echarts/echarts~EChart} chart
|
|
* @param {Object} [opt] {width: ..., height: ...}
|
|
* @param {number} [opt.width] If not specified, use mainEl current width.
|
|
* @param {number} [opt.height] If not specified, use mainEl current height.
|
|
* @param {boolean} [opt.lockX=false]
|
|
* @param {boolean} [opt.lockY=false]
|
|
* @param {number} [opt.throttle=false]
|
|
* @param {Function} [opt.onDrag]
|
|
* @return {type} description
|
|
*/
|
|
init: function (mainEl, chart, opt) {
|
|
opt = opt || {};
|
|
|
|
var onDrag = opt.onDrag || $.proxy(chart.resize, chart);
|
|
|
|
var onDragThrottled = chart ? onDrag : function () {};
|
|
if (opt.throttle) {
|
|
onDragThrottled = throttle(onDragThrottled, opt.throttle, true, false);
|
|
}
|
|
|
|
var mainEl = $(mainEl);
|
|
var id = mainEl.attr('data-draggable-id');
|
|
|
|
var width = mainEl.outerWidth();
|
|
var height = mainEl.outerHeight();
|
|
var mainStyle = mainEl[0].style;
|
|
var placeholder = $('<div></div>').css({
|
|
position: mainStyle.position,
|
|
width: width,
|
|
height: height,
|
|
top: mainStyle.top,
|
|
bottom: mainStyle.bottom,
|
|
left: mainStyle.left,
|
|
right: mainStyle.right,
|
|
borderWidth: 0,
|
|
margin: 0,
|
|
padding: 0,
|
|
visibility: 'hidden'
|
|
});
|
|
placeholder.insertAfter(mainEl);
|
|
|
|
if (id == null) {
|
|
id = +Math.random();
|
|
mainEl.attr('data-draggable-id', id);
|
|
}
|
|
else {
|
|
$('.draggable-control[data-draggable-id=' + id + ']').remove();
|
|
}
|
|
|
|
var controlEl = $(
|
|
'<div class="draggable-control">DRAG<span class="draggable-label"></span></div>'
|
|
);
|
|
|
|
controlEl.css({
|
|
'position': 'absolute',
|
|
'border-radius': '30px',
|
|
'width': '60px',
|
|
'height': '60px',
|
|
'line-height': '60px',
|
|
'text-align': 'center',
|
|
'background': '#333',
|
|
'color': '#fff',
|
|
'cursor': 'pointer',
|
|
'font-size': '18px',
|
|
'box-shadow': '0 0 5px #333',
|
|
'-webkit-user-select': 'none',
|
|
'user-select': 'none'
|
|
});
|
|
|
|
var label = controlEl.find('.draggable-label');
|
|
|
|
label.css({
|
|
'display': 'block',
|
|
'position': 'absolute',
|
|
'color': '#000',
|
|
'font-size': '12px',
|
|
'text-align': 'center',
|
|
'left': 0,
|
|
'top': '65px',
|
|
'width': '60px',
|
|
'line-height': 1
|
|
});
|
|
|
|
mainEl.css({
|
|
'position': 'absolute',
|
|
'width': mainEl[0].offsetWidth + 'px',
|
|
'height': mainEl[0].offsetHeight + 'px',
|
|
'border-style': 'solid',
|
|
'border-color': '#ddd',
|
|
'border-width': BORDER_WIDTH + 'px',
|
|
'padding': 0,
|
|
'margin': 0
|
|
});
|
|
|
|
mainEl.parent().append(controlEl);
|
|
|
|
var locationMaker = createLocationMaker(mainEl);
|
|
var controlSize = controlEl[0].offsetWidth;
|
|
var dragging = false;
|
|
|
|
controlEl.on('mousedown', function () {
|
|
dragging = true;
|
|
});
|
|
|
|
$(document).on('mousemove', function (e) {
|
|
if (dragging) {
|
|
resize(e.pageX, e.pageY);
|
|
}
|
|
});
|
|
|
|
$(document).on('mouseup', function () {
|
|
dragging = false;
|
|
});
|
|
|
|
relocate(opt.width, opt.height);
|
|
|
|
// A temporarily way to handle the reflow.
|
|
// Where the position should be sync to the placeholder.
|
|
$(function () {
|
|
setTimeout(function () {
|
|
relocate();
|
|
}, 0);
|
|
});
|
|
|
|
function relocate(width, height) {
|
|
mainEl.css({
|
|
'left': locationMaker.left(placeholder[0].offsetLeft) + 'px',
|
|
'top': locationMaker.top(placeholder[0].offsetTop) + 'px',
|
|
});
|
|
var mainContentWidth = width != null ? width : locationMaker.width(mainEl.width());
|
|
var mainContentHeight = height != null ? height : locationMaker.height(mainEl.height());
|
|
|
|
var mainOffset = mainEl.offset();
|
|
resize(
|
|
mainOffset.left + mainContentWidth + BORDER_WIDTH,
|
|
mainOffset.top + mainContentHeight + BORDER_WIDTH,
|
|
true
|
|
);
|
|
}
|
|
|
|
function resize(x, y, isInit) {
|
|
var mainOffset = mainEl.offset();
|
|
var mainPosition = mainEl.position();
|
|
var mainContentWidth = x - mainOffset.left - BORDER_WIDTH;
|
|
var mainContentHeight = y - mainOffset.top - BORDER_WIDTH;
|
|
|
|
if (isInit || !opt.lockX) {
|
|
controlEl.css(
|
|
'left',
|
|
(mainPosition.left + mainContentWidth + BORDER_WIDTH - controlSize / 2) + 'px'
|
|
);
|
|
mainEl.css(
|
|
'width',
|
|
locationMaker.width(mainContentWidth) + 'px'
|
|
);
|
|
}
|
|
|
|
if (isInit || !opt.lockY) {
|
|
controlEl.css(
|
|
'top',
|
|
(mainPosition.top + mainContentHeight + BORDER_WIDTH - controlSize / 2) + 'px'
|
|
);
|
|
mainEl.css(
|
|
'height',
|
|
locationMaker.height(mainContentHeight) + 'px'
|
|
);
|
|
}
|
|
|
|
label.text(Math.round(mainContentWidth) + ' x ' + Math.round(mainContentHeight));
|
|
|
|
onDragThrottled();
|
|
}
|
|
}
|
|
};
|
|
|
|
function createLocationMaker(mainEl) {
|
|
var isBorderBox = mainEl.css('box-sizing') === 'border-box';
|
|
|
|
return {
|
|
width: function (w) {
|
|
return w + (isBorderBox ? 2 * BORDER_WIDTH : 0);
|
|
},
|
|
height: function (h) {
|
|
return h + (isBorderBox ? 2 * BORDER_WIDTH : 0);
|
|
},
|
|
left: function (l) {
|
|
return l - (isBorderBox ? 0: BORDER_WIDTH);
|
|
},
|
|
top: function (t) {
|
|
return t - (isBorderBox ? 0: BORDER_WIDTH);
|
|
}
|
|
};
|
|
}
|
|
|
|
function throttle(fn, delay, trailing, debounce) {
|
|
|
|
var currCall = (new Date()).getTime();
|
|
var lastCall = 0;
|
|
var lastExec = 0;
|
|
var timer = null;
|
|
var diff;
|
|
var scope;
|
|
var args;
|
|
var isSingle = typeof fn === 'function';
|
|
delay = delay || 0;
|
|
|
|
if (isSingle) {
|
|
return createCallback();
|
|
}
|
|
else {
|
|
var ret = [];
|
|
for (var i = 0; i < fn.length; i++) {
|
|
ret[i] = createCallback(i);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
function createCallback(index) {
|
|
|
|
function exec() {
|
|
lastExec = (new Date()).getTime();
|
|
timer = null;
|
|
(isSingle ? fn : fn[index]).apply(scope, args || []);
|
|
}
|
|
|
|
var cb = function () {
|
|
currCall = (new Date()).getTime();
|
|
scope = this;
|
|
args = arguments;
|
|
diff = currCall - (debounce ? lastCall : lastExec) - delay;
|
|
|
|
clearTimeout(timer);
|
|
|
|
if (debounce) {
|
|
if (trailing) {
|
|
timer = setTimeout(exec, delay);
|
|
}
|
|
else if (diff >= 0) {
|
|
exec();
|
|
}
|
|
}
|
|
else {
|
|
if (diff >= 0) {
|
|
exec();
|
|
}
|
|
else if (trailing) {
|
|
timer = setTimeout(exec, -diff);
|
|
}
|
|
}
|
|
|
|
lastCall = currCall;
|
|
};
|
|
|
|
/**
|
|
* Clear throttle.
|
|
* @public
|
|
*/
|
|
cb.clear = function () {
|
|
if (timer) {
|
|
clearTimeout(timer);
|
|
timer = null;
|
|
}
|
|
};
|
|
|
|
return cb;
|
|
}
|
|
}
|
|
|
|
})(window); |