websch/editor/jquery-draginput.js

179 lines
5.6 KiB
JavaScript
Raw Normal View History

2012-07-24 02:30:12 +00:00
// Mark MacKay http://method.ac MIT License
$.fn.dragInput = function(cfg){
return this.each(function(){
this.repeating = false;
// Apply specified options or defaults:
// (Ought to refactor this some day to use $.extend() instead)
this.dragCfg = {
min: cfg && !isNaN(parseFloat(cfg.min)) ? Number(cfg.min) : null, // Fixes bug with min:0
max: cfg && !isNaN(parseFloat(cfg.max)) ? Number(cfg.max) : null,
2012-07-25 16:27:20 +00:00
step: cfg && Number(cfg.step) ? cfg.step : 1,
2012-07-24 02:30:12 +00:00
stepfunc: cfg && cfg.stepfunc ? cfg.stepfunc : false,
2012-07-26 05:52:06 +00:00
dragAdjust: cfg && cfg.dragAdjust ? cfg.dragAdjust : 1,
2012-07-24 02:30:12 +00:00
height: 70,
cursor: cfg && cfg.cursor ? Boolean(cfg.cursor) : false,
start: cfg && cfg.start ? Number(cfg.start) : 0,
_btn_width: 20,
_direction: null,
_delay: null,
_repeat: null,
callback: cfg && cfg.callback ? cfg.callback : null
};
// if a smallStep isn't supplied, use half the regular step
this.dragCfg.smallStep = cfg && cfg.smallStep ? cfg.smallStep : this.dragCfg.step/2;
2012-07-26 05:52:06 +00:00
var dragAdjust = this.dragCfg.dragAdjust;
2012-07-24 02:30:12 +00:00
var $label = $(this).parent();
var $input = $(this);
var cursorHeight = this.dragCfg.height;
var min = this.dragCfg.min;
var max = this.dragCfg.max
var step = this.dragCfg.step
var area = (max - min > 0) ? (max - min) / step : 200;
var scale = area/cursorHeight * step;
var lastY = 0;
var attr = this.getAttribute("data-attr");
var canvas = svgEditor.canvas
var selectedElems = canvas.getSelectedElems();
var isTouch = svgedit.browser.isTouch();
2012-07-27 17:13:52 +00:00
var completed = true //for mousewheel
var $cursor = (area && this.dragCfg.cursor)
2012-07-24 02:30:12 +00:00
? $("<div class='draginput_cursor' />").appendTo($label)
: false
2012-07-25 06:32:18 +00:00
$input.attr("readonly", "readonly")
2012-07-24 12:42:34 +00:00
if ($cursor && !isNaN(this.dragCfg.start)) $cursor.css("top", (this.dragCfg.start*-1)/scale+cursorHeight)
2012-07-25 06:32:18 +00:00
2012-07-24 02:30:12 +00:00
//this is where all the magic happens
2012-07-27 17:13:52 +00:00
this.adjustValue = function(i, completed){
2012-07-24 02:30:12 +00:00
var v;
if(isNaN(this.value)) {
v = this.dragCfg.reset;
} else if($.isFunction(this.dragCfg.stepfunc)) {
v = this.dragCfg.stepfunc(this, i);
} else {
v = Number((Number(this.value) + Number(i)).toFixed(5));
}
if (max !== null) v = Math.min(v, max);
if (min !== null) v = Math.max(v, min);
if ($cursor) this.updateCursor(v);
this.value = v;
$label.attr("data-value", v)
2012-07-27 17:13:52 +00:00
if ($.isFunction(this.dragCfg.callback)) this.dragCfg.callback(this, completed)
2012-07-24 02:30:12 +00:00
};
$label.toggleClass("draginput", $label.is("label"))
// when the mouse is down and moving
this.move = function(e, oy, val) {
if (isTouch) {
e = e.originalEvent.touches[0]
}
// just got started let's save for undo purposes
if (lastY === 0) {
lastY = oy;
}
var deltaY = (e.pageY - lastY) *-1
lastY = e.pageY;
2012-07-26 05:52:06 +00:00
val = (deltaY * scale) * dragAdjust
2012-07-24 02:30:12 +00:00
var fixed = (step < 1) ? 1 : 0
this.adjustValue(val.toFixed(fixed)) //no undo true
};
//when the mouse is released
this.stop = function() {
$('body').removeClass('dragging');
2012-07-27 17:13:52 +00:00
$label.removeClass("active");
completed = true;
2012-07-24 02:30:12 +00:00
$(window).unbind("mousemove.draginput touchmove.draginput mouseup.draginput touchend.draginput");
lastY = 0;
if (selectedElems[0]) {
var batchCmd = canvas.undoMgr.finishUndoableChange();
if (!batchCmd.isEmpty()) canvas.undoMgr.addCommandToHistory(batchCmd);
}
2012-07-27 17:13:52 +00:00
this.adjustValue(0, completed)
2012-07-24 02:30:12 +00:00
}
this.updateCursor = function(){
var value = parseFloat(this.value)
var pos = (value*-1)/scale+cursorHeight
2012-07-25 06:32:18 +00:00
$cursor.css("top", pos)
2012-07-24 02:30:12 +00:00
}
this.start = function(e) {
if (isTouch) e = e.originalEvent.touches[0]
var oy = e.pageY;
var val = this.value;
var el = this;
canvas.undoMgr.beginUndoableChange(attr, selectedElems)
$('body').addClass('dragging');
$label.addClass('active');
$(window).bind("mousemove.draginput touchmove.draginput", function(e){el.move(e, oy, parseFloat(val))})
$(window).bind("mouseup.draginput touchend.draginput", function(e){el.stop()})
}
$(this)
.attr("readonly", "readonly")
.attr("data-scale", scale)
.attr("data-domain", cursorHeight)
.attr("data-cursor", ($cursor != false))
2012-07-25 06:32:18 +00:00
.bind("mousedown touchstart", function(e){
this.blur();
this.start(e);
})
2012-07-24 02:30:12 +00:00
.bind("dblclick taphold", function(e) {
this.removeAttribute("readonly", "readonly");
this.focus();
this.select();
})
.keydown(function(e){
2012-07-25 06:32:18 +00:00
// Respond to up/down arrow keys.
switch(e.keyCode){
case 13: this.adjustValue(0); this.blur(); break; // Enter
}
2012-07-24 02:30:12 +00:00
})
2012-07-25 06:32:18 +00:00
.focus(function(e){
if (this.getAttribute("readonly") === "readonly") this.blur()
2012-07-24 02:30:12 +00:00
})
2012-07-25 06:32:18 +00:00
.blur(function(e){
this.setAttribute("readonly", "readonly")
2012-07-24 02:30:12 +00:00
})
.bind("mousewheel", function(e, delta, deltaX, deltaY){
2012-07-27 17:13:52 +00:00
if (completed) canvas.undoMgr.beginUndoableChange(attr, selectedElems)
completed = false
clearTimeout(window.undoTimeout)
window.undoTimeout = setTimeout(function(){
wheel_input.stop()
},1000)
var wheel_input = this;
2012-07-24 02:30:12 +00:00
if (deltaY > 0)
2012-07-25 16:27:20 +00:00
this.adjustValue(this.dragCfg.step);
2012-07-24 02:30:12 +00:00
else if (deltaY < 0)
2012-07-25 16:27:20 +00:00
this.adjustValue(-this.dragCfg.step);
2012-07-24 02:30:12 +00:00
e.preventDefault();
2012-07-27 17:13:52 +00:00
2012-07-24 02:30:12 +00:00
})
2012-07-27 17:13:52 +00:00
});
2012-07-24 02:30:12 +00:00
};
// public function
$.fn.dragInput.updateCursor = function(el){
var value = parseFloat(el.value);
var scale = parseFloat(el.getAttribute("data-scale"));
var domain = parseFloat(el.getAttribute("data-domain"));
var pos = ((value*-1)/scale+domain) + "px";
2012-07-25 06:32:18 +00:00
var cursor = el.parentNode.lastChild
if (cursor.className == "draginput_cursor") cursor.style.top = pos;
2012-07-24 02:30:12 +00:00
}