add zoom to mouse position when using scrollwheel
This commit is contained in:
parent
e02e77605f
commit
02a3b5c6a1
4 changed files with 269 additions and 64 deletions
|
@ -1646,7 +1646,7 @@ Miscellaneous
|
|||
position: absolute;
|
||||
padding: 1px 2px 1px 2px;
|
||||
font-size: 9px;
|
||||
opacity: 0;
|
||||
//opacity: 0;
|
||||
z-index: 12;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
|
|
|
@ -2484,6 +2484,31 @@ Ox.stripTags = function(str) {
|
|||
return str.replace(/(<.*?>)/gi, '');
|
||||
};
|
||||
|
||||
Ox.substr = function(str, start, stop) {
|
||||
/***
|
||||
Ox.substr behaves like str[start:stop] in Python
|
||||
(or like str.substring() with negative values for stop)
|
||||
not implemented
|
||||
>>> Ox.substr('foobar', 1)
|
||||
"oobar"
|
||||
>>> Ox.substr('foobar', -1)
|
||||
"r"
|
||||
>>> Ox.substr('foobar', 1, 3)
|
||||
"oo"
|
||||
>>> Ox.substr('foobar', -3, 5)
|
||||
"ba"
|
||||
>>> Ox.substr('foobar', 1, -2)
|
||||
"oob"
|
||||
>>> Ox.substr('foobar', -4, -1)
|
||||
"oba"
|
||||
***/
|
||||
stop = Ox.isUndefined(stop) ? str.length : stop;
|
||||
return str.substring(
|
||||
start < 0 ? str.length + start : start,
|
||||
stop < 0 ? str.length + stop : stop
|
||||
);
|
||||
};
|
||||
|
||||
Ox.toCamelCase = function(str) {
|
||||
/*
|
||||
>>> Ox.toCamelCase("foo-bar-baz")
|
||||
|
|
|
@ -883,6 +883,13 @@ requires
|
|||
Basic element object
|
||||
***/
|
||||
|
||||
/*
|
||||
tooltip option can be any of the following:
|
||||
string
|
||||
function(e), returns string
|
||||
{mousemove: true, title: function(e)}
|
||||
*/
|
||||
|
||||
return function(options, self) {
|
||||
|
||||
if (!(this instanceof arguments.callee)) {
|
||||
|
@ -901,8 +908,19 @@ requires
|
|||
self.$eventHandler = $('<div>');
|
||||
}
|
||||
|
||||
var that = new Ox.$Element($('<' + (self.options.element || 'div') + '>'));
|
||||
that.$element.mousedown(mousedown);
|
||||
var that = new Ox.$Element(
|
||||
$('<' + (self.options.element || 'div') + '>')
|
||||
)
|
||||
.mousedown(mousedown);
|
||||
|
||||
/*
|
||||
self.options.tooltip && that.bind(Ox.extend({
|
||||
mouseenter: mouseenter,
|
||||
mouseleave: mouseleave
|
||||
}, self.options.tooltip.mousemove ? {
|
||||
mousemove: mousemove
|
||||
} : {}));
|
||||
*/
|
||||
|
||||
function mousedown(e) {
|
||||
/*
|
||||
|
@ -987,6 +1005,26 @@ requires
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
function mouseenter(e) {
|
||||
self.$tooltip = new Ox.Tooltip({
|
||||
title: Ox.isString(self.options.tooltip) ?
|
||||
self.options.tooltip : Ox.isFunction(self.options.tooltip) ?
|
||||
self.options.tooltip(e) : self.options.tooltip.title(e)
|
||||
}).show();
|
||||
}
|
||||
|
||||
function mouseleave(e) {
|
||||
self.$tooltip.hide();
|
||||
}
|
||||
|
||||
function mousemove(e) {
|
||||
self.$tooltip.options({
|
||||
title: self.options.tooltip.title(e)
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
self.onChange = function() {
|
||||
// self.onChange(key, value)
|
||||
// is called when an option changes
|
||||
|
@ -10308,20 +10346,21 @@ requires
|
|||
|
||||
Ox.MapPlace = function(options) {
|
||||
|
||||
var options = Ox.extend({
|
||||
east: 0,
|
||||
editing: false,
|
||||
geoname: '',
|
||||
map: null,
|
||||
name: '',
|
||||
north: 0,
|
||||
selected: false,
|
||||
south: 0,
|
||||
type: [],
|
||||
visible: false,
|
||||
west: 0
|
||||
}, options),
|
||||
that = this;
|
||||
options = Ox.extend({
|
||||
east: 0,
|
||||
editing: false,
|
||||
geoname: '',
|
||||
map: null,
|
||||
name: '',
|
||||
north: 0,
|
||||
selected: false,
|
||||
south: 0,
|
||||
type: [],
|
||||
visible: false,
|
||||
west: 0
|
||||
}, options);
|
||||
|
||||
var that = this;
|
||||
|
||||
Ox.forEach(options, function(val, key) {
|
||||
that[key] = val;
|
||||
|
@ -10865,6 +10904,7 @@ requires
|
|||
height: self.options.height + 'px'
|
||||
});
|
||||
|
||||
self.maxZoom = 28;
|
||||
self.overlayWidths = [Math.round(self.options.width / 16)];
|
||||
self.overlayWidths = [
|
||||
Math.floor((self.options.width - self.overlayWidths[0]) / 2),
|
||||
|
@ -10984,7 +11024,11 @@ requires
|
|||
top: '24px',
|
||||
bottom: '40px'
|
||||
})
|
||||
.mousewheel(mousewheel)
|
||||
.bind({
|
||||
mouseleave: mouseleave,
|
||||
mousemove: mousemove,
|
||||
mousewheel: mousewheel
|
||||
})
|
||||
.bindEvent({
|
||||
dragstart: dragstart,
|
||||
drag: drag,
|
||||
|
@ -11041,17 +11085,16 @@ requires
|
|||
})
|
||||
.appendTo(that);
|
||||
|
||||
self.$zoombar = new Ox.Bar({
|
||||
size: 16
|
||||
})
|
||||
self.$zoombar = new Ox.Element()
|
||||
.css({
|
||||
position: 'absolute',
|
||||
bottom: 24 + 'px'
|
||||
bottom: 24 + 'px',
|
||||
height: '16px'
|
||||
})
|
||||
.appendTo(that);
|
||||
self.$zoomInput = new Ox.Range({
|
||||
arrows: true,
|
||||
max: 28,
|
||||
max: self.maxZoom,
|
||||
min: 0,
|
||||
size: self.options.width,
|
||||
thumbSize: 32,
|
||||
|
@ -11063,6 +11106,24 @@ requires
|
|||
})
|
||||
.appendTo(self.$zoombar);
|
||||
|
||||
self.$statusbar = new Ox.Bar({
|
||||
size: 24
|
||||
})
|
||||
.css({
|
||||
// fixme: no need to set position absolute with map statusbar
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
textAlign: 'center'
|
||||
})
|
||||
.appendTo(that);
|
||||
|
||||
self.$tooltip = new Ox.Tooltip({
|
||||
animate: false
|
||||
})
|
||||
.css({
|
||||
textAlign: 'center'
|
||||
});
|
||||
|
||||
sortDates();
|
||||
renderTimelines();
|
||||
renderDates();
|
||||
|
@ -11096,6 +11157,7 @@ requires
|
|||
}
|
||||
|
||||
function dragpause(event, e) {
|
||||
return;
|
||||
if (self.drag) {
|
||||
Ox.print('dragpause')
|
||||
dragafter();
|
||||
|
@ -11127,6 +11189,7 @@ requires
|
|||
}
|
||||
|
||||
function dragpauseScrollbar(event, e) {
|
||||
return;
|
||||
self.drag = {x: e.clientX};
|
||||
dragafter();
|
||||
}
|
||||
|
@ -11149,6 +11212,50 @@ requires
|
|||
$('.OxDate').remove();
|
||||
renderTimelines();
|
||||
renderDates();
|
||||
var calendarDate = getCalendarDate();
|
||||
self.$statusbar.html(
|
||||
calendarDate.start + ' | ' + self.options.date + ' | ' + calendarDate.stop
|
||||
);
|
||||
}
|
||||
|
||||
function formatDate(date) {
|
||||
var isFullDays = Ox.formatDate(date.start, '%H:%M:%S') == '00:00:00' &&
|
||||
Ox.formatDate(date.stop, '%H:%M:%S') == '00:00:00',
|
||||
isOneDay = isFullDays && date.stop - date.start == 86400000, // fixme: wrong, DST
|
||||
isSameDay = Ox.formatDate(date.start, '%Y-%m-%d') ==
|
||||
Ox.formatDate(date.stop, '%Y-%m-%d'),
|
||||
isSameYear = date.start.getFullYear() == date.stop.getFullYear(),
|
||||
timeFormat = isFullDays ? '' : ', %H:%M:%S',
|
||||
str = Ox.formatDate(date.start, '%a, %b %e');
|
||||
if (isOneDay || isSameDay || !isSameYear) {
|
||||
str += Ox.formatDate(date.start, ', %Y' + timeFormat);
|
||||
}
|
||||
if (!isOneDay && !isSameDay) {
|
||||
str += Ox.formatDate(date.stop, ' - %a, %b %e, %Y' + timeFormat);
|
||||
}
|
||||
if (isSameDay) {
|
||||
str += Ox.formatDate(date.stop, ' - ' + timeFormat.replace(', ', ''));
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function getCalendarDate() {
|
||||
var ms = self.options.width * getSecondsPerPixel() * 1000;
|
||||
return {
|
||||
start: new Date(+self.options.date - ms / 2),
|
||||
stop: new Date(+self.options.date + ms / 2)
|
||||
};
|
||||
}
|
||||
|
||||
function getDateByName(name) {
|
||||
var date = {};
|
||||
Ox.forEach(self.options.dates, function(v) {
|
||||
if (v.name == name) {
|
||||
date = v;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return date;
|
||||
}
|
||||
|
||||
function getDateElement(date, zoom) {
|
||||
|
@ -11156,24 +11263,26 @@ requires
|
|||
width = Math.max(getPosition(date.stop, zoom) - left, 1);
|
||||
return new Ox.Element()
|
||||
.addClass('OxDate')
|
||||
.attr({
|
||||
title: date.name
|
||||
})
|
||||
.css({
|
||||
left: left + 'px',
|
||||
width: width + 'px'
|
||||
})
|
||||
.data({
|
||||
name: date.name
|
||||
})
|
||||
.html(' ' + date.name);
|
||||
}
|
||||
|
||||
function getMouseDate(e) {
|
||||
return new Date(+self.options.date + (
|
||||
e.clientX - that.offset().left - self.options.width / 2 - 1
|
||||
) * getSecondsPerPixel() * 1000);
|
||||
}
|
||||
|
||||
function getPixelsPerSecond(zoom) {
|
||||
return Math.pow(2, (zoom || self.options.zoom) - 24);
|
||||
}
|
||||
|
||||
function getSecondsPerPixel(zoom) {
|
||||
return 1 / getPixelsPerSecond(zoom);
|
||||
}
|
||||
|
||||
function getPosition(date, zoom) {
|
||||
zoom = zoom || self.options.zoom
|
||||
return Math.round(
|
||||
|
@ -11182,6 +11291,10 @@ requires
|
|||
);
|
||||
}
|
||||
|
||||
function getSecondsPerPixel(zoom) {
|
||||
return 1 / getPixelsPerSecond(zoom);
|
||||
}
|
||||
|
||||
function getTimelineElements(zoom) {
|
||||
var $elements = [],
|
||||
pixelsPerSecond = getPixelsPerSecond(zoom),
|
||||
|
@ -11210,10 +11323,36 @@ requires
|
|||
return $elements;
|
||||
}
|
||||
|
||||
function mousewheel(event, delta, deltaX, deltaY) {
|
||||
function mouseleave() {
|
||||
self.$tooltip.hide();
|
||||
}
|
||||
|
||||
function mousemove(e) {
|
||||
var $target = $(e.target),
|
||||
date, title;
|
||||
if ($target.is('.OxLine > .OxDate')) {
|
||||
date = getDateByName($target.data('name'));
|
||||
title = '<span class="OxBright">' + date.name + '</span><br/>' +
|
||||
formatDate(date);
|
||||
} else {
|
||||
title = Ox.formatDate(getMouseDate(e), '%a, %b %e, %Y, %H:%M:%S');
|
||||
}
|
||||
self.$tooltip.options({
|
||||
title: title
|
||||
})
|
||||
.show(e.clientX, e.clientY);
|
||||
}
|
||||
|
||||
function mousewheel(e, delta, deltaX, deltaY) {
|
||||
Ox.print('mousewheel', delta, deltaX, deltaY);
|
||||
if (!self.mousewheel && deltaY && Math.abs(deltaY) > Math.abs(deltaX)) {
|
||||
self.options.zoom += deltaY < 0 ? -1 : 1;
|
||||
self.options.date = deltaY < 0 ?
|
||||
new Date(2 * +self.options.date - +getMouseDate(e)) :
|
||||
new Date((+self.options.date + +getMouseDate(e)) / 2)
|
||||
self.options.zoom = Ox.limit(self.options.zoom + (
|
||||
deltaY < 0 ? -1 : 1
|
||||
), 0, self.maxZoom);
|
||||
self.$zoomInput.options({value: self.options.zoom});
|
||||
$('.OxDate').remove();
|
||||
renderTimelines();
|
||||
renderDates();
|
||||
|
@ -11294,6 +11433,32 @@ requires
|
|||
|
||||
};
|
||||
|
||||
Ox.CalendarDate = function(options) {
|
||||
|
||||
var self = {},
|
||||
that = this;
|
||||
|
||||
['start', 'stop'].forEach(function(v) {
|
||||
var date = self.options[v];
|
||||
if (Ox.isString(date)) {
|
||||
date = new Date(self.options[v]);
|
||||
}
|
||||
});
|
||||
|
||||
self.duration = self.options.stop - self.options.start;
|
||||
|
||||
that.format = function() {
|
||||
|
||||
};
|
||||
|
||||
that.formatDuration = function() {
|
||||
|
||||
};
|
||||
|
||||
return that;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
============================================================================
|
||||
Menus
|
||||
|
@ -13024,6 +13189,11 @@ requires
|
|||
$markerPoint: [],
|
||||
$selection: [],
|
||||
$subtitles: [],
|
||||
$tooltip: new Ox.Tooltip({
|
||||
animate: false
|
||||
}).css({
|
||||
textAlign: 'center'
|
||||
}),
|
||||
hasSubtitles: self.options.subtitles.length,
|
||||
height: 16,
|
||||
lines: Math.ceil(self.options.duration / self.options.width),
|
||||
|
@ -13245,7 +13415,7 @@ requires
|
|||
}
|
||||
|
||||
function mouseleave(e) {
|
||||
self.$tooltip && self.$tooltip.hide();
|
||||
self.$tooltip.hide();
|
||||
}
|
||||
|
||||
function mousemove(e) {
|
||||
|
@ -13259,19 +13429,16 @@ requires
|
|||
) {
|
||||
position = getPosition(e),
|
||||
subtitle = getSubtitle(position);
|
||||
self.$tooltip = new Ox.Tooltip({
|
||||
self.$tooltip.options({
|
||||
title: subtitle ?
|
||||
'<span class=\'OxBright\'>' +
|
||||
Ox.highlight(subtitle.value, self.options.find).replace(/\n/g, '<br/>') + '</span><br/>' +
|
||||
Ox.formatDuration(subtitle['in'], 3) + ' - ' + Ox.formatDuration(subtitle['out'], 3) :
|
||||
Ox.formatDuration(position, 3)
|
||||
})
|
||||
.css({
|
||||
textAlign: 'center'
|
||||
})
|
||||
.show(e.clientX, e.clientY);
|
||||
} else {
|
||||
self.$tooltip && self.$tooltip.hide();
|
||||
self.$tooltip.hide();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13482,7 +13649,9 @@ requires
|
|||
$markerPoint: [],
|
||||
$subtitles: [],
|
||||
$tiles: {},
|
||||
$tooltip: new Ox.Tooltip(),
|
||||
$tooltip: new Ox.Tooltip({
|
||||
animate: false
|
||||
}),
|
||||
center: parseInt(self.options.width / 2),
|
||||
element: that.$element[0],
|
||||
fps: 25,
|
||||
|
@ -13543,8 +13712,7 @@ requires
|
|||
|
||||
function click(event, e) {
|
||||
self.options.position = Ox.limit(
|
||||
self.options.position + (e.clientX - that.$element.offset().left - self.center - 1) / self.fps,
|
||||
0, self.options.duration
|
||||
getPosition(e), 0, self.options.duration
|
||||
);
|
||||
setPosition();
|
||||
triggerChangeEvent();
|
||||
|
@ -13564,6 +13732,10 @@ requires
|
|||
triggerChangeEvent();
|
||||
}
|
||||
|
||||
function getPosition(e) {
|
||||
return self.options.position + (e.clientX - that.offset().left - self.center - 1) / self.fps
|
||||
}
|
||||
|
||||
function mouseleave(e) {
|
||||
self.clientX = 0;
|
||||
self.clientY = 0;
|
||||
|
@ -13632,8 +13804,7 @@ requires
|
|||
}
|
||||
|
||||
function updateTooltip() {
|
||||
// fixme: duplicated, need getPosition(e)
|
||||
var position = self.options.position + (self.clientX - that.offset().left - self.center - 1) / self.fps;
|
||||
var position = getPosition(self);
|
||||
if (position >= 0 && position <= self.options.duration) {
|
||||
self.$tooltip
|
||||
.options({
|
||||
|
@ -13689,6 +13860,11 @@ requires
|
|||
$images: [],
|
||||
$markerPoint: [],
|
||||
$subtitles: [],
|
||||
$tooltip: new Ox.Tooltip({
|
||||
animate: false
|
||||
}).css({
|
||||
textAlign: 'center'
|
||||
}),
|
||||
hasSubtitles: self.options.subtitles.length,
|
||||
height: 16,
|
||||
margin: 8
|
||||
|
@ -13770,7 +13946,7 @@ requires
|
|||
}
|
||||
|
||||
function mouseleave(e) {
|
||||
self.$tooltip && self.$tooltip.hide();
|
||||
self.$tooltip.hide();
|
||||
}
|
||||
|
||||
function mousemove(e) {
|
||||
|
@ -13783,19 +13959,16 @@ requires
|
|||
) {
|
||||
position = getPosition(e),
|
||||
subtitle = getSubtitle(position);
|
||||
self.$tooltip = new Ox.Tooltip({
|
||||
self.$tooltip.options({
|
||||
title: subtitle ?
|
||||
'<span class=\'OxBright\'>' +
|
||||
Ox.highlight(subtitle.value, self.options.find).replace(/\n/g, '<br/>') + '</span><br/>' +
|
||||
Ox.formatDuration(subtitle['in'], 3) + ' - ' + Ox.formatDuration(subtitle['out'], 3) :
|
||||
Ox.formatDuration(position, 3)
|
||||
})
|
||||
.css({
|
||||
textAlign: 'center'
|
||||
})
|
||||
.show(e.clientX, e.clientY);
|
||||
} else {
|
||||
self.$tooltip && self.$tooltip.hide();
|
||||
self.$tooltip.hide();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15207,7 +15380,7 @@ requires
|
|||
change: changeSmallTimeline
|
||||
})
|
||||
};
|
||||
self.$timeline.forEach(function($timeline) {
|
||||
Ox.forEach(self.$timeline, function($timeline) {
|
||||
$timeline.appendTo(self.$timelines);
|
||||
});
|
||||
|
||||
|
@ -15440,19 +15613,22 @@ requires
|
|||
============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
*/
|
||||
Ox.Tooltip = function(options, self) {
|
||||
|
||||
var self = self || {},
|
||||
that = new Ox.Element('div', self)
|
||||
.defaults({
|
||||
animate: true,
|
||||
title: ''
|
||||
})
|
||||
.options(options || {})
|
||||
.addClass('OxTooltip')
|
||||
.html(self.options.title);
|
||||
|
||||
self.options.animate && that.css({
|
||||
opacity: 0
|
||||
});
|
||||
|
||||
self.onChange = function(key, value) {
|
||||
if (key == 'title') {
|
||||
that.html(value);
|
||||
|
@ -15460,29 +15636,33 @@ requires
|
|||
};
|
||||
|
||||
that.hide = function() {
|
||||
that.animate({
|
||||
opacity: 0
|
||||
}, 0, function() {
|
||||
if (self.options.animate) {
|
||||
that.animate({
|
||||
opacity: 0
|
||||
}, 250, function() {
|
||||
that.removeElement();
|
||||
});
|
||||
} else {
|
||||
that.removeElement();
|
||||
});
|
||||
}
|
||||
return that;
|
||||
};
|
||||
|
||||
that.show = function(x, y) {
|
||||
var left, top, width, height;
|
||||
$('.OxTooltip').remove(); // fixme: don't use dom
|
||||
$('.OxTooltip').remove(); // fixme: don't use DOM
|
||||
that.appendTo(Ox.UI.$body);
|
||||
width = that.width();
|
||||
height = that.height();
|
||||
left = Ox.limit(x - width / 2, 0, Ox.UI.$document.width() - width);
|
||||
top = y > Ox.UI.$document.height() - height - 16 ? y - 32 : y + 16;
|
||||
that.css({
|
||||
left: left + 'px',
|
||||
top: top + 'px'
|
||||
})
|
||||
.animate({
|
||||
opacity: 1
|
||||
}, 0);
|
||||
left: left + 'px',
|
||||
top: top + 'px'
|
||||
});
|
||||
self.options.animate && that.animate({
|
||||
opacity: 1
|
||||
}, 250);
|
||||
return that;
|
||||
};
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ $(function() {
|
|||
{name: 'American Civil War', start: new Date('1861-04-12'), stop: new Date('1865-04-10')},
|
||||
{name: 'Franco-Prussian War', start: new Date('1870-07-19'), stop: new Date('1871-05-11')},
|
||||
{name: 'Paris Commune', start: new Date('1871-03-18'), stop: new Date('1871-05-29')},
|
||||
{name: '20th century', start: new Date('1900-01-01'), stop: new Date('2000-01-01')},
|
||||
{name: '20th century', start: new Date('1900'), stop: new Date('2000')},
|
||||
{name: 'World War One', start: new Date('1914-07-28'), stop: new Date('1918-11-12')},
|
||||
{name: 'Russian Revolution', start: new Date('1917'), stop: new Date('1918')},
|
||||
{name: 'October Revolution', start: new Date('1917-11-07'), stop: new Date('1917-11-09')},
|
||||
|
|
Loading…
Reference in a new issue