b=435244 – Add initial support for zooming. Animation is disabled.

--HG--
branch : mobile
This commit is contained in:
mark.finkle@gmail.com 2008-05-22 16:46:20 -04:00
parent 62ca4fba25
commit a2d64cb5d3
3 changed files with 169 additions and 31 deletions

View File

@ -425,11 +425,11 @@ SpeedCache.prototype = {
_maxsize : 1,
init: function(maxsize) {
if (maxsize <= 0) maxsize = 1;
this._items = new Array(maxsize);
this._count = 0;
for (x = 0; x < maxsize; x++) {
this._items[x] = 0;
}
@ -440,7 +440,7 @@ SpeedCache.prototype = {
this._items[index] = speed;
this._count++;
},
getAverage: function() {
var maxsize = this._items.length;
var sum = 0;
@ -460,7 +460,7 @@ MouseController.prototype = {
_contextID : null,
_mousedown : false,
_panning : false,
// just remember the last 5 events.
// just remember the last 5 events.
_lastX : new SpeedCache(5),
_lastY : new SpeedCache(5),
@ -520,6 +520,9 @@ MouseController.prototype = {
this._contextID = null;
}
if (!this._panning)
return;
//FIX Hide scrollbars now
// Cancel link clicks if we've been dragging for a while
@ -527,10 +530,7 @@ MouseController.prototype = {
Math.pow(this.firstEvent.screenX - aEvent.screenX, 2) +
Math.pow(this.firstEvent.screenY - aEvent.screenY, 2));
if (totalDistance > 10) { // why 10? from mfinkle
aEvent.preventDefault();
}
else if (this._panning) {
if (totalDistance < 10) { // why 10? from mfinkle
// and if we haven't been dragging for very long, just
// end the pan without any kinetic scroll
this._browser.endPan();
@ -538,6 +538,8 @@ MouseController.prototype = {
return;
}
aEvent.preventDefault();
// Keep scrolling if there is enough momentum
function _doKineticScroll(browser, speedX, speedY, step) {
const decayFactor = 0.95;
@ -749,7 +751,7 @@ ZoomController.prototype = {
if (!el) return;
if (this.scale == 1 || el != this._target) {
//this._browser.zoomIn(el);
this._browser.zoomIn(el);
this._target = el;
}
else {

View File

@ -22,6 +22,7 @@
<binding id="deckbrowser">
<content>
<xul:stack flex="1">
<html:canvas anonid="canvas-scratch" moz-opaque="true"/>
<xul:stack anonid="renderspace" class="deckbrowser-renderspace" style="overflow:hidden;" flex="1">
<html:div anonid="canvas-background"/>
<html:canvas anonid="canvas" moz-opaque="true"/>
@ -255,16 +256,29 @@
0
</field>
<method name="_updateCanvas">
<method name="_browserToCanvas">
<parameter name="aCanvas"/>
<body>
<![CDATA[
var canvas = document.getAnonymousElementByAttribute(this, "anonid", "canvas");
var domWin = this.browser.contentWindow;
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
var stime = Date.now();
ctx.drawWindow(domWin, domWin.scrollX - this._panX, domWin.scrollY - this._panY, domWin.innerWidth, domWin.innerHeight, "white");
var etime = Date.now();
var zoom = this.browser.markupDocumentViewer.fullZoom;
zoom = Math.floor(zoom * 1000) / 1000; // Round to 4 digits
var ctx = aCanvas.getContext("2d");
//ctx.fillStyle = "red";
//ctx.fillRect(0, 0, aCanvas.width, aCanvas.height);
ctx.clearRect(0, 0, aCanvas.width, aCanvas.height);
//var stime = Date.now();
if (zoom != 1) {
ctx.save();
ctx.scale(zoom, zoom);
}
ctx.drawWindow(domWin, domWin.scrollX - this._panX / zoom, domWin.scrollY - this._panY / zoom, aCanvas.width, aCanvas.height, "white");
if (zoom != 1) {
ctx.restore();
}
//var etime = Date.now();
//dump("drawWindow: " + (etime - stime) + " ms\n");
]]>
</body>
@ -279,14 +293,15 @@
var background = document.getAnonymousElementByAttribute(this, "anonid", "canvas-background");
var canvas = document.getAnonymousElementByAttribute(this, "anonid", "canvas");
var domWin = this.browser.contentWindow;
var zoom = this.browser.markupDocumentViewer.fullZoom;
// The 'background' element acts as a 'sizer' in the <stack>
background.width = domWin.innerWidth + domWin.scrollMaxX;
background.height = domWin.innerHeight + domWin.scrollMaxY;
background.width = (domWin.innerWidth + domWin.scrollMaxX) * zoom;
background.height = (domWin.innerHeight + domWin.scrollMaxY) * zoom;
// Initialize the canvas size and location
canvas.width = domWin.innerWidth;
canvas.height = domWin.innerHeight;
canvas.width = this.browser.boxObject.width;
canvas.height = this.browser.boxObject.height;
canvas.style.left = "0px";
canvas.style.top = "0px";
@ -299,7 +314,7 @@
this._dragY = 0;
// Render the current viewable area into the canvas
this._updateCanvas();
this._browserToCanvas(canvas);
this._updateTimer = null;
]]>
</body>
@ -337,14 +352,14 @@
canvas.style.top = "0px";
self._dragX = 0;
self._dragY = 0;
self._updateCanvas();
self._browserToCanvas(canvas);
}
// if the total distance panned is greater than our threshold, force an update.
if (Math.abs(this._dragX) > canvas.width / 3 || Math.abs(this._dragY) > canvas.height / 3 ) {
_doUpdate();
return;
}
// if the total distance panned is greater than our threshold, force an update.
if (Math.abs(this._dragX) > canvas.width / 3 || Math.abs(this._dragY) > canvas.height / 3 ) {
_doUpdate();
return;
}
this._updateTimer = setTimeout(_doUpdate, 300); // why 300? carry over from mfinkle
]]>
</body>
@ -361,7 +376,18 @@
// Scroll the browser into the new location
var domWin = this.browser.contentWindow;
domWin.scrollBy(-this._panX, -this._panY);
var zoom = this.browser.markupDocumentViewer.fullZoom;
domWin.scrollBy(-this._panX / zoom, -this._panY / zoom);
//dump("panX: " + this._panX + ", panY: " + this._panY + "\n");
// Reset panning data members
var canvas = document.getAnonymousElementByAttribute(this, "anonid", "canvas");
canvas.style.left = "0px";
canvas.style.top = "0px";
this._panX = 0;
this._panY = 0;
this._dragX = 0;
this._dragY = 0;
// Toggle browser visibility so the browser is visible
this._container.style.visibility = "visible";
@ -369,6 +395,115 @@
</body>
</method>
<method name="zoomIn">
<parameter name="aTarget"/>
<body>
<![CDATA[
this._container.style.visibility = "hidden";
var canvas = document.getAnonymousElementByAttribute(this, "anonid", "canvas");
var scratch = document.getAnonymousElementByAttribute(this, "anonid", "canvas-scratch");
var domWin = this.browser.contentWindow;
// Collect data from pre-zoom
var origin = {};
origin.zoom = this.browser.markupDocumentViewer.fullZoom;
origin.x = 0;
origin.y = 0;
//origin.scrollX = domWin.scrollX;
//origin.scrollY = domWin.scrollY;
// Setup the on-screen and off-screen canvas
canvas.width = scratch.width = this.browser.boxObject.width;
canvas.height = scratch.height = this.browser.boxObject.height;
// Render the current view to the off-screen canvas
this._browserToCanvas(scratch);
// Get the position of the target (adding a margin to the horizontal)
var r1 = aTarget.getBoundingClientRect();
r1.x = r1.left + domWin.scrollX - 8;
r1.y = r1.top + domWin.scrollY;
r1.width = (r1.right - r1.left) + 16;
r1.height = r1.bottom - r1.top;
//dump("r1: " + r1.left + ", " + r1.top + ", " + r1.right + ", " + r1.bottom + "\n");
// For the given target, find a suitable zoom
var zoomX = this.browser.boxObject.width / r1.width;
var zoomY = this.browser.boxObject.height / r1.height;
// Collect some data about post-zoom
var dest = {};
dest.zoom = Math.min(zoomX, zoomY);
// Clamp the zoom
dest.zoom = Math.min(4, Math.max(0.1, dest.zoom));
dest.zoom = Math.floor(dest.zoom * 1000) / 1000; // Round to 4 digits
if (dest.zoom != this.browser.markupDocumentViewer.fullZoom)
this.browser.markupDocumentViewer.fullZoom = dest.zoom;
// Determine the best x & y placement of the target post-zoom.
// Try to position the top / left corner of screen so that target is centered
var overflowY = Math.floor((r1.height * dest.zoom) - this.browser.boxObject.height);
dest.y = r1.y + overflowY / dest.zoom / 2;
if (overflowY > 0)
dest.y = r1.y;
if ((dest.y + this.browser.boxObject.height / dest.zoom) > (domWin.innerHeight + domWin.scrollMaxY))
dest.y = (domWin.innerHeight + domWin.scrollMaxY) - this.browser.boxObject.height / dest.zoom;
if (dest.y < 0)
dest.y = 0;
dest.y = Math.floor(dest.y);
//dump("y: " + dest.y + ", overy: " + overflowY + "\n");
var overflowX = Math.floor((r1.width * dest.zoom) - this.browser.boxObject.width);
dest.x = r1.x + overflowX / dest.zoom / 2;
if (overflowX > 0)
dest.x = r1.x;
if ((dest.x + this.browser.boxObject.width / dest.zoom) > (domWin.innerWidth + domWin.scrollMaxX))
dest.x = (domWin.innerWidth + domWin.scrollMaxX) - this.browser.boxObject.width / dest.zoom;
if (dest.x < 0)
dest.x = 0;
dest.x = Math.floor(dest.x);
//dump("x: " + dest.x + ", overx: " + overflowX + "\n");
// Initialize the animation bits (should switch to constant time)
var anim = {};
anim.steps = 1; // XXX disabling animation for now
anim.step = 1;
// Scroll the browser to the right spot (isn't visible yet)
domWin.scrollTo(dest.x, dest.y);
var self = this;
var onscreen = canvas.getContext("2d");
function _doZoomInAnimate(origin, dest, anim) {
// Determine the new values as we march through the animation
let zoom = origin.zoom + ((dest.zoom - origin.zoom) * anim.step) / anim.steps;
let x = origin.x + ((dest.x - origin.x) * anim.step) / anim.steps;
let y = origin.y + ((dest.y - origin.y) * anim.step) / anim.steps;
anim.step += 1;
//var stime2 = Date.now();
//onscreen.drawImage(scratch, -x * zoom, -y * zoom, Math.floor(scratch.width * zoom), Math.floor(scratch.height * zoom));
//var etime2 = Date.now();
//dump("animate: " + zoom + ", " + x + ", " + y + ", " + (etime2 - stime2) + " ms\n");
if (zoom < dest.zoom) {
setTimeout(_doZoomInAnimate, 100, origin, dest, anim);
}
else {
self._container.style.visibility = "visible";
var offscreen = scratch.getContext("2d");
offscreen.clearRect(0, 0, scratch.width, scratch.height);
}
}
if (dest.zoom != 1)
_doZoomInAnimate(origin, dest, anim);
]]>
</body>
</method>
</implementation>
<handlers>

View File

@ -37,13 +37,14 @@
/* Style the scrollbars */
scrollbar {
-moz-appearance: none !important;
background-color: transparent !important;
-moz-appearance: none !important;
/*background-color: transparent !important;*/
display: none !important;
}
scrollbarbutton {
-moz-appearance: none !important;
display: none !important;
display: none !important;
}
thumb {