Merge branch 'master' of github.com:openseadragon/openseadragon into issue37-navigator
23
Gruntfile.js
@ -1,5 +1,6 @@
|
|||||||
module.exports = function(grunt) {
|
module.exports = function(grunt) {
|
||||||
|
|
||||||
|
// ----------
|
||||||
grunt.loadNpmTasks("grunt-contrib-compress");
|
grunt.loadNpmTasks("grunt-contrib-compress");
|
||||||
grunt.loadNpmTasks("grunt-contrib-concat");
|
grunt.loadNpmTasks("grunt-contrib-concat");
|
||||||
grunt.loadNpmTasks("grunt-contrib-jshint");
|
grunt.loadNpmTasks("grunt-contrib-jshint");
|
||||||
@ -9,10 +10,12 @@ module.exports = function(grunt) {
|
|||||||
grunt.loadNpmTasks("grunt-contrib-watch");
|
grunt.loadNpmTasks("grunt-contrib-watch");
|
||||||
grunt.loadNpmTasks("grunt-contrib-clean");
|
grunt.loadNpmTasks("grunt-contrib-clean");
|
||||||
|
|
||||||
|
// ----------
|
||||||
var distribution = "build/openseadragon/openseadragon.js",
|
var distribution = "build/openseadragon/openseadragon.js",
|
||||||
minified = "build/openseadragon/openseadragon.min.js",
|
minified = "build/openseadragon/openseadragon.min.js",
|
||||||
sources = [
|
sources = [
|
||||||
"src/openseadragon.js",
|
"src/openseadragon.js",
|
||||||
|
"src/fullscreen.js",
|
||||||
"src/eventhandler.js",
|
"src/eventhandler.js",
|
||||||
"src/mousetracker.js",
|
"src/mousetracker.js",
|
||||||
"src/control.js",
|
"src/control.js",
|
||||||
@ -41,6 +44,7 @@ module.exports = function(grunt) {
|
|||||||
"src/viewport.js"
|
"src/viewport.js"
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// ----------
|
||||||
// Project configuration.
|
// Project configuration.
|
||||||
grunt.initConfig({
|
grunt.initConfig({
|
||||||
pkg: grunt.file.readJSON("package.json"),
|
pkg: grunt.file.readJSON("package.json"),
|
||||||
@ -59,7 +63,10 @@ module.exports = function(grunt) {
|
|||||||
},
|
},
|
||||||
concat: {
|
concat: {
|
||||||
options: {
|
options: {
|
||||||
banner: "/**\n * @version <%= pkg.name %> <%= pkg.version %>\n */\n\n"
|
banner: "//! <%= pkg.name %> <%= pkg.version %>\n"
|
||||||
|
+ "//! Built on <%= grunt.template.today('yyyy-mm-dd') %>\n"
|
||||||
|
+ "//! http://openseadragon.github.com\n\n",
|
||||||
|
process: true
|
||||||
},
|
},
|
||||||
dist: {
|
dist: {
|
||||||
src: [ "<banner>" ].concat(sources),
|
src: [ "<banner>" ].concat(sources),
|
||||||
@ -67,6 +74,9 @@ module.exports = function(grunt) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
uglify: {
|
uglify: {
|
||||||
|
options: {
|
||||||
|
preserveComments: "some"
|
||||||
|
},
|
||||||
openseadragon: {
|
openseadragon: {
|
||||||
src: [ distribution ],
|
src: [ distribution ],
|
||||||
dest: minified
|
dest: minified
|
||||||
@ -106,7 +116,7 @@ module.exports = function(grunt) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
files: [ "grunt.js", "src/*.js" ],
|
files: [ "Gruntfile.js", "src/*.js", "images/*" ],
|
||||||
tasks: "build"
|
tasks: "build"
|
||||||
},
|
},
|
||||||
jshint: {
|
jshint: {
|
||||||
@ -123,6 +133,7 @@ module.exports = function(grunt) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ----------
|
||||||
// Copy:build task.
|
// Copy:build task.
|
||||||
// Copies the image files into the appropriate location in the build folder.
|
// Copies the image files into the appropriate location in the build folder.
|
||||||
grunt.registerTask("copy:build", function() {
|
grunt.registerTask("copy:build", function() {
|
||||||
@ -131,36 +142,42 @@ module.exports = function(grunt) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ----------
|
||||||
// Copy:release task.
|
// Copy:release task.
|
||||||
// Copies the contents of the build folder into ../site-build.
|
// Copies the contents of the build folder into ../site-build.
|
||||||
grunt.registerTask("copy:release", function() {
|
grunt.registerTask("copy:release", function() {
|
||||||
grunt.file.recurse("build", function(abspath, rootdir, subdir, filename) {
|
grunt.file.recurse("build", function(abspath, rootdir, subdir, filename) {
|
||||||
var dest = "../site-build/"
|
var dest = "../site-build/"
|
||||||
+ (subdir ? subdir + "/" : "")
|
+ (subdir ? subdir + "/" : '/')
|
||||||
+ filename;
|
+ filename;
|
||||||
|
|
||||||
grunt.file.copy(abspath, dest);
|
grunt.file.copy(abspath, dest);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ----------
|
||||||
// Build task.
|
// Build task.
|
||||||
// Cleans out the build folder and builds the code and images into it, checking lint.
|
// Cleans out the build folder and builds the code and images into it, checking lint.
|
||||||
grunt.registerTask("build", [
|
grunt.registerTask("build", [
|
||||||
"clean:build", "jshint:beforeconcat", "concat", "jshint:afterconcat", "uglify", "copy:build"
|
"clean:build", "jshint:beforeconcat", "concat", "jshint:afterconcat", "uglify", "copy:build"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// ----------
|
||||||
// Test task.
|
// Test task.
|
||||||
// Builds and runs unit tests.
|
// Builds and runs unit tests.
|
||||||
grunt.registerTask("test", ["build", "connect", "qunit"]);
|
grunt.registerTask("test", ["build", "connect", "qunit"]);
|
||||||
|
|
||||||
|
// ----------
|
||||||
// Package task.
|
// Package task.
|
||||||
// Builds and creates the .zip and .tar files.
|
// Builds and creates the .zip and .tar files.
|
||||||
grunt.registerTask("package", ["build", "compress"]);
|
grunt.registerTask("package", ["build", "compress"]);
|
||||||
|
|
||||||
|
// ----------
|
||||||
// Publish task.
|
// Publish task.
|
||||||
// Cleans the built files out of ../site-build and copies newly built ones over.
|
// Cleans the built files out of ../site-build and copies newly built ones over.
|
||||||
grunt.registerTask("publish", ["package", "clean:release", "copy:release"]);
|
grunt.registerTask("publish", ["package", "clean:release", "copy:release"]);
|
||||||
|
|
||||||
|
// ----------
|
||||||
// Default task.
|
// Default task.
|
||||||
// Does a normal build.
|
// Does a normal build.
|
||||||
grunt.registerTask("default", ["build"]);
|
grunt.registerTask("default", ["build"]);
|
||||||
|
@ -22,8 +22,8 @@ For more information on the upgrade, see http://gruntjs.com/upgrading-from-0.3-t
|
|||||||
|
|
||||||
All command-line operations are scripted using [Grunt](http://gruntjs.com/) which is based on [Node.js](http://nodejs.org/). To get set up:
|
All command-line operations are scripted using [Grunt](http://gruntjs.com/) which is based on [Node.js](http://nodejs.org/). To get set up:
|
||||||
|
|
||||||
1. Install Node (available at the link above)
|
1. Install Node, if you haven't already (available at the link above)
|
||||||
1. On the command line, run `npm install -g grunt-cli` (this will install the Grunt command line runner)
|
1. Install the Grunt command line runner (if you haven't already); on the command line, run `npm install -g grunt-cli`
|
||||||
1. Clone the openseadragon repository
|
1. Clone the openseadragon repository
|
||||||
1. On the command line, go in to the openseadragon folder
|
1. On the command line, go in to the openseadragon folder
|
||||||
1. Run `npm install`
|
1. Run `npm install`
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "OpenSeadragon",
|
"name": "OpenSeadragon",
|
||||||
"version": "0.9.122",
|
"version": "0.9.123",
|
||||||
"description": "Provides a smooth, zoomable user interface for HTML/Javascript.",
|
"description": "Provides a smooth, zoomable user interface for HTML/Javascript.",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"grunt": "~0.4.0",
|
"grunt": "~0.4.0",
|
||||||
|
@ -515,7 +515,12 @@ function updateViewport( drawer ) {
|
|||||||
).x;
|
).x;
|
||||||
|
|
||||||
zeroRatioT = drawer.viewport.deltaPixelsFromPoints(
|
zeroRatioT = drawer.viewport.deltaPixelsFromPoints(
|
||||||
drawer.source.getPixelRatio( 0 ),
|
drawer.source.getPixelRatio(
|
||||||
|
Math.max(
|
||||||
|
drawer.source.getClosestLevel( drawer.viewport.containerSize ) - 1,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
),
|
||||||
false
|
false
|
||||||
).x;
|
).x;
|
||||||
|
|
||||||
@ -850,7 +855,7 @@ function blendTile( drawer, tile, x, y, level, levelOpacity, currentTime ){
|
|||||||
}
|
}
|
||||||
|
|
||||||
deltaTime = currentTime - tile.blendStart;
|
deltaTime = currentTime - tile.blendStart;
|
||||||
opacity = Math.min( 1, deltaTime / ( blendTimeMillis || 1 ) );
|
opacity = blendTimeMillis ? Math.min( 1, deltaTime / ( blendTimeMillis ) ) : 1;
|
||||||
|
|
||||||
if ( drawer.alwaysBlend ) {
|
if ( drawer.alwaysBlend ) {
|
||||||
opacity *= levelOpacity;
|
opacity *= levelOpacity;
|
||||||
@ -1085,9 +1090,6 @@ function drawTiles( drawer, lastDrawn ){
|
|||||||
showNavigator: false,
|
showNavigator: false,
|
||||||
showSequenceControl: false,
|
showSequenceControl: false,
|
||||||
showNavigationControl: false,
|
showNavigationControl: false,
|
||||||
//visibilityRatio: 1,
|
|
||||||
//debugMode: true,
|
|
||||||
//debugGridColor: 'red',
|
|
||||||
tileSources: [
|
tileSources: [
|
||||||
tileSource
|
tileSource
|
||||||
]
|
]
|
||||||
@ -1153,6 +1155,7 @@ function drawTiles( drawer, lastDrawn ){
|
|||||||
function drawDebugInfo( drawer, tile, count, i ){
|
function drawDebugInfo( drawer, tile, count, i ){
|
||||||
|
|
||||||
if ( USE_CANVAS ) {
|
if ( USE_CANVAS ) {
|
||||||
|
drawer.context.save();
|
||||||
drawer.context.lineWidth = 2;
|
drawer.context.lineWidth = 2;
|
||||||
drawer.context.font = 'small-caps bold 13px ariel';
|
drawer.context.font = 'small-caps bold 13px ariel';
|
||||||
drawer.context.strokeStyle = drawer.debugGridColor;
|
drawer.context.strokeStyle = drawer.debugGridColor;
|
||||||
@ -1205,6 +1208,7 @@ function drawDebugInfo( drawer, tile, count, i ){
|
|||||||
tile.position.x + 10,
|
tile.position.x + 10,
|
||||||
tile.position.y + 70
|
tile.position.y + 70
|
||||||
);
|
);
|
||||||
|
drawer.context.restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
78
src/fullscreen.js
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
* Determines the appropriate level of native full screen support we can get
|
||||||
|
* from the browser.
|
||||||
|
* Thanks to John Dyer for the implementation and research
|
||||||
|
* http://johndyer.name/native-fullscreen-javascript-api-plus-jquery-plugin/
|
||||||
|
* Also includes older IE support based on
|
||||||
|
* http://stackoverflow.com/questions/1125084/how-to-make-in-javascript-full-screen-windows-stretching-all-over-the-screen/7525760
|
||||||
|
* @name $.supportsFullScreen
|
||||||
|
*/
|
||||||
|
(function( $ ) {
|
||||||
|
var fullScreenApi = {
|
||||||
|
supportsFullScreen: false,
|
||||||
|
isFullScreen: function() { return false; },
|
||||||
|
requestFullScreen: function() {},
|
||||||
|
cancelFullScreen: function() {},
|
||||||
|
fullScreenEventName: '',
|
||||||
|
prefix: ''
|
||||||
|
},
|
||||||
|
browserPrefixes = 'webkit moz o ms khtml'.split(' ');
|
||||||
|
|
||||||
|
// check for native support
|
||||||
|
if (typeof document.cancelFullScreen != 'undefined') {
|
||||||
|
fullScreenApi.supportsFullScreen = true;
|
||||||
|
} else {
|
||||||
|
// check for fullscreen support by vendor prefix
|
||||||
|
for (var i = 0, il = browserPrefixes.length; i < il; i++ ) {
|
||||||
|
fullScreenApi.prefix = browserPrefixes[i];
|
||||||
|
|
||||||
|
if (typeof document[fullScreenApi.prefix + 'CancelFullScreen' ] != 'undefined' ) {
|
||||||
|
fullScreenApi.supportsFullScreen = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update methods to do something useful
|
||||||
|
if (fullScreenApi.supportsFullScreen) {
|
||||||
|
fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange';
|
||||||
|
|
||||||
|
fullScreenApi.isFullScreen = function() {
|
||||||
|
switch (this.prefix) {
|
||||||
|
case '':
|
||||||
|
return document.fullScreen;
|
||||||
|
case 'webkit':
|
||||||
|
return document.webkitIsFullScreen;
|
||||||
|
default:
|
||||||
|
return document[this.prefix + 'FullScreen'];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fullScreenApi.requestFullScreen = function( element ) {
|
||||||
|
return (this.prefix === '') ?
|
||||||
|
element.requestFullScreen() :
|
||||||
|
element[this.prefix + 'RequestFullScreen']();
|
||||||
|
|
||||||
|
};
|
||||||
|
fullScreenApi.cancelFullScreen = function( element ) {
|
||||||
|
return (this.prefix === '') ?
|
||||||
|
document.cancelFullScreen() :
|
||||||
|
document[this.prefix + 'CancelFullScreen']();
|
||||||
|
};
|
||||||
|
} else if ( typeof window.ActiveXObject !== "undefined" ){
|
||||||
|
// Older IE.
|
||||||
|
fullScreenApi.requestFullScreen = function(){
|
||||||
|
var wscript = new ActiveXObject("WScript.Shell");
|
||||||
|
if ( wscript !== null ) {
|
||||||
|
wscript.SendKeys("{F11}");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
fullScreenApi.cancelFullScreen = fullScreenApi.requestFullScreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// export api
|
||||||
|
$.extend( $, fullScreenApi );
|
||||||
|
|
||||||
|
})( OpenSeadragon );
|
@ -47,7 +47,10 @@ $.Navigator = function( options ){
|
|||||||
showNavigator: false,
|
showNavigator: false,
|
||||||
mouseNavEnabled: false,
|
mouseNavEnabled: false,
|
||||||
showNavigationControl: false,
|
showNavigationControl: false,
|
||||||
showSequenceControl: false
|
showSequenceControl: false,
|
||||||
|
immediateRender: true,
|
||||||
|
blendTime: 0,
|
||||||
|
animationTime: 0
|
||||||
});
|
});
|
||||||
|
|
||||||
options.minPixelRatio = this.minPixelRatio = viewer.minPixelRatio;
|
options.minPixelRatio = this.minPixelRatio = viewer.minPixelRatio;
|
||||||
@ -247,6 +250,20 @@ $.extend( $.Navigator.prototype, $.EventHandler.prototype, $.Viewer.prototype, {
|
|||||||
}( this.displayRegion.style, this.borderWidth));
|
}( this.displayRegion.style, this.borderWidth));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
open: function( source ){
|
||||||
|
var containerSize = this.viewer.viewport.containerSize.times( this.sizeRatio );
|
||||||
|
if( source.tileSize > containerSize.x ||
|
||||||
|
source.tileSize > containerSize.y ){
|
||||||
|
this.minPixelRatio = Math.min(
|
||||||
|
containerSize.x,
|
||||||
|
containerSize.y
|
||||||
|
) / source.tileSize;
|
||||||
|
} else {
|
||||||
|
this.minPixelRatio = thie.viewer.minPixelRatio;
|
||||||
|
}
|
||||||
|
return $.Viewer.prototype.open.apply( this, [ source ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
|
* @version <%= pkg.name %> <%= pkg.version %>
|
||||||
|
*
|
||||||
* @fileOverview
|
* @fileOverview
|
||||||
* <h2>
|
* <h2>
|
||||||
* <strong>
|
* <strong>
|
||||||
@ -472,26 +474,26 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
|||||||
constrainDuringPan: false,
|
constrainDuringPan: false,
|
||||||
wrapHorizontal: false,
|
wrapHorizontal: false,
|
||||||
wrapVertical: false,
|
wrapVertical: false,
|
||||||
visibilityRatio: 0.5,
|
visibilityRatio: 0.5, //-> how much of the viewer can be negative space
|
||||||
minPixelRatio: 0.5,
|
minPixelRatio: 1, //->closer to 0 draws tiles meant for a higher zoom at this zoom
|
||||||
minZoomImageRatio: 0.8,
|
|
||||||
maxZoomPixelRatio: 2,
|
|
||||||
defaultZoomLevel: 0,
|
defaultZoomLevel: 0,
|
||||||
minZoomLevel: null,
|
minZoomLevel: null,
|
||||||
maxZoomLevel: null,
|
maxZoomLevel: null,
|
||||||
|
|
||||||
//UI RESPONSIVENESS AND FEEL
|
//UI RESPONSIVENESS AND FEEL
|
||||||
springStiffness: 5.0,
|
springStiffness: 7.0,
|
||||||
clickTimeThreshold: 300,
|
clickTimeThreshold: 300,
|
||||||
clickDistThreshold: 5,
|
clickDistThreshold: 5,
|
||||||
zoomPerClick: 2.0,
|
zoomPerClick: 2,
|
||||||
zoomPerScroll: 1.2,
|
zoomPerScroll: 1.2,
|
||||||
zoomPerSecond: 2.0,
|
zoomPerSecond: 1.0,
|
||||||
animationTime: 1.5,
|
animationTime: 1.2,
|
||||||
blendTime: 1.5,
|
blendTime: 0,
|
||||||
alwaysBlend: false,
|
alwaysBlend: false,
|
||||||
autoHideControls: true,
|
autoHideControls: true,
|
||||||
immediateRender: false,
|
immediateRender: false,
|
||||||
|
minZoomImageRatio: 0.9, //-> closer to 0 allows zoom out to infinity
|
||||||
|
maxZoomPixelRatio: 1.1, //-> higher allows 'over zoom' into pixels
|
||||||
|
|
||||||
//DEFAULT CONTROL SETTINGS
|
//DEFAULT CONTROL SETTINGS
|
||||||
showSequenceControl: true, //SEQUENCE
|
showSequenceControl: true, //SEQUENCE
|
||||||
@ -530,7 +532,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
|||||||
//PERFORMANCE SETTINGS
|
//PERFORMANCE SETTINGS
|
||||||
imageLoaderLimit: 0,
|
imageLoaderLimit: 0,
|
||||||
maxImageCacheCount: 200,
|
maxImageCacheCount: 200,
|
||||||
timeout: 5000,
|
timeout: 30000,
|
||||||
|
|
||||||
//INTERFACE RESOURCE SETTINGS
|
//INTERFACE RESOURCE SETTINGS
|
||||||
prefixUrl: "/images/",
|
prefixUrl: "/images/",
|
||||||
@ -1655,6 +1657,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
|
|||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
//TODO: $.console is often used inside a try/catch block which generally
|
//TODO: $.console is often used inside a try/catch block which generally
|
||||||
// prevents allowings errors to occur with detection until a debugger
|
// prevents allowings errors to occur with detection until a debugger
|
||||||
// is attached. Although I've been guilty of the same anti-pattern
|
// is attached. Although I've been guilty of the same anti-pattern
|
||||||
|
@ -377,11 +377,13 @@ function loadPanels(strip, viewerSize, scroll){
|
|||||||
tileSources: [ strip.viewer.tileSources[ i ] ],
|
tileSources: [ strip.viewer.tileSources[ i ] ],
|
||||||
element: element,
|
element: element,
|
||||||
navigatorSizeRatio: strip.sizeRatio,
|
navigatorSizeRatio: strip.sizeRatio,
|
||||||
minPixelRatio: strip.minPixelRatio,
|
|
||||||
showNavigator: false,
|
showNavigator: false,
|
||||||
mouseNavEnabled: false,
|
mouseNavEnabled: false,
|
||||||
showNavigationControl: false,
|
showNavigationControl: false,
|
||||||
showSequenceControl: false
|
showSequenceControl: false,
|
||||||
|
immediateRender: true,
|
||||||
|
blendTime: 0,
|
||||||
|
animationTime: 0
|
||||||
} );
|
} );
|
||||||
|
|
||||||
miniViewer.displayRegion = $.makeNeutralElement( "textarea" );
|
miniViewer.displayRegion = $.makeNeutralElement( "textarea" );
|
||||||
|
47
src/tile.js
@ -1,5 +1,5 @@
|
|||||||
(function( $ ){
|
(function( $ ){
|
||||||
|
var TILE_CACHE = {};
|
||||||
/**
|
/**
|
||||||
* @class
|
* @class
|
||||||
* @param {Number} level The zoom level this tile belongs to.
|
* @param {Number} level The zoom level this tile belongs to.
|
||||||
@ -140,9 +140,11 @@ $.Tile.prototype = {
|
|||||||
drawCanvas: function( context ) {
|
drawCanvas: function( context ) {
|
||||||
|
|
||||||
var position = this.position,
|
var position = this.position,
|
||||||
size = this.size;
|
size = this.size,
|
||||||
|
rendered,
|
||||||
|
canvas;
|
||||||
|
|
||||||
if ( !this.loaded || !this.image ) {
|
if ( !this.loaded || !( this.image || TILE_CACHE[ this.url ] ) ){
|
||||||
$.console.warn(
|
$.console.warn(
|
||||||
"Attempting to draw tile %s when it's not yet loaded.",
|
"Attempting to draw tile %s when it's not yet loaded.",
|
||||||
this.toString()
|
this.toString()
|
||||||
@ -151,13 +153,13 @@ $.Tile.prototype = {
|
|||||||
}
|
}
|
||||||
context.globalAlpha = this.opacity;
|
context.globalAlpha = this.opacity;
|
||||||
|
|
||||||
context.save();
|
//context.save();
|
||||||
|
|
||||||
//if we are supposed to b rendering fully opaque rectangle,
|
//if we are supposed to be rendering fully opaque rectangle,
|
||||||
//ie its done fading or fading is turned off, and if we are drawing
|
//ie its done fading or fading is turned off, and if we are drawing
|
||||||
//an image with an alpha channel, then the only way
|
//an image with an alpha channel, then the only way
|
||||||
//to avoid seeing the tile underneath is to clear the rectangle
|
//to avoid seeing the tile underneath is to clear the rectangle
|
||||||
if( context.globalAlpha == 1 && this.image.src.match('.png') ){
|
if( context.globalAlpha == 1 && this.url.match('.png') ){
|
||||||
//clearing only the inside of the rectangle occupied
|
//clearing only the inside of the rectangle occupied
|
||||||
//by the png prevents edge flikering
|
//by the png prevents edge flikering
|
||||||
context.clearRect(
|
context.clearRect(
|
||||||
@ -169,9 +171,35 @@ $.Tile.prototype = {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context.drawImage( this.image, position.x, position.y, size.x, size.y );
|
if( !TILE_CACHE[ this.url ] ){
|
||||||
|
canvas = document.createElement( 'canvas' );
|
||||||
|
canvas.width = this.image.width;
|
||||||
|
canvas.height = this.image.height;
|
||||||
|
rendered = canvas.getContext('2d');
|
||||||
|
rendered.drawImage( this.image, 0, 0 );
|
||||||
|
TILE_CACHE[ this.url ] = rendered;
|
||||||
|
//since we are caching the prerendered image on a canvas
|
||||||
|
//allow the image to not be held in memory
|
||||||
|
this.image = null;
|
||||||
|
}
|
||||||
|
|
||||||
context.restore();
|
rendered = TILE_CACHE[ this.url ];
|
||||||
|
|
||||||
|
//rendered.save();
|
||||||
|
context.drawImage(
|
||||||
|
rendered.canvas,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
rendered.canvas.width,
|
||||||
|
rendered.canvas.height,
|
||||||
|
position.x,
|
||||||
|
position.y,
|
||||||
|
size.x,
|
||||||
|
size.y
|
||||||
|
);
|
||||||
|
//rendered.restore();
|
||||||
|
|
||||||
|
//context.restore();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -182,6 +210,9 @@ $.Tile.prototype = {
|
|||||||
if ( this.element && this.element.parentNode ) {
|
if ( this.element && this.element.parentNode ) {
|
||||||
this.element.parentNode.removeChild( this.element );
|
this.element.parentNode.removeChild( this.element );
|
||||||
}
|
}
|
||||||
|
if ( TILE_CACHE[ this.url ]){
|
||||||
|
delete TILE_CACHE[ this.url ];
|
||||||
|
}
|
||||||
|
|
||||||
this.element = null;
|
this.element = null;
|
||||||
this.image = null;
|
this.image = null;
|
||||||
|
@ -65,7 +65,7 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve
|
|||||||
height: args[1],
|
height: args[1],
|
||||||
tileSize: args[2],
|
tileSize: args[2],
|
||||||
tileOverlap: args[3],
|
tileOverlap: args[3],
|
||||||
minlevel: args[4],
|
minLevel: args[4],
|
||||||
maxLevel: args[5]
|
maxLevel: args[5]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -180,6 +180,24 @@ $.TileSource.prototype = {
|
|||||||
return new $.Point(rx, ry);
|
return new $.Point(rx, ry);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function
|
||||||
|
* @param {Number} level
|
||||||
|
*/
|
||||||
|
getClosestLevel: function( rect ) {
|
||||||
|
var i,
|
||||||
|
tilesPerSide = Math.floor( Math.max( rect.x, rect.y ) / this.tileSize ),
|
||||||
|
tiles;
|
||||||
|
for( i = this.minLevel; i < this.maxLevel; i++ ){
|
||||||
|
tiles = this.getNumTiles( i );
|
||||||
|
if( Math.max( tiles.x, tiles.y ) + 1 >= tilesPerSide ){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Math.max( 0, i - 1 );
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
* @param {Number} level
|
* @param {Number} level
|
||||||
|
@ -128,7 +128,8 @@ $.Viewer = function( options ) {
|
|||||||
"lastZoomTime": null,
|
"lastZoomTime": null,
|
||||||
// did we decide this viewer has a sequence of tile sources
|
// did we decide this viewer has a sequence of tile sources
|
||||||
"sequenced": false,
|
"sequenced": false,
|
||||||
"sequence": 0
|
"sequence": 0,
|
||||||
|
"onfullscreenchange": null
|
||||||
};
|
};
|
||||||
|
|
||||||
//Inherit some behaviors and properties
|
//Inherit some behaviors and properties
|
||||||
@ -685,6 +686,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
|
|||||||
docStyle = document.documentElement.style,
|
docStyle = document.documentElement.style,
|
||||||
containerStyle = this.element.style,
|
containerStyle = this.element.style,
|
||||||
canvasStyle = this.canvas.style,
|
canvasStyle = this.canvas.style,
|
||||||
|
_this = this,
|
||||||
oldBounds,
|
oldBounds,
|
||||||
newBounds,
|
newBounds,
|
||||||
viewer,
|
viewer,
|
||||||
@ -697,6 +699,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ( fullPage ) {
|
if ( fullPage ) {
|
||||||
|
|
||||||
this.bodyOverflow = bodyStyle.overflow;
|
this.bodyOverflow = bodyStyle.overflow;
|
||||||
@ -744,21 +747,43 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
|
|||||||
'class',
|
'class',
|
||||||
this.toolbar.element.className +" fullpage"
|
this.toolbar.element.className +" fullpage"
|
||||||
);
|
);
|
||||||
//this.toolbar.element.style.position = 'fixed';
|
|
||||||
|
|
||||||
//this.container.style.top = $.getElementSize(
|
|
||||||
// this.toolbar.element
|
|
||||||
//).y + 'px';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body.appendChild( this.element );
|
body.appendChild( this.element );
|
||||||
if( this.toolbar && this.toolbar.element ){
|
|
||||||
this.element.style.height = (
|
if( $.supportsFullScreen ){
|
||||||
$.getWindowSize().y - $.getElementSize( this.toolbar.element ).y
|
THIS[ this.hash ].onfullscreenchange = function( event ) {
|
||||||
) + 'px';
|
// The event object doesn't carry information about the
|
||||||
|
// fullscreen state of the browser, but it is possible to
|
||||||
|
// retrieve it through the fullscreen API
|
||||||
|
if( $.isFullScreen() ){
|
||||||
|
_this.setFullPage( true );
|
||||||
|
} else {
|
||||||
|
_this.setFullPage( false );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$.requestFullScreen( document.body );
|
||||||
|
|
||||||
|
// The target of the event is always the document,
|
||||||
|
// but it is possible to retrieve the fullscreen element through the API
|
||||||
|
// Note that the API is still vendor-prefixed in browsers implementing it
|
||||||
|
document.addEventListener(
|
||||||
|
$.fullScreenEventName,
|
||||||
|
THIS[ this.hash ].onfullscreenchange
|
||||||
|
);
|
||||||
|
this.element.style.height = '100%';
|
||||||
|
this.element.style.width = '100%';
|
||||||
}else{
|
}else{
|
||||||
this.element.style.height = $.getWindowSize().y + 'px';
|
this.element.style.height = $.getWindowSize().y + 'px';
|
||||||
}
|
|
||||||
this.element.style.width = $.getWindowSize().x + 'px';
|
this.element.style.width = $.getWindowSize().x + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
if( this.toolbar && this.toolbar.element ){
|
||||||
|
this.element.style.height = (
|
||||||
|
$.getElementSize( this.element ).y - $.getElementSize( this.toolbar.element ).y
|
||||||
|
) + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
// mouse will be inside container now
|
// mouse will be inside container now
|
||||||
$.delegate( this, onContainerEnter )();
|
$.delegate( this, onContainerEnter )();
|
||||||
@ -766,6 +791,14 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if( $.supportsFullScreen ){
|
||||||
|
document.removeEventListener(
|
||||||
|
$.fullScreenEventName,
|
||||||
|
THIS[ this.hash ].onfullscreenchange
|
||||||
|
);
|
||||||
|
$.cancelFullScreen( document );
|
||||||
|
}
|
||||||
|
|
||||||
bodyStyle.overflow = this.bodyOverflow;
|
bodyStyle.overflow = this.bodyOverflow;
|
||||||
docStyle.overflow = this.docOverflow;
|
docStyle.overflow = this.docOverflow;
|
||||||
|
|
||||||
@ -816,6 +849,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
|
|||||||
// mouse will likely be outside now
|
// mouse will likely be outside now
|
||||||
$.delegate( this, onContainerExit )();
|
$.delegate( this, onContainerExit )();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
this.raiseEvent( 'fullpage', { fullpage: fullPage, viewer: this } );
|
this.raiseEvent( 'fullpage', { fullpage: fullPage, viewer: this } );
|
||||||
|
|
||||||
|
75
test/basic.js
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
(function() {
|
||||||
|
|
||||||
|
var viewer = null;
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
asyncTest('Open', function() {
|
||||||
|
$(document).ready(function() {
|
||||||
|
viewer = OpenSeadragon({
|
||||||
|
id: 'example',
|
||||||
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
|
tileSources: '/test/data/testpattern.dzi',
|
||||||
|
showNavigator: true
|
||||||
|
});
|
||||||
|
|
||||||
|
ok(viewer, 'Viewer exists');
|
||||||
|
|
||||||
|
var openHandler = function(eventSender, eventData) {
|
||||||
|
viewer.removeHandler('open', openHandler);
|
||||||
|
ok(true, 'Open event was sent');
|
||||||
|
ok(eventSender === viewer, 'Sender of open event was viewer');
|
||||||
|
ok(eventData, 'Handler also received event data');
|
||||||
|
ok(viewer.viewport, 'Viewport exists');
|
||||||
|
start();
|
||||||
|
};
|
||||||
|
|
||||||
|
viewer.addHandler('open', openHandler);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
asyncTest('Zoom', function() {
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
ok(viewport.getZoom() === 1, 'We start out unzoomed');
|
||||||
|
|
||||||
|
var zoomHandler = function() {
|
||||||
|
viewer.removeHandler('animationfinish', zoomHandler);
|
||||||
|
ok(viewport.getZoom() === 2, 'Zoomed correctly');
|
||||||
|
start();
|
||||||
|
};
|
||||||
|
|
||||||
|
viewer.addHandler('animationfinish', zoomHandler);
|
||||||
|
viewport.zoomTo(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
asyncTest('Pan', function() {
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
var center = viewport.getCenter();
|
||||||
|
ok(center.x === 0.5 && center.y === 0.5, 'We start out unpanned');
|
||||||
|
|
||||||
|
var panHandler = function() {
|
||||||
|
viewer.removeHandler('animationfinish', panHandler);
|
||||||
|
center = viewport.getCenter();
|
||||||
|
ok(center.x === 0.1 && center.y === 0.1, 'Panned correctly');
|
||||||
|
start();
|
||||||
|
};
|
||||||
|
|
||||||
|
viewer.addHandler('animationfinish', panHandler);
|
||||||
|
viewport.panTo(new OpenSeadragon.Point(0.1, 0.1));
|
||||||
|
});
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
asyncTest('Close', function() {
|
||||||
|
var closeHandler = function() {
|
||||||
|
viewer.removeHandler('close', closeHandler);
|
||||||
|
ok(true, 'Close event was sent');
|
||||||
|
start();
|
||||||
|
};
|
||||||
|
|
||||||
|
viewer.addHandler('close', closeHandler);
|
||||||
|
|
||||||
|
viewer.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
1
test/data/testpattern.dzi
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><Image TileSize="254" Overlap="1" Format="jpg" xmlns="http://schemas.microsoft.com/deepzoom/2008"><Size Width="1000" Height="1000"/></Image>
|
BIN
test/data/testpattern_files/0/0_0.jpg
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
test/data/testpattern_files/1/0_0.jpg
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
test/data/testpattern_files/10/0_0.jpg
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
test/data/testpattern_files/10/0_1.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
test/data/testpattern_files/10/0_2.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
test/data/testpattern_files/10/0_3.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
test/data/testpattern_files/10/1_0.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
test/data/testpattern_files/10/1_1.jpg
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
test/data/testpattern_files/10/1_2.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
test/data/testpattern_files/10/1_3.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
test/data/testpattern_files/10/2_0.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
test/data/testpattern_files/10/2_1.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
test/data/testpattern_files/10/2_2.jpg
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
test/data/testpattern_files/10/2_3.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
test/data/testpattern_files/10/3_0.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
test/data/testpattern_files/10/3_1.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
test/data/testpattern_files/10/3_2.jpg
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
test/data/testpattern_files/10/3_3.jpg
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
test/data/testpattern_files/2/0_0.jpg
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
test/data/testpattern_files/3/0_0.jpg
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
test/data/testpattern_files/4/0_0.jpg
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
test/data/testpattern_files/5/0_0.jpg
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
test/data/testpattern_files/6/0_0.jpg
Normal file
After Width: | Height: | Size: 5.0 KiB |
BIN
test/data/testpattern_files/7/0_0.jpg
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
test/data/testpattern_files/8/0_0.jpg
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
test/data/testpattern_files/9/0_0.jpg
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
test/data/testpattern_files/9/0_1.jpg
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
test/data/testpattern_files/9/1_0.jpg
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
test/data/testpattern_files/9/1_1.jpg
Normal file
After Width: | Height: | Size: 28 KiB |
5
test/lib/jquery-1.9.1.min.js
vendored
Normal file
@ -11,7 +11,8 @@
|
|||||||
<div id="qunit-fixture"></div>
|
<div id="qunit-fixture"></div>
|
||||||
<div id="example"></div>
|
<div id="example"></div>
|
||||||
<script src="/node_modules/grunt-contrib-qunit/test/libs/qunit.js"></script>
|
<script src="/node_modules/grunt-contrib-qunit/test/libs/qunit.js"></script>
|
||||||
|
<script src="/test/lib/jquery-1.9.1.min.js"></script>
|
||||||
<script src="/build/openseadragon/openseadragon.min.js"></script>
|
<script src="/build/openseadragon/openseadragon.min.js"></script>
|
||||||
<script src="/test/test.js"></script>
|
<script src="/test/basic.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
16
test/test.js
@ -1,16 +0,0 @@
|
|||||||
test( "hello test", function() {
|
|
||||||
ok( 1 == "1", "Passed!" );
|
|
||||||
});
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
|
|
||||||
// $(document).ready(function() {
|
|
||||||
// OpenSeadragon({
|
|
||||||
// id: "example",
|
|
||||||
// prefixUrl: "/images/",
|
|
||||||
// tileSources: "/test/dzi/dog-and-cat-collars.xml",
|
|
||||||
// showNavigator: true
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
|
||||||
})();
|
|