add zoom to mouse position when using scrollwheel

This commit is contained in:
rlx 2011-04-20 22:42:09 +00:00
parent e02e77605f
commit 02a3b5c6a1
4 changed files with 269 additions and 64 deletions

View file

@ -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;

View file

@ -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")

View file

@ -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('&nbsp;' + 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;
};

View file

@ -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')},