mirror of
https://github.com/apankrat/nullboard.git
synced 2025-08-08 22:26:49 +02:00
redo Drag class
This commit is contained in:
355
nullboard.html
355
nullboard.html
@@ -555,6 +555,7 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
line-height: 22px;
|
line-height: 22px;
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
|
padding-bottom: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***/
|
/***/
|
||||||
@@ -1055,7 +1056,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.fsize-z1 .dragster.collapsed {
|
.fsize-z1 .dragster.collapsed {
|
||||||
line-height: 24px;
|
line-height: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fsize-z1 .board .note .ops {
|
.fsize-z1 .board .note .ops {
|
||||||
@@ -1242,7 +1243,7 @@
|
|||||||
{
|
{
|
||||||
this.type = '?';
|
this.type = '?';
|
||||||
|
|
||||||
this.conf = null;
|
this.conf = new AppConfig();
|
||||||
this.boardIndex = new Map();
|
this.boardIndex = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1501,8 +1502,6 @@
|
|||||||
{
|
{
|
||||||
var conf = this.getJson('config');
|
var conf = this.getJson('config');
|
||||||
|
|
||||||
this.conf = new AppConfig();
|
|
||||||
|
|
||||||
if (conf && (conf.format != NB.confVersion))
|
if (conf && (conf.format != NB.confVersion))
|
||||||
{
|
{
|
||||||
if (! confirm('Preferences are stored in an unsupported format. Reset them?'))
|
if (! confirm('Preferences are stored in an unsupported format. Reset them?'))
|
||||||
@@ -1633,21 +1632,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _rollback()
|
|
||||||
{
|
|
||||||
localStorage.removeItem('nullboard.config');
|
|
||||||
|
|
||||||
var metas = [];
|
|
||||||
|
|
||||||
for (var i=0; i<localStorage.length; i++)
|
|
||||||
{
|
|
||||||
var m = localStorage.key(i).match(/^nullboard\.board\.(\d+)\.meta$/);
|
|
||||||
if (m) metas.push(m[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var k of metas) localStorage.removeItem(k);
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
@@ -1692,35 +1676,42 @@
|
|||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
function Drag()
|
function Drag2()
|
||||||
{
|
{
|
||||||
this.item = null; // .text of .note
|
// config
|
||||||
this.org_loc = 0; // original noteLocation();
|
this.listSel = null;
|
||||||
this.priming = null;
|
this.itemSel = null;
|
||||||
this.primexy = { x: 0, y: 0 };
|
this.onDragging = function(started) { }
|
||||||
this.$drag = null;
|
this.swapAnimMs = 200;
|
||||||
this.mouse = null;
|
|
||||||
this.delta = { x: 0, y: 0 };
|
|
||||||
this.in_swap = false;
|
|
||||||
|
|
||||||
|
// state
|
||||||
|
this.item = null;
|
||||||
|
this.priming = null;
|
||||||
|
this.primeXY = { x: 0, y: 0 };
|
||||||
|
this.$drag = null;
|
||||||
|
this.mouseEv = null;
|
||||||
|
this.delta = { x: 0, y: 0 };
|
||||||
|
this.inSwap = 0;
|
||||||
|
|
||||||
|
// api
|
||||||
this.prime = function(item, ev)
|
this.prime = function(item, ev)
|
||||||
{
|
{
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
this.item = item;
|
this.item = item;
|
||||||
this.priming = setTimeout(function(){ self.onPrimed.call(self); }, ev.altKey ? 1 : 500);
|
this.priming = setTimeout(function(){ self.onPrimed.call(self); }, ev.altKey ? 1 : 500);
|
||||||
this.primexy.x = ev.clientX;
|
this.primeXY = { x: ev.clientX, y: ev.clientY };
|
||||||
this.primexy.y = ev.clientY;
|
this.mouseEv = ev;
|
||||||
this.mouse = ev;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.cancelPriming = function()
|
this.cancelPriming = function()
|
||||||
{
|
{
|
||||||
if (this.item && this.priming)
|
if (! this.item || ! this.priming)
|
||||||
{
|
return;
|
||||||
clearTimeout(this.priming);
|
|
||||||
this.priming = null;
|
clearTimeout(this.priming);
|
||||||
this.item = null;
|
this.priming = null;
|
||||||
}
|
this.item = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.end = function()
|
this.end = function()
|
||||||
@@ -1736,36 +1727,34 @@
|
|||||||
|
|
||||||
this.onPrimed = function()
|
this.onPrimed = function()
|
||||||
{
|
{
|
||||||
|
console.log('onPrimed');
|
||||||
|
|
||||||
clearTimeout(this.priming);
|
clearTimeout(this.priming);
|
||||||
this.priming = null;
|
this.priming = null;
|
||||||
this.item.was_dragged = true;
|
|
||||||
|
|
||||||
var $text = $(this.item);
|
removeTextSelection();
|
||||||
var $note = $text.parent();
|
|
||||||
$note.addClass('dragging');
|
|
||||||
|
|
||||||
this.org_loc = noteLocation($note);
|
var $item = $(this.item);
|
||||||
|
$item.addClass('dragging');
|
||||||
|
|
||||||
$('body').append('<div class=dragster></div>');
|
$('body').append('<div class=dragster></div>');
|
||||||
var $drag = $('body .dragster').last();
|
var $drag = $('body .dragster').last();
|
||||||
|
|
||||||
if ($note.hasClass('collapsed'))
|
$drag.innerWidth ( $item.innerWidth() );
|
||||||
$drag.addClass('collapsed');
|
$drag.innerHeight( $item.innerHeight() );
|
||||||
|
|
||||||
$drag.html( $text.html() );
|
|
||||||
|
|
||||||
$drag.innerWidth ( $note.innerWidth() );
|
|
||||||
$drag.innerHeight( $note.innerHeight() );
|
|
||||||
|
|
||||||
this.$drag = $drag;
|
this.$drag = $drag;
|
||||||
|
|
||||||
|
if (this.onDragging)
|
||||||
|
this.onDragging.call(this, true); // started
|
||||||
|
|
||||||
var $win = $(window);
|
var $win = $(window);
|
||||||
var scroll_x = $win.scrollLeft();
|
var scroll_x = $win.scrollLeft();
|
||||||
var scroll_y = $win.scrollTop();
|
var scroll_y = $win.scrollTop();
|
||||||
|
|
||||||
var pos = $note.offset();
|
var pos = $item.offset();
|
||||||
this.delta.x = pos.left - this.mouse.clientX - scroll_x;
|
this.delta.x = pos.left - this.mouseEv.clientX - scroll_x;
|
||||||
this.delta.y = pos.top - this.mouse.clientY - scroll_y;
|
this.delta.y = pos.top - this.mouseEv.clientY - scroll_y;
|
||||||
this.adjustDrag();
|
this.adjustDrag();
|
||||||
|
|
||||||
$drag.css({ opacity: 1 });
|
$drag.css({ opacity: 1 });
|
||||||
@@ -1778,163 +1767,194 @@
|
|||||||
if (! this.$drag)
|
if (! this.$drag)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var drag = this;
|
||||||
|
var $drag = this.$drag;
|
||||||
|
|
||||||
var $win = $(window);
|
var $win = $(window);
|
||||||
var scroll_x = $win.scrollLeft();
|
var scroll_x = $win.scrollLeft();
|
||||||
var scroll_y = $win.scrollTop();
|
var scroll_y = $win.scrollTop();
|
||||||
|
|
||||||
var drag_x = this.mouse.clientX + this.delta.x + scroll_x;
|
var drag_x = drag.mouseEv.clientX + drag.delta.x + scroll_x;
|
||||||
var drag_y = this.mouse.clientY + this.delta.y + scroll_y;
|
var drag_y = drag.mouseEv.clientY + drag.delta.y + scroll_y;
|
||||||
|
|
||||||
this.$drag.offset({ left: drag_x, top: drag_y });
|
$drag.offset({ left: drag_x, top: drag_y });
|
||||||
|
|
||||||
if (this.in_swap)
|
if (drag.inSwap)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* see if a swap is in order
|
* see if a swap is in order
|
||||||
*/
|
*/
|
||||||
var pos = this.$drag.offset();
|
var pos = $drag.offset();
|
||||||
var x = pos.left + this.$drag.width()/2 - $win.scrollLeft();
|
var x = pos.left + $drag.width()/2 - $win.scrollLeft();
|
||||||
var y = pos.top + this.$drag.height()/2 - $win.scrollTop();
|
var y = pos.top + $drag.height()/2 - $win.scrollTop();
|
||||||
|
|
||||||
var drag = this;
|
|
||||||
var prepend = null; // if dropping on the list header
|
|
||||||
var target = null; // if over some item
|
var target = null; // if over some item
|
||||||
var before = false; // if should go before that item
|
var before = false; // if should go before that item
|
||||||
|
|
||||||
$(".board .list").each(function(){
|
$(this.listSel).each(function(){
|
||||||
|
|
||||||
var list = this;
|
var list = this;
|
||||||
var rc = list.getBoundingClientRect();
|
var rcList = list.getBoundingClientRect();
|
||||||
var y_min = rc.bottom;
|
var yTop, itemTop = null;
|
||||||
var n_min = null;
|
var yBottom, itemBottom = null;
|
||||||
|
|
||||||
if (x <= rc.left || rc.right <= x || y <= rc.top || rc.bottom <= y)
|
if (x <= rcList.left || rcList.right <= x)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var $list = $(list);
|
$(list).find(drag.itemSel).each(function(){
|
||||||
|
var rcItem = this.getBoundingClientRect();
|
||||||
|
|
||||||
$list.find('.note').each(function(){
|
if (! itemTop || rcItem.top < yTop)
|
||||||
var note = this;
|
|
||||||
var rc = note.getBoundingClientRect();
|
|
||||||
|
|
||||||
if (rc.top < y_min)
|
|
||||||
{
|
{
|
||||||
y_min = rc.top;
|
itemTop = this;
|
||||||
n_min = note;
|
yTop = rcItem.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y <= rc.top || rc.bottom <= y)
|
if (! itemBottom || yBottom < rcItem.bottom)
|
||||||
|
{
|
||||||
|
itemBottom = this;
|
||||||
|
yBottom = rcItem.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y <= rcItem.top || rcItem.bottom <= y)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (note == drag.item.parentNode)
|
if (this == drag.item)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
target = note;
|
target = this;
|
||||||
before = (y < (rc.top + rc.bottom)/2);
|
before = (y < (rcItem.top + rcItem.bottom)/2);
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
if (y < rcList.top)
|
||||||
* dropping on the list header
|
|
||||||
*/
|
|
||||||
if (! target && y < y_min)
|
|
||||||
{
|
{
|
||||||
if (n_min) // non-empty list
|
target = itemTop;
|
||||||
{
|
before = true;
|
||||||
target = n_min;
|
|
||||||
before = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prepend = list;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if (y >= rcList.bottom)
|
||||||
|
{
|
||||||
|
target = itemBottom;
|
||||||
|
before = false;
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (! target && ! prepend)
|
if (! target)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (target)
|
if (target == drag.item)
|
||||||
{
|
return;
|
||||||
if (target == drag.item.parentNode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (! before && target.nextSibling == drag.item.parentNode ||
|
if (! before && $(target).next()[0] == drag.item ||
|
||||||
before && target.previousSibling == drag.item.parentNode)
|
before && $(target).prev()[0] == drag.item)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (prepend.firstChild == drag.item.parentNode)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* swap 'em
|
* swap 'em
|
||||||
*/
|
*/
|
||||||
var $have = $(this.item.parentNode);
|
var $target = $(target);
|
||||||
|
|
||||||
|
var have = drag.item;
|
||||||
|
var $have = $(have);
|
||||||
var $want = $have.clone();
|
var $want = $have.clone();
|
||||||
|
|
||||||
$want.css({ display: 'none' });
|
$want.css({ display: 'none' });
|
||||||
|
|
||||||
if (target)
|
if (before)
|
||||||
{
|
{
|
||||||
var $target = $(target);
|
$want.insertBefore($target);
|
||||||
|
$want = $target.prev();
|
||||||
if (before)
|
|
||||||
{
|
|
||||||
$want.insertBefore($target);
|
|
||||||
$want = $target.prev();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$want.insertAfter($target);
|
|
||||||
$want = $target.next();
|
|
||||||
}
|
|
||||||
|
|
||||||
drag.item = $want.find('.text')[0];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var $notes = $(prepend).find('.notes');
|
$want.insertAfter($target);
|
||||||
|
$want = $target.next();
|
||||||
$notes.prepend($want);
|
|
||||||
|
|
||||||
drag.item = $notes.find('.note .text')[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
drag.item = $want[0];
|
||||||
var h = $have.height();
|
|
||||||
|
|
||||||
drag.in_swap = true;
|
if (! drag.swapAnimMs)
|
||||||
|
{
|
||||||
|
$have.remove();
|
||||||
|
$want.show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$want.css({ display: 'block', height: 0, marginTop: 0 });
|
/*
|
||||||
|
* see if it's a same-list move
|
||||||
|
*/
|
||||||
|
if (target.parentNode == have.parentNode)
|
||||||
|
{
|
||||||
|
var delta = $have.offset().top - $target.offset().top;
|
||||||
|
|
||||||
|
var d_bulk = 0;
|
||||||
|
var d_have = 0;
|
||||||
|
var $bulk = $();
|
||||||
|
|
||||||
|
if (delta < 0) // item is moving down
|
||||||
|
{
|
||||||
|
for (var $i = $have.next(); $i.length && $i[0] != $want[0]; $i = $i.next())
|
||||||
|
$bulk = $bulk.add($i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (var $i = $want.next(); $i.length && $i[0] != $have[0]; $i = $i.next())
|
||||||
|
$bulk = $bulk.add($i);
|
||||||
|
}
|
||||||
|
|
||||||
|
d_bulk = $have.outerHeight(true);
|
||||||
|
d_have = $bulk.last().offset().top + $bulk.last().outerHeight(true) - $bulk.first().offset().top;
|
||||||
|
|
||||||
|
if (delta < 0) d_bulk = -d_bulk;
|
||||||
|
else d_have = -d_have;
|
||||||
|
|
||||||
|
$have.parent().css({ position: 'relative' });
|
||||||
|
$have.css({ position: 'relative', 'z-index': 0 });
|
||||||
|
$bulk.css({ position: 'relative', 'z-index': 1 });
|
||||||
|
|
||||||
|
drag.inSwap = 1 + $bulk.length;
|
||||||
|
|
||||||
|
$have.animate({ top: d_have }, drag.swapAnimMs, function(){ if (! --drag.inSwap) swapCleanUp(); });
|
||||||
|
$bulk.animate({ top: d_bulk }, drag.swapAnimMs, function(){ if (! --drag.inSwap) swapCleanUp(); });
|
||||||
|
|
||||||
|
function swapCleanUp()
|
||||||
|
{
|
||||||
|
$have.parent().css({ position: '' });
|
||||||
|
|
||||||
$want.animate({ height: h }, {
|
|
||||||
duration: 'fast',
|
|
||||||
progress: function() {
|
|
||||||
$have.height( h - $(this).height() );
|
|
||||||
},
|
|
||||||
complete: function() {
|
|
||||||
$have.remove();
|
$have.remove();
|
||||||
$want.css({ marginTop: 5, opacity: '', height: '' });
|
$want.show();
|
||||||
drag.in_swap = false;
|
$bulk.css({ position: '', 'z-index': '', top: '' });
|
||||||
|
|
||||||
drag.adjustDrag();
|
drag.adjustDrag();
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
drag.inSwap = 1;
|
||||||
|
|
||||||
|
$want.slideDown(drag.swapAnimMs);
|
||||||
|
|
||||||
|
$have.slideUp(drag.swapAnimMs, function() {
|
||||||
|
$have.remove();
|
||||||
|
drag.inSwap = 0;
|
||||||
|
drag.adjustDrag();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onMouseMove = function(ev)
|
this.onMouseMove = function(ev)
|
||||||
{
|
{
|
||||||
this.mouse = ev;
|
this.mouseEv = ev;
|
||||||
|
|
||||||
if (! this.item)
|
if (! this.item)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (this.priming)
|
if (this.priming)
|
||||||
{
|
{
|
||||||
var x = ev.clientX - this.primexy.x;
|
var x = ev.clientX - this.primeXY.x;
|
||||||
var y = ev.clientY - this.primexy.y;
|
var y = ev.clientY - this.primeXY.y;
|
||||||
if (x*x + y*y > 5*5)
|
if (x*x + y*y > 5*5)
|
||||||
this.onPrimed();
|
this.onPrimed();
|
||||||
}
|
}
|
||||||
@@ -1946,11 +1966,9 @@
|
|||||||
|
|
||||||
this.stopDragging = function()
|
this.stopDragging = function()
|
||||||
{
|
{
|
||||||
var $text = $(this.item);
|
var $item = $(this.item);
|
||||||
var $note = $text.parent();
|
|
||||||
$note.addClass('dragging');
|
|
||||||
|
|
||||||
$note.removeClass('dragging');
|
$item.removeClass('dragging');
|
||||||
$('body').removeClass('dragging');
|
$('body').removeClass('dragging');
|
||||||
|
|
||||||
if (this.$drag)
|
if (this.$drag)
|
||||||
@@ -1958,12 +1976,10 @@
|
|||||||
this.$drag.remove();
|
this.$drag.remove();
|
||||||
this.$drag = null;
|
this.$drag = null;
|
||||||
|
|
||||||
if (window.getSelection) { window.getSelection().removeAllRanges(); }
|
removeTextSelection();
|
||||||
else if (document.selection) { document.selection.empty(); }
|
|
||||||
|
|
||||||
var loc_now = noteLocation($note);
|
if (this.onDragging)
|
||||||
if (loc_now != this.org_loc)
|
this.onDragging.call(this, false); // stopped
|
||||||
saveBoard();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.item = null;
|
this.item = null;
|
||||||
@@ -2582,6 +2598,12 @@
|
|||||||
return $note.attr('_text');
|
return $note.attr('_text');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeTextSelection()
|
||||||
|
{
|
||||||
|
if (window.getSelection) { window.getSelection().removeAllRanges(); }
|
||||||
|
else if (document.selection) { document.selection.empty(); }
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* inline editing
|
* inline editing
|
||||||
*/
|
*/
|
||||||
@@ -2846,7 +2868,34 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
NB.storage = new Storage_Local();
|
NB.storage = new Storage_Local();
|
||||||
NB.drag = new Drag(),
|
NB.drag = new Drag2();
|
||||||
|
|
||||||
|
NB.drag.listSel = '.board .list';
|
||||||
|
NB.drag.itemSel = '.note';
|
||||||
|
NB.drag.onDragging = function(started)
|
||||||
|
{
|
||||||
|
var drag = this;
|
||||||
|
var $note = $(drag.item);
|
||||||
|
|
||||||
|
if (started)
|
||||||
|
{
|
||||||
|
var $drag = drag.$drag;
|
||||||
|
|
||||||
|
if ($note.hasClass('collapsed'))
|
||||||
|
$drag.addClass('collapsed');
|
||||||
|
|
||||||
|
$drag.html( $note.find('.text').html() );
|
||||||
|
|
||||||
|
drag.org_loc = noteLocation($note);
|
||||||
|
if ($note.hasClass('collapsed'))
|
||||||
|
drag.$drag.addClass('collapsed');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (drag.org_log != noteLocation($note))
|
||||||
|
saveBoard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* event handlers
|
* event handlers
|
||||||
@@ -3101,7 +3150,7 @@
|
|||||||
|
|
||||||
//
|
//
|
||||||
$('.wrap').on('mousedown', '.board .note .text', function(ev){
|
$('.wrap').on('mousedown', '.board .note .text', function(ev){
|
||||||
NB.drag.prime(this, ev);
|
NB.drag.prime(this.parentNode, ev);
|
||||||
});
|
});
|
||||||
|
|
||||||
$(document).on('mouseup', function(ev){
|
$(document).on('mouseup', function(ev){
|
||||||
|
Reference in New Issue
Block a user