An Open Source library for multi-touch, WebGL powered applications.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

2556 lines
88 KiB

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>iwmlib API Documentation</title>
<meta name="description" content="The IWM Browser: One Browser for all apps." />
<meta property="og:title" content="iwmlib API Documentation"/>
<meta property="og:type" content="website"/>
<meta property="og:image" content=""/>
<meta property="og:url" content="https://www.iwm-tuebingen.de"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="scripts/prettify/prettify.js"></script>
<script src="scripts/prettify/lang-css.js"></script>
<script src="scripts/jquery.min.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="https://fonts.googleapis.com/css?family=Libre+Franklin:400,700" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="styles/main.css">
<script>
var config = {"monospaceLinks":false,"cleverLinks":false,"applicationName":"iwmlib","disqus":"","googleAnalytics":"","openGraph":{"title":"iwmlib API Documentation","type":"website","image":"","site_name":"","url":"https://www.iwm-tuebingen.de"},"meta":{"title":"iwmlib API Documentation","description":"The IWM Browser: One Browser for all apps.","keyword":""},"linenums":true,"cleverlinks":true,"default":{"outputSourceFiles":true,"useLongnameInNav":false}};
</script>
</head>
<body>
<div id="wrap" class="clearfix">
<div class="navigation">
<h3 class="applicationName"><a href="index.html">iwmlib</a></h3>
<button id="menuToggle" class="btn btn-link btn-lg menu-toggle">
<span class="glyphicon glyphicon-menu-hamburger"></span>
</button>
<div class="search">
<input id="search" type="text" class="form-control input-md" placeholder="Search...">
</div>
<ul class="list">
<li class="item" data-name="global">
<span class="title namespace ">
<span class="namespaceTag">
<span class="glyphicon glyphicon-globe"></span>
</span>
<a href="global.html">Global</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
<span class="subtitle">Typedefs</span>
<li class="parent" data-name="actionActiveCallback"><a href="global.html#actionActiveCallback">actionActiveCallback</a></li>
<li class="parent" data-name="actionCallback"><a href="global.html#actionCallback">actionCallback</a></li>
<li class="parent" data-name="actionCallback"><a href="global.html#actionCallback">actionCallback</a></li>
<li class="parent" data-name="afterActionCallback"><a href="global.html#afterActionCallback">afterActionCallback</a></li>
<li class="parent" data-name="afterActionCallback"><a href="global.html#afterActionCallback">afterActionCallback</a></li>
<li class="parent" data-name="beforeActionCallback"><a href="global.html#beforeActionCallback">beforeActionCallback</a></li>
<li class="parent" data-name="beforeActionCallback"><a href="global.html#beforeActionCallback">beforeActionCallback</a></li>
<li class="parent" data-name="onCompleteCallback"><a href="global.html#onCompleteCallback">onCompleteCallback</a></li>
<li class="parent" data-name="onCompleteCallback"><a href="global.html#onCompleteCallback">onCompleteCallback</a></li>
<li class="parent" data-name="onStartCallback"><a href="global.html#onStartCallback">onStartCallback</a></li>
<li class="parent" data-name="onStartCallback"><a href="global.html#onStartCallback">onStartCallback</a></li>
<li class="parent" data-name="onUpdateCallback"><a href="global.html#onUpdateCallback">onUpdateCallback</a></li>
<li class="parent" data-name="onUpdateCallback"><a href="global.html#onUpdateCallback">onUpdateCallback</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="AbstractPopup">
<span class="title ">
<a href="AbstractPopup.html">AbstractPopup</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="AbstractPopup#content"><a href="AbstractPopup.html#content">content</a></li>
<li class="parent " data-name="AbstractPopup#header"><a href="AbstractPopup.html#header">header</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="AbstractPopup#hide"><a href="AbstractPopup.html#hide">hide</a></li>
<li class="parent " data-name="AbstractPopup#layout"><a href="AbstractPopup.html#layout">layout</a></li>
<li class="parent " data-name="AbstractPopup#show"><a href="AbstractPopup.html#show">show</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Badge">
<span class="title ">
<a href="Badge.html">Badge</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class=" " data-name="Badge#content"><a href="Badge.html#content">content</a></li>
<li class=" " data-name="Badge#header"><a href="Badge.html#header">header</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class=" " data-name="Badge#hide"><a href="Badge.html#hide">hide</a></li>
<li class=" " data-name="Badge#layout"><a href="Badge.html#layout">layout</a></li>
<li class=" " data-name="Badge#show"><a href="Badge.html#show">show</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="BlurFilter">
<span class="title ">
<a href="BlurFilter.html">BlurFilter</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="BlurFilter#blur"><a href="BlurFilter.html#blur">blur</a></li>
<li class="parent " data-name="BlurFilter#shape"><a href="BlurFilter.html#shape">shape</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Button">
<span class="title ">
<a href="Button.html">Button</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="Button#active"><a href="Button.html#active">active</a></li>
<li class="parent " data-name="Button#disabled"><a href="Button.html#disabled">disabled</a></li>
<li class="parent " data-name="Button#iconColor"><a href="Button.html#iconColor">iconColor</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="Button#capture"><a href="Button.html#capture">capture</a></li>
<li class="parent " data-name="Button#hide"><a href="Button.html#hide">hide</a></li>
<li class="parent " data-name="Button#layout"><a href="Button.html#layout">layout</a></li>
<li class="parent " data-name="Button#show"><a href="Button.html#show">show</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ButtonGroup">
<span class="title ">
<a href="ButtonGroup.html">ButtonGroup</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="ButtonGroup#disabled"><a href="ButtonGroup.html#disabled">disabled</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ButtonGroup#hide"><a href="ButtonGroup.html#hide">hide</a></li>
<li class="parent " data-name="ButtonGroup#layout"><a href="ButtonGroup.html#layout">layout</a></li>
<li class="parent " data-name="ButtonGroup#show"><a href="ButtonGroup.html#show">show</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="DeepZoomImage">
<span class="title ">
<a href="DeepZoomImage.html">DeepZoomImage</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="DeepZoomImage#baseSize"><a href="DeepZoomImage.html#baseSize">baseSize</a></li>
<li class="parent " data-name="DeepZoomImage#foreground"><a href="DeepZoomImage.html#foreground">foreground</a></li>
<li class="parent " data-name="DeepZoomImage#height"><a href="DeepZoomImage.html#height">height</a></li>
<li class="parent " data-name="DeepZoomImage#maxScale"><a href="DeepZoomImage.html#maxScale">maxScale</a></li>
<li class="parent " data-name="DeepZoomImage#pixelSize"><a href="DeepZoomImage.html#pixelSize">pixelSize</a></li>
<li class="parent " data-name="DeepZoomImage#width"><a href="DeepZoomImage.html#width">width</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="DeepZoomImage#_calculateBounds"><a href="DeepZoomImage.html#_calculateBounds">_calculateBounds</a></li>
<li class="parent " data-name="DeepZoomImage#_createTiles"><a href="DeepZoomImage.html#_createTiles">_createTiles</a></li>
<li class="parent " data-name="DeepZoomImage#activate"><a href="DeepZoomImage.html#activate">activate</a></li>
<li class="parent " data-name="DeepZoomImage#addTiles"><a href="DeepZoomImage.html#addTiles">addTiles</a></li>
<li class="parent " data-name="DeepZoomImage#allTiles"><a href="DeepZoomImage.html#allTiles">allTiles</a></li>
<li class="parent " data-name="DeepZoomImage#bringTilesToFront"><a href="DeepZoomImage.html#bringTilesToFront">bringTilesToFront</a></li>
<li class="parent " data-name="DeepZoomImage#calculateBounds"><a href="DeepZoomImage.html#calculateBounds">calculateBounds</a></li>
<li class="parent " data-name="DeepZoomImage#changedTiles"><a href="DeepZoomImage.html#changedTiles">changedTiles</a></li>
<li class="parent " data-name="DeepZoomImage#deactivate"><a href="DeepZoomImage.html#deactivate">deactivate</a></li>
<li class="parent " data-name="DeepZoomImage#destroyObsoleteTiles"><a href="DeepZoomImage.html#destroyObsoleteTiles">destroyObsoleteTiles</a></li>
<li class="parent " data-name="DeepZoomImage#destroyTiles"><a href="DeepZoomImage.html#destroyTiles">destroyTiles</a></li>
<li class="parent " data-name="DeepZoomImage#destroyTilesAboveLevel"><a href="DeepZoomImage.html#destroyTilesAboveLevel">destroyTilesAboveLevel</a></li>
<li class="parent " data-name="DeepZoomImage#destroyUnneededTiles"><a href="DeepZoomImage.html#destroyUnneededTiles">destroyUnneededTiles</a></li>
<li class="parent " data-name="DeepZoomImage#ensureAllTiles"><a href="DeepZoomImage.html#ensureAllTiles">ensureAllTiles</a></li>
<li class="parent " data-name="DeepZoomImage#ensureTiles"><a href="DeepZoomImage.html#ensureTiles">ensureTiles</a></li>
<li class="parent " data-name="DeepZoomImage#levelAndAlphaForScale"><a href="DeepZoomImage.html#levelAndAlphaForScale">levelAndAlphaForScale</a></li>
<li class="parent " data-name="DeepZoomImage#levelForScale"><a href="DeepZoomImage.html#levelForScale">levelForScale</a></li>
<li class="parent " data-name="DeepZoomImage#neededTiles"><a href="DeepZoomImage.html#neededTiles">neededTiles</a></li>
<li class="parent " data-name="DeepZoomImage#populateAllTiles"><a href="DeepZoomImage.html#populateAllTiles">populateAllTiles</a></li>
<li class="parent " data-name="DeepZoomImage#populateTiles"><a href="DeepZoomImage.html#populateTiles">populateTiles</a></li>
<li class="parent " data-name="DeepZoomImage#setup"><a href="DeepZoomImage.html#setup">setup</a></li>
<li class="parent " data-name="DeepZoomImage#setupTiles"><a href="DeepZoomImage.html#setupTiles">setupTiles</a></li>
<li class="parent " data-name="DeepZoomImage#thumbnail"><a href="DeepZoomImage.html#thumbnail">thumbnail</a></li>
<li class="parent " data-name="DeepZoomImage#tintObsoleteTiles"><a href="DeepZoomImage.html#tintObsoleteTiles">tintObsoleteTiles</a></li>
<li class="parent " data-name="DeepZoomImage#transformed"><a href="DeepZoomImage.html#transformed">transformed</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="DeepZoomInfo">
<span class="title ">
<a href="DeepZoomInfo.html">DeepZoomInfo</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="DeepZoomInfo#dimensions"><a href="DeepZoomInfo.html#dimensions">dimensions</a></li>
<li class="parent " data-name="DeepZoomInfo#getDimensions"><a href="DeepZoomInfo.html#getDimensions">getDimensions</a></li>
<li class="parent " data-name="DeepZoomInfo#getNumTiles"><a href="DeepZoomInfo.html#getNumTiles">getNumTiles</a></li>
<li class="parent " data-name="DeepZoomInfo#getScale"><a href="DeepZoomInfo.html#getScale">getScale</a></li>
<li class="parent " data-name="DeepZoomInfo#imageForURL"><a href="DeepZoomInfo.html#imageForURL">imageForURL</a></li>
<li class="parent " data-name="DeepZoomInfo#urlForTile"><a href="DeepZoomInfo.html#urlForTile">urlForTile</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Flippable">
<span class="title ">
<a href="Flippable.html">Flippable</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="Flippable#flipped"><a href="Flippable.html#flipped">flipped</a></li>
<li class="parent " data-name="Flippable#frontSideInFront"><a href="Flippable.html#frontSideInFront">frontSideInFront</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="Flippable#layout"><a href="Flippable.html#layout">layout</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="FontInfo">
<span class="title ">
<a href="FontInfo.html">FontInfo</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Hypenate">
<span class="title ">
<a href="Hypenate.html">Hypenate</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="Hypenate.splitLines"><a href="Hypenate.html#.splitLines">splitLines</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="InteractivePopup">
<span class="title ">
<a href="InteractivePopup.html">InteractivePopup</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class=" " data-name="InteractivePopup#content"><a href="InteractivePopup.html#content">content</a></li>
<li class=" " data-name="InteractivePopup#header"><a href="InteractivePopup.html#header">header</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class=" " data-name="InteractivePopup#hide"><a href="InteractivePopup.html#hide">hide</a></li>
<li class="parent " data-name="InteractivePopup#layout"><a href="InteractivePopup.html#layout">layout</a></li>
<li class=" " data-name="InteractivePopup#show"><a href="InteractivePopup.html#show">show</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="LabeledGraphics">
<span class="title ">
<a href="LabeledGraphics.html">LabeledGraphics</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="LabeledGraphics#clear"><a href="LabeledGraphics.html#clear">clear</a></li>
<li class="parent " data-name="LabeledGraphics#debugInfos"><a href="LabeledGraphics.html#debugInfos">debugInfos</a></li>
<li class="parent " data-name="LabeledGraphics#ensureLabel"><a href="LabeledGraphics.html#ensureLabel">ensureLabel</a></li>
<li class="parent " data-name="LabeledGraphics#getLabel"><a href="LabeledGraphics.html#getLabel">getLabel</a></li>
<li class="parent " data-name="LabeledGraphics#hideLabel"><a href="LabeledGraphics.html#hideLabel">hideLabel</a></li>
<li class="parent " data-name="LabeledGraphics#removeLabel"><a href="LabeledGraphics.html#removeLabel">removeLabel</a></li>
<li class="parent " data-name="LabeledGraphics#truncateLabel"><a href="LabeledGraphics.html#truncateLabel">truncateLabel</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="LabeledGraphics.exports.LabeledGraphics">
<span class="title ">
<a href="LabeledGraphics.exports.LabeledGraphics.html">LabeledGraphics.exports.LabeledGraphics</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="List">
<span class="title ">
<a href="List.html">List</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="List#innerHeight"><a href="List.html#innerHeight">innerHeight</a></li>
<li class="parent " data-name="List#innerWidth"><a href="List.html#innerWidth">innerWidth</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="List#capture"><a href="List.html#capture">capture</a></li>
<li class="parent " data-name="List#layout"><a href="List.html#layout">layout</a></li>
<li class="parent " data-name="List#resize"><a href="List.html#resize">resize</a></li>
<li class="parent " data-name="List#setItems"><a href="List.html#setItems">setItems</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Message">
<span class="title ">
<a href="Message.html">Message</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class=" " data-name="Message#content"><a href="Message.html#content">content</a></li>
<li class=" " data-name="Message#header"><a href="Message.html#header">header</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class=" " data-name="Message#hide"><a href="Message.html#hide">hide</a></li>
<li class="parent " data-name="Message#layout"><a href="Message.html#layout">layout</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="MessageInteractivePopup">
<span class="title ">
<a href="MessageInteractivePopup.html">MessageInteractivePopup</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="MessageMessageInteractivePopup">
<span class="title ">
<a href="MessageMessageInteractivePopup.html">MessageMessageInteractivePopup</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Modal">
<span class="title ">
<a href="Modal.html">Modal</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="Modal#content"><a href="Modal.html#content">content</a></li>
<li class="parent " data-name="Modal#header"><a href="Modal.html#header">header</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="Modal#hide"><a href="Modal.html#hide">hide</a></li>
<li class="parent " data-name="Modal#layout"><a href="Modal.html#layout">layout</a></li>
<li class="parent " data-name="Modal#show"><a href="Modal.html#show">show</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ModalInteractivePopup">
<span class="title ">
<a href="ModalInteractivePopup.html">ModalInteractivePopup</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ModalModalInteractivePopup">
<span class="title ">
<a href="ModalModalInteractivePopup.html">ModalModalInteractivePopup</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="PIXIApp">
<span class="title ">
<a href="PIXIApp.html">PIXIApp</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="PIXIApp#center"><a href="PIXIApp.html#center">center</a></li>
<li class="parent " data-name="PIXIApp#size"><a href="PIXIApp.html#size">size</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="PIXIApp#addFpsDisplay"><a href="PIXIApp.html#addFpsDisplay">addFpsDisplay</a></li>
<li class="parent " data-name="PIXIApp#checkOrientation"><a href="PIXIApp.html#checkOrientation">checkOrientation</a></li>
<li class="parent " data-name="PIXIApp#convertPointFromNodeToPage"><a href="PIXIApp.html#convertPointFromNodeToPage">convertPointFromNodeToPage</a></li>
<li class="parent " data-name="PIXIApp#convertPointFromPageToNode"><a href="PIXIApp.html#convertPointFromPageToNode">convertPointFromPageToNode</a></li>
<li class="parent " data-name="PIXIApp#draw"><a href="PIXIApp.html#draw">draw</a></li>
<li class="parent " data-name="PIXIApp#expandRenderer"><a href="PIXIApp.html#expandRenderer">expandRenderer</a></li>
<li class="parent " data-name="PIXIApp#layout"><a href="PIXIApp.html#layout">layout</a></li>
<li class="parent " data-name="PIXIApp#loadSprites"><a href="PIXIApp.html#loadSprites">loadSprites</a></li>
<li class="parent " data-name="PIXIApp#loadTextures"><a href="PIXIApp.html#loadTextures">loadTextures</a></li>
<li class="parent " data-name="PIXIApp#message"><a href="PIXIApp.html#message">message</a></li>
<li class="parent " data-name="PIXIApp#modal"><a href="PIXIApp.html#modal">modal</a></li>
<li class="parent " data-name="PIXIApp#mutate"><a href="PIXIApp.html#mutate">mutate</a></li>
<li class="parent " data-name="PIXIApp#orientation"><a href="PIXIApp.html#orientation">orientation</a></li>
<li class="parent " data-name="PIXIApp#orientationChanged"><a href="PIXIApp.html#orientationChanged">orientationChanged</a></li>
<li class="parent " data-name="PIXIApp#progress"><a href="PIXIApp.html#progress">progress</a></li>
<li class="parent " data-name="PIXIApp#query"><a href="PIXIApp.html#query">query</a></li>
<li class="parent " data-name="PIXIApp#resize"><a href="PIXIApp.html#resize">resize</a></li>
<li class="parent " data-name="PIXIApp#setup"><a href="PIXIApp.html#setup">setup</a></li>
<li class="parent " data-name="PIXIApp#subscribe"><a href="PIXIApp.html#subscribe">subscribe</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Popup">
<span class="title ">
<a href="Popup.html">Popup</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class=" " data-name="Popup#content"><a href="Popup.html#content">content</a></li>
<li class=" " data-name="Popup#header"><a href="Popup.html#header">header</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class=" " data-name="Popup#hide"><a href="Popup.html#hide">hide</a></li>
<li class=" " data-name="Popup#layout"><a href="Popup.html#layout">layout</a></li>
<li class=" " data-name="Popup#show"><a href="Popup.html#show">show</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="PopupInteractivePopup">
<span class="title ">
<a href="PopupInteractivePopup.html">PopupInteractivePopup</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="PopupMenu">
<span class="title ">
<a href="PopupMenu.html">PopupMenu</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class=" " data-name="PopupMenu#content"><a href="PopupMenu.html#content">content</a></li>
<li class=" " data-name="PopupMenu#header"><a href="PopupMenu.html#header">header</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class=" " data-name="PopupMenu#hide"><a href="PopupMenu.html#hide">hide</a></li>
<li class=" " data-name="PopupMenu#layout"><a href="PopupMenu.html#layout">layout</a></li>
<li class=" " data-name="PopupMenu#show"><a href="PopupMenu.html#show">show</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="PopupMenuPopupInteractivePopup">
<span class="title ">
<a href="PopupMenuPopupInteractivePopup.html">PopupMenuPopupInteractivePopup</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="PopupMenuPopupMenuPopupInteractivePopup">
<span class="title ">
<a href="PopupMenuPopupMenuPopupInteractivePopup.html">PopupMenuPopupMenuPopupInteractivePopup</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="PopupMenuPopupMenuPopupPopupInteractivePopup">
<span class="title ">
<a href="PopupMenuPopupMenuPopupPopupInteractivePopup.html">PopupMenuPopupMenuPopupPopupInteractivePopup</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="PopupMenuPopupPopupInteractivePopup">
<span class="title ">
<a href="PopupMenuPopupPopupInteractivePopup.html">PopupMenuPopupPopupInteractivePopup</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="PopupPopupInteractivePopup">
<span class="title ">
<a href="PopupPopupInteractivePopup.html">PopupPopupInteractivePopup</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Progress">
<span class="title ">
<a href="Progress.html">Progress</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="Progress#progress"><a href="Progress.html#progress">progress</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="Progress#hide"><a href="Progress.html#hide">hide</a></li>
<li class="parent " data-name="Progress#layout"><a href="Progress.html#layout">layout</a></li>
<li class="parent " data-name="Progress#show"><a href="Progress.html#show">show</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Scrollview">
<span class="title ">
<a href="Scrollview.html">Scrollview</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="Scrollview#layout"><a href="Scrollview.html#layout">layout</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Slider">
<span class="title ">
<a href="Slider.html">Slider</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="Slider#disabled"><a href="Slider.html#disabled">disabled</a></li>
<li class="parent " data-name="Slider#value"><a href="Slider.html#value">value</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="Slider#hide"><a href="Slider.html#hide">hide</a></li>
<li class="parent " data-name="Slider#layout"><a href="Slider.html#layout">layout</a></li>
<li class="parent " data-name="Slider#show"><a href="Slider.html#show">show</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Switch">
<span class="title ">
<a href="Switch.html">Switch</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="Switch#active"><a href="Switch.html#active">active</a></li>
<li class="parent " data-name="Switch#disabled"><a href="Switch.html#disabled">disabled</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="Switch#hide"><a href="Switch.html#hide">hide</a></li>
<li class="parent " data-name="Switch#layout"><a href="Switch.html#layout">layout</a></li>
<li class="parent " data-name="Switch#show"><a href="Switch.html#show">show</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="TextLabel.TextLabel">
<span class="title ">
<a href="TextLabel.TextLabel.html">TextLabel.TextLabel</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Theme">
<span class="title ">
<a href="Theme.html">Theme</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="Theme.fromString"><a href="Theme.html#.fromString">fromString</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ThemeDark">
<span class="title ">
<a href="ThemeDark.html">ThemeDark</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ThemeLight">
<span class="title ">
<a href="ThemeLight.html">ThemeLight</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ThemeRed">
<span class="title ">
<a href="ThemeRed.html">ThemeRed</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="TileQuadNode">
<span class="title ">
<a href="TileQuadNode.html">TileQuadNode</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="TileQuadNode#link"><a href="TileQuadNode.html#link">link</a></li>
<li class="parent " data-name="TileQuadNode#noQuads"><a href="TileQuadNode.html#noQuads">noQuads</a></li>
<li class="parent " data-name="TileQuadNode#unlink"><a href="TileQuadNode.html#unlink">unlink</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Tooltip">
<span class="title ">
<a href="Tooltip.html">Tooltip</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class=" " data-name="Tooltip#content"><a href="Tooltip.html#content">content</a></li>
<li class=" " data-name="Tooltip#header"><a href="Tooltip.html#header">header</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class=" " data-name="Tooltip#hide"><a href="Tooltip.html#hide">hide</a></li>
<li class=" " data-name="Tooltip#layout"><a href="Tooltip.html#layout">layout</a></li>
<li class=" " data-name="Tooltip#show"><a href="Tooltip.html#show">show</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="UITest">
<span class="title ">
<a href="UITest.html">UITest</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="UITest#timeline"><a href="UITest.html#timeline">timeline</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="UITest#clear"><a href="UITest.html#clear">clear</a></li>
<li class="parent " data-name="UITest#pan"><a href="UITest.html#pan">pan</a></li>
<li class="parent " data-name="UITest#pinch"><a href="UITest.html#pinch">pinch</a></li>
<li class="parent " data-name="UITest#restart"><a href="UITest.html#restart">restart</a></li>
<li class="parent " data-name="UITest#start"><a href="UITest.html#start">start</a></li>
<li class="parent " data-name="UITest#stop"><a href="UITest.html#stop">stop</a></li>
<li class="parent " data-name="UITest#tap"><a href="UITest.html#tap">tap</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="Volatile">
<span class="title ">
<a href="Volatile.html">Volatile</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="Volatile#layout"><a href="Volatile.html#layout">layout</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
</ul>
</div>
<div class="main">
<h1 class="page-title" data-filename="pixi_deepzoom_image.js.html">Source: pixi/deepzoom/image.js</h1>
<section>
<header>
<div class="header content-size">
<h2>pixi/deepzoom/image.js</h2>
</div>
</header>
<article>
<pre id="source-code" class="prettyprint source linenums"><code>import { Capabilities } from '../../capabilities.js'
import { Points } from '../../utils.js'
import Tile from './tile.js'
import { Tiles } from './tiles.js'
function isEven(n) {
return n % 2 == 0
}
/**
* A utility class that holds information typically provided by DZI files, i.e.
* height and width of the overall image, overlap, and image type.
*
* @constructor
* @param {obj} attrs - A JSON-Object holding the listed keys and values
* @example
* {
* "tileSize": 1024,
* "format": "jpeg",
* "overlap": 1,
* "height": 4794,
* "width": 4095,
* "clip": { "minLevel": 12, "maxLevel": 20, "startCol": 301436, "startRow": 354060 },
* // optional: minLevel and maxLevel define the level bounds
* // startCol: first col at maxLevel
* // startRow: first row at maxLevel
* "path": "var/Vermeer/Vermeer_files",
* "type": "dzi", // optional: dzi (default) or map
* "urlTileTemplate": "{path}/{level}/{column}/{row}.{format}"
* // optional: {path}/{level}/{column}_{row}.{format} (default) or
* // a template String with the format of the URL
* }
*/
export class DeepZoomInfo {
constructor(attrs) {
for (let key in attrs) {
this[key] = attrs[key]
}
this.maxLevel = 0 // The highest level number, typically corresponds to the
// number in the file system for the folder with tiles
this.clip = this.clip || null // e.g. { level: 12, col: 301436, row: 354060 }
this.type = this.type || 'dzi'
this.urlTileTemplate =
this.urlTileTemplate || '{path}/{level}/{column}_{row}.{format}'
this.setupDimensions()
}
/* Computes the needed number of layers from the width and height
* of the image. Note that this includes the level 0, i.e. 0 ... 4
* means that 5 levels exist.
**/
numLevels() {
let maxDimension = Math.max(this.width, this.height)
let boundary = this.type === 'dzi' ? 1 : this.tileSize
let numLevels = 0
while (maxDimension >= boundary) {
maxDimension /= 2
numLevels++
}
return numLevels
}
/** Computes the scale at the given level.
* @param {number} level - The level of the wanted layer
* @returns {number} scale
**/
getScale(level) {
let scale = 1
if (this.type === 'dzi') {
scale = Math.pow(0.5, this.maxLevel - level + 1)
} else {
scale = Math.pow(0.5, this.maxLevel - level)
}
return scale
}
/** Computes the scaled width and height of the given level.
* @param {number} level - The level of the wanted layer
* @returns {array} size - The width and height
**/
getDimensions(level) {
let scale = this.getScale(level)
let w = Math.ceil(this.width * scale)
let h = Math.ceil(this.height * scale)
return [w, h]
}
/** Computes the number of cols and rows of tiles.
* @param {number} level - The level of the wanted layer
* @returns {array} size - The cols and rows
**/
getNumTiles(level) {
let dim = this.getDimensions(level)
let cols = Math.ceil(dim[0] / this.tileSize)
let rows = Math.ceil(dim[1] / this.tileSize)
if (this.clip) {
let rest = this.rests[level]
if (rest) {
if (rest.restCol) {
cols += 1
}
if (rest.restRows) {
rows += 1
}
}
}
return [cols, rows]
}
setupDimensions(loadBaseImage = false) {
/** Setup instance variables and load the base image, i.e. the largest
image that can be represented as a single tile.
@private
**/
let ww = this.width
let hh = this.height
let scale = 1.0
let level = 0
let single = 0
const tsize = this.tileSize
if (this.clip) {
this.baseLevel = this.clip.minLevel
this.maxLevel = this.clip.maxLevel
this.baseImage = null
this.size = this.getDimensions(this.baseLevel)
this.offsets = {}
this.rests = {}
let startCol = this.clip.startCol
let startRow = this.clip.startRow
let floatStartCol = startCol
let floatStartRow = startRow
for (let i = this.maxLevel; i >= this.baseLevel; i--) {
this.offsets[i] = { startCol, startRow }
let restCol = floatStartCol % 1
let restRow = floatStartRow % 1
this.rests[i] = { restCol, restRow }
startCol = Math.floor(startCol / 2)
startRow = Math.floor(startRow / 2)
floatStartCol /= 2
floatStartRow /= 2
}
} else {
const boundary = this.type === 'dzi' ? 1.0 : tsize
while (ww > boundary &amp;&amp; hh > boundary) {
if (ww >= tsize &amp;&amp; hh >= tsize) {
single += 1
}
scale = scale / 2.0
ww = Math.ceil(this.width * scale)
hh = Math.ceil(this.height * scale)
level += 1
}
this.baseLevel = level - single
this.maxLevel = this.numLevels() - 1
this.baseURL = this.urlForTile(this.baseLevel, 0, 0, false)
if (loadBaseImage) {
this.imageForURL(this.baseURL, e => {
this.size = [e.target.naturalWidth, e.target.naturalHeight]
this.baseImage = e.target
})
} else {
this.baseImage = null
this.size = this.getDimensions(this.baseLevel)
}
}
}
get maxLoadableLevel() {
if (this.clip) {
return this.maxLevel
}
return this.type === 'dzi' ? this.maxLevel : this.maxLevel
}
/** Computes the url for the given level, column and and row.
* @param {number} level - The level of the wanted layer
* @param {number} column - The column of the tile
* @param {number} row - The row of the tile
* @returns {string} url
**/
urlForTile(level, column, row, compressed = true) {
let format = this.format
if (compressed &amp;&amp; this.compression) {
let supported = Capabilities.isIOS ? 'pvr' : 'dds'
if (this.compression.indexOf(supported) >= 0) {
format = supported
}
}
if (this.clip) {
let offset = this.offsets[level]
if (offset) {
let { startCol, startRow } = offset
column += startCol
row += startRow
}
}
let url = this.urlTileTemplate
.replace(/\{path\}/g, this.path)
.replace(/\{level\}/g, level)
.replace(/\{row\}/g, row)
.replace(/\{column\}/g, column)
.replace(/\{format\}/g, format)
return url
}
/** Loads the image for the given url and executes a callback function
on completion.
* @param {string} url - The url of the tile
* @param {function} complete - The callback function
* @returns {Image} obj
**/
imageForURL(url, complete) {
let img = new Image()
img.onload = complete.bind(this)
img.src = url
return img
}
/** Computes the columns and rows as well as scaled width and height.
* @param {number} level - The level of the wanted layer
* @returns {array} [cols, rows, width, height]
**/
dimensions(level) {
let dim = this.getDimensions(level)
let tiles = this.getNumTiles(level)
return [tiles[0], tiles[1], dim[0], dim[1]]
}
test() {
//console.log("w=" + this.width + " h=" + this.height + " maxlevel=" + this.maxLevel + " base=" + this.baseLevel)
for (let i = 0; i &lt;= this.maxLevel; i++) {
console.log(
' ' +
i +
' -> ' +
this.getScale(i) +
' [' +
this.dimensions(i) +
']'
)
}
console.log(this.urlForTile(this.baseLevel, 0, 0))
}
}
/**
* A utility class that describes a quad tree of tiles. Each tile on a given
* level has up to four corresponding tiles on the next level. A TileQuadNode
* uses the attributes nw (i.e. northwest), ne, sw, se to link to the
* quad nodes on the next level. The previous attributes links to the quad
* one level below that holds the given quad as nw, ne, sw, or se.
* We use this node class because we need a representation of tiles that are
* needed but not loaded yet to compute tiles which can be abandoned to reduce
* the memory pressure.
*
* @constructor
* @param {level} Number - The level the quad node belongs to
* @param {col} Number - The col of the quad
* @param {row} Number - The level the quad node belongs to
* @param {url} String - The level the quad node belongs to
*/
class TileQuadNode {
constructor(level, col, row, url) {
this.level = level
this.col = col
this.row = row
this.url = url
this.nw = null
this.ne = null
this.sw = null
this.se = null
this.previous = null
}
/** Return True if this node has no successors and can be used as
an indicator of tiles to free.
**/
noQuads() {
if (this.previous === null) return false
return (
this.nw === null &amp;&amp;
this.ne === null &amp;&amp;
this.sw === null &amp;&amp;
this.se === null
)
}
/** Unlink the given quad node
* @param {node} TileQuadNode - The TileQuadNode to remove
**/
unlink(node) {
if (this.nw === node) this.nw = null
if (this.ne === node) this.ne = null
if (this.sw === node) this.sw = null
if (this.se === node) this.se = null
}
/** Link this quad node to the given previous node. Use the north
* and west flags to address nw, ne, sw, and se.
* @param {node} TileQuadNode - The TileQuadNode to remove
* @param {north} Boolean - Link to north (true) or south (false)
* @param {west} Boolean - Link to west (true) or east (false)
**/
link(north, west, previous) {
this.previous = previous
if (north) {
if (west) {
previous.nw = this
} else {
previous.ne = this
}
} else {
if (west) {
previous.sw = this
} else {
previous.se = this
}
}
}
}
/**
* The main class of a deeply zoomable image that is represented by a hierarchy
* of tile layers for each zoom level. This gives the user the impression that
* even huge pictures (up to gigapixel-images) can be zoomed instantaneously,
* since the tiles at smaller levels are scaled immediately and overloaded by
* more detailed tiles at the larger level as fast as possible.
* @constructor
* @param {DeepZoomInfo} deepZoomInfo - Information extracted from a JSON-Object
*/
export class DeepZoomImage extends PIXI.Container {
constructor(
deepZoomInfo,
{
debug = false,
shadow = false,
center = false,
world = null, // Defines the world bounds the images lives in
highResolution = true,
autoLoadTiles = true,
useWorker = '',
minimumLevel = 0,
alpha = 1,
app = window.app
} = {}
) {
super()
this.app = app
this.debug = debug
this.shadow = shadow
this.world = world
this.useWorker = useWorker
this.resolution = highResolution
? Math.round(window.devicePixelRatio)
: 1
this.alpha = alpha
this.fastLoads = 0
this.active = true
this.autoLoadTiles = autoLoadTiles
this.minimumLevel = minimumLevel
this.quadTrees = new Map() // url as keys, TileQuadNodes as values
this.setup(deepZoomInfo, center)
}
get point() {
if (this._point == null) {
let graphics = new PIXI.Graphics()
graphics.lineStyle(2, 0x00ff00)
graphics.drawCircle(0, 0, 2)
graphics.interactive = false
this._point = graphics
}
return this._point
}
/** Reads the DeepZoomInfo object and initializes all tile layers.
* Called by the constructor.
* Creates the sprite for the loaded texture and add the sprite to the tile
* layer.
* @param {Object} deepZoomInfo - the DeepZoomInfo instance
* @param {boolean} center - If true ensures that the pivot is set to the center
**/
setup(deepZoomInfo, center) {
this.info = deepZoomInfo
this.interactive = true
this.tileLayers = {}
this._foreground = null
this.tileContainer = new PIXI.Container()
this.tileContainer.interactive = false
let [w, h] = this.baseSize
if (this.shadow) {
this.filters = [new PIXI.filters.DropShadowFilter(45, 3)]
}
this.addChild(this.tileContainer)
if (deepZoomInfo.clip) {
let mask = new PIXI.Graphics()
mask.beginFill(1, 1)
mask.drawRect(0, 0, w, h)
mask.endFill()
this.mask = mask
mask.alpha = 0
this.addChild(mask)
this.minimumLevel = deepZoomInfo.baseLevel
}
this.currentLevel = Math.max(this.minimumLevel, deepZoomInfo.baseLevel)
//console.log("autoLoadTiles", this.autoLoadTiles)
if (this.autoLoadTiles) {
this.setupTiles(center)
}
}
/** Default setup method for tiles. Loads all tiles of the current level.
Can be overwritten in subclasses.
@param {boolean} center - If true ensures that the pivot is set to the center
**/
setupTiles(center = false) {
// First load background tile
let tiles = this.ensureAllTiles(this.currentLevel)
if (center) {
this.pivot.set(w / 2, h / 2)
}
let scaleLevel = this.levelForScale(1)
this.ensureAllTiles(scaleLevel)
}
removeTileQuadNode(level, col, row, url) {
if (this.quadTrees.has(url)) {
let quad = this.quadTrees.get(url)
this.tileQuadRemoved(quad)
this.quadTrees.delete(url)
}
}
addTileQuadNode(level, col, row, url) {
if (this.quadTrees.has(url)) return this.quadTrees.get(url)
let quad = new TileQuadNode(level, col, row, url)
this.quadTrees.set(url, quad)
this.tileQuadAdded(quad)
return quad
}
tileQuadRemoved(quad) {
let below = quad.previous
// if (this.debug) console.log("tileQuadRemoved", quad)
if (below) {
below.unlink(quad)
if (below.noQuads()) {
if (this.debug) console.log('Removed tile below')
let levelBelow = quad.level - 1
if (levelBelow &lt; this.minimumLevel) return
let c = Math.floor(quad.col / 2)
let r = Math.floor(quad.row / 2)
let urlBelow = this.info.urlForTile(levelBelow, c, r)
if (this.quadTrees.has(urlBelow)) {
this.removeTileQuadNode(levelBelow, c, r, urlBelow)
}
}
}
}
tileQuadAdded(quad) {
let levelBelow = quad.level - 1
if (levelBelow &lt; this.minimumLevel) return
//if (this.debug) console.log("tileQuadAdded", quad)
let c = Math.floor(quad.col / 2)
let r = Math.floor(quad.row / 2)
let urlBelow = this.info.urlForTile(levelBelow, c, r)
let below = null
if (!this.quadTrees.has(urlBelow)) {
below = this.addTileQuadNode(levelBelow, c, r, urlBelow)
quad.link(isEven(quad.row), isEven(quad.col), below)
}
}
/** Returns the tile layer level that corresponds to the given scale.
* @param {number} scale - the scale factor
**/
levelForScale(scale) {
let level = Math.round(Math.log2(scale * this.resolution)) // Math.floor(Math.log2(event.scale))+1
let newLevel = this.info.baseLevel + Math.max(level, 0)
return Math.min(newLevel, this.info.maxLoadableLevel)
}
/** Returns the tile layer level that corresponds to the given scale.
* @param {number} scale - the scale factor
**/
levelAndAlphaForScale(scale) {
let value = Math.log2(scale * this.resolution)
let level = Math.round(value)
let newLevel = this.info.baseLevel + Math.max(level, 0)
return { level: Math.min(newLevel, this.info.maxLoadableLevel), alpha: value - level }
}
/** Adds a tile layer to the DeepZoomImage.
* @param {string} key - the access key
* @param {Tiles} tiles - the tile layer object
**/
addTiles(key, tiles) {
if (key in this.tileLayers) {
console.warn('Tiles already availabl', key)
}
this.tileContainer.addChild(tiles)
this.tileLayers[key] = tiles
}
destroyTiles(key) {
let tiles = this.tileLayers[key]
this.tileContainer.removeChild(tiles)
tiles.destroy()
delete this.tileLayers[key]
}
/** Getter for PIXI.Container foreground layer.
* Adds a PIXI.Container if necessary.
**/
get foreground() {
if (this._foreground == null) {
this._foreground = new PIXI.Container()
this.addChild(this._foreground)
}
return this._foreground
}
/** Getter for the DeepZoomInfo base level size.
**/
get baseSize() {
return this.info.getDimensions(this.info.baseLevel)
}
/** Getter for the current scaled size in pixels.
**/
get pixelSize() {
let [w, h] = this.baseSize
return [w * this.scale.x, h * this.scale.y]
}
/** Getter for the max scale factor.
**/
get maxScale() {
let delta = this.info.maxLevel - this.info.baseLevel
return Math.pow(2, delta) / this.resolution * 2
}
/** Getter for the current width.
**/
get width() {
return this.pixelSize[0]
}
/** Getter for the current height.
**/
get height() {
return this.pixelSize[1]
}
/* Overrides PIXI.Container.hitArea()
* Allows to optimize the hit testing. Container with hit areas are directly
* hit tested without consideration of children.
*/
get hitArea() {
// Defining the hitArea resulted hitting the scatter in masked area
// when a mask was used (@Tüsch[submaps]). Removing the hitArea() altogether
// broke the interaction in other projects (@googleart).
// Fix: When masked, the hitArea is ignored by returning null.
// TODO: test if childs are hittested, without setting interactiveChildren.
// Opel, 03-05-2018
if (this.mask) {
return null
}
return this
}
/* Overrides PIXI.Container.contains()
* Allows to optimize the hit testing.
*/
contains(x, y) {
let [w, h] = this.baseSize
return x >= 0 &amp;&amp; x &lt;= w &amp;&amp; y >= 0 &amp;&amp; y &lt;= h
}
/** Overrides PIXI.Container._calculateBounds()
* Only considers the base size and reduces the calculation to a single
* rect.
*/
_calculateBounds() {
let [w, h] = this.baseSize
this._bounds.addFrame(this.transform, 0, 0, w, h)
}
/** Overrides PIXI.Container.calculateBounds()
* Skips the children and only considers the deep zoom base size. Calls
* the also overwritten _calculateBounds method.
*/
calculateBounds() {
this._bounds.clear()
this._calculateBounds()
this._lastBoundsID = this._boundsID
}
/** Returns a single sprite that can be used a thumbnail representation of
* large images.
* @return {Sprite} sprite - A sprite with a single tile texture
*/
thumbnail() {
return new PIXI.Sprite.fromImage(this.info.baseURL)
}
/** Returns a list of all tiles of a given level.
* @param {Tiles} tiles - the grid of tiles
* @param {number} level - The zoom level of the grid
* @return {Array[]} - An array of [url, col, row] arrays
**/
allTiles(tiles, level) {
let result = []
for (let col = 0; col &lt; tiles.cols; col++) {
for (let row = 0; row &lt; tiles.rows; row++) {
let url = this.info.urlForTile(level, col, row)
result.push([url, col, row])
}
}
return result
}
worldBounds() {
let viewBounds = this.app.scene.bounds || this.app.scene.getBounds()
// Using getBounds extends visible scope after loading tiles and leads
// to excessive loading. So we prefer bounds over getBounds()
if (this.world != null) {
let bounds = this.world.bounds
let x = Math.max(-bounds.width, bounds.x)
let y = Math.max(-bounds.height, bounds.y)
let width = Math.min(viewBounds.width, bounds.width)
let height = Math.min(viewBounds.height, bounds.height)
//console.log("worldBounds new", { x, y, width, height })
return { x, y, width, height }
}
//console.log("worldBounds old", viewBounds)
return viewBounds
}
/** Loads all tiles that are needed to fill the app bounds.
* @param {Tiles} tiles - the grid of tiles
* @param {number} level - The zoom level of the grid
* @param {boolean} debug
* @return {Array[]} - An array of [url, col, row] arrays
*/
neededTiles(tiles, level, debug = false) {
let needed = []
let tsize = tiles.tileSize
let worldBounds = this.worldBounds()
let maxWidth = worldBounds.width
let maxHeight = worldBounds.height
let pointInWindow = new PIXI.Point()
let worldTopLeft = new PIXI.Point(worldBounds.x, worldBounds.y)
let worldBottomRight = new PIXI.Point(worldBounds.x + maxWidth, worldBounds.y + maxHeight)
let worldCenter = new PIXI.Point(worldBounds.x + maxWidth / 2, worldBounds.y + maxHeight / 2)
let tilesCenter = tiles.toLocal(worldCenter)
let topLeft = tiles.toLocal(worldTopLeft)
let bottomRight = tiles.toLocal(worldBottomRight)
tiles._centerPoint = tilesCenter
let bounds = new PIXI.Rectangle(
topLeft.x,
topLeft.y,
bottomRight.x - topLeft.x,
bottomRight.y - topLeft.y)
tiles._boundsRect = bounds
/* UO: we need a toLocal call here since the transform may need an update
which is guaranteed by the toLocal method. */
let centerCol = Math.floor(tilesCenter.x / tsize)
let centerRow = Math.floor(tilesCenter.y / tsize)
// Expand because we want to test for included centers
bounds.x -= tsize / 2
bounds.y -= tsize / 2
bounds.width += tsize
bounds.height += tsize
try {
let maxTilesWidth = Math.ceil(maxWidth / tsize)
let maxTilesHeight = Math.ceil(maxHeight / tsize)
maxTilesWidth += 2
maxTilesHeight += 2
let startCol = Math.max(0, centerCol - maxTilesWidth)
let endCol = Math.min(tiles.cols, centerCol + maxTilesWidth)
let startRow = Math.max(0, centerRow - maxTilesHeight)
let endRow = Math.min(tiles.rows, centerRow + maxTilesHeight)
for (let col = startCol; col &lt; endCol; col++) {
let cx = (col + 0.5) * tsize
for (let row = startRow; row &lt; endRow; row++) {
let cy = (row + 0.5) * tsize
let tileCenter = new PIXI.Point(cx, cy)
if (bounds.contains(tileCenter.x, tileCenter.y)) {
let url = this.info.urlForTile(level, col, row)
needed.push([url, col, row])
}
}
}
} catch (error) {
console.warn(error.message)
}
return { centerCol, centerRow, needed }
}
/** Returns all changed tiles for a given level.
* @param {Tiles} tiles - the grid of tiles
* @param {number} level - The zoom level of the grid
* @return {object} - An object with the keys added and removed which values are [url, col, row] arrays
*/
changedTiles(tiles, level) {
if (this.debug) console.time('changedTiles')
let changed = { added: [], removed: [] }
let newNeeded = new Map()
let { centerCol, centerRow, needed } = this.neededTiles(tiles, level)
needed.forEach(d => {
let [url, col, row] = d
newNeeded.set(url, [col, row])
if (!tiles.requested.has(url)) {
changed.added.push(d)
}
})
for (let url of tiles.needed.keys()) {
if (!newNeeded.has(url)) {
let [col, row] = tiles.needed.get(url)
changed.removed.push([url, col, row])
}
}
tiles.needed = newNeeded
if (this.debug) console.log(newNeeded)
if (this.debug) console.timeEnd('changedTiles')
return { centerCol, centerRow, changed }
}
/** Populates all tiles for a given level.
* @param {Tiles} tiles - the grid of tiles
* @param {number} level - The zoom level of the grid
*/
populateAllTiles(tiles, level) {
let all = this.allTiles(tiles, level)
for (let [url, col, row] of all) {
this.addTileQuadNode(level, col, row, url)
}
tiles.loadTiles(all, false, 0, 0)
}
/** Loads all tiles that are needed to fill the browser window.
* If the optional about parameter is provided (as a point with col as x,
* and row as y attr) the tiles are sorted by the distance to this point.
*
* @param {Tiles} tiles - the grid of tiles
* @param {number} level - The zoom level of the grid
* Optional parameter:
* @param {boolean} onlyone - if true only one tile is loaded
* @param {PIXI.Point} about - point of interaction
*/
populateTiles(tiles, level, { onlyone = false, about = null } = {}) {
if (tiles.isComplete())
return
let referenceCol = -1
let referenceRow = -1
let { centerCol, centerRow, changed } = this.changedTiles(tiles, level)
if (about != null) {
// We want to load tiles in the focus of the user first, therefore
// we sort according to the distance of the focus of interaction
let refPoint = this.toLocal(about)
let scaledTileSize = tiles.tileSize * tiles.tileScale
referenceCol = Math.floor(refPoint.x / scaledTileSize)
referenceRow = Math.floor(refPoint.y / scaledTileSize)
}
else {
referenceCol = centerCol
referenceRow = centerRow
}
referenceCol = centerCol
referenceRow = centerRow
let removed = changed.removed
for (let [url, col, row] of removed) {
this.removeTileQuadNode(level, col, row, url)
}
let added = changed.added
if (added.length == 0) return
for (let [url, col, row] of added) {
this.addTileQuadNode(level, col, row, url)
}
let ref = new PIXI.Point(referenceCol, referenceRow)
// Note: The array must be sorted in a way that the nearest tiles
// are at the end of the array since the load queue uses Array.push
// Array.pop
added.sort((a, b) => {
let aa = new PIXI.Point(a[1], a[2])
let bb = new PIXI.Point(b[1], b[2])
let da = Points.distance(aa, ref)
let db = Points.distance(bb, ref)
return db - da
})
tiles.loadTiles(added, onlyone, referenceCol, referenceRow)
}
/** Private method: creates all tiles for a given level.
* @param {number} level - The zoom level of the grid
* @return {Tiles} - tiles
*/
_createTiles(key, level) {
let [cols, rows, w, h] = this.info.dimensions(level)
let increasedLevels = level - this.info.baseLevel
let invScale = Math.pow(0.5, increasedLevels)
let tiles = new Tiles(
level,
this,
invScale,
cols,
rows,
w,
h,
this.info.tileSize,
this.info.overlap
)
this.addTiles(key, tiles)
if (this.info.clip) {
let rest = this.info.rests[level]
if (rest) {
let x = rest.restCol * this.info.tileSize * invScale
let y = rest.restRow * this.info.tileSize * invScale
tiles.x = -x
tiles.y = -y
}
}
return tiles
}
/** Ensures that all needed tiles of a given level are loaded. Creates
* a new Tiles layer if necessary
* @param {number} level - The zoom level of the grid
* @return {Tiles} tiles
*/
ensureTiles(level, about) {
let key = level.toString()
if (key in this.tileLayers) {
let tiles = this.tileLayers[key]
this.populateTiles(tiles, level, { about: about })
return tiles
}
let tiles = this._createTiles(key, level)
this.populateTiles(tiles, level, { about: about })
//console.log("ensureTiles", level)
return tiles
}
untintTiles(level) {
let key = level.toString()
if (key in this.tileLayers) {
let tiles = this.tileLayers[key]
}
}
/** Ensures that all tiles of a given level are loaded.
* @param {number} level - The zoom level of the grid
*/
ensureAllTiles(level) {
let key = level.toString()
if (key in this.tileLayers) {
let tiles = this.tileLayers[key]
this.populateAllTiles(tiles, level)
tiles.keep = true
return
}
let tiles = this._createTiles(key, level)
this.populateAllTiles(tiles, level)
tiles.keep = true
return tiles
}
hideTilesAboveLevel(level) {
Object.keys(this.tileLayers).forEach(key => {
let tiles = this.tileLayers[key]
if (tiles.level > level) {
tiles.visible = false
}
})
}
/** Destroys all tiles above a given level to ensure that the memory can
* be reused.
* @param {number} level - The zoom level of the grid
*/
destroyTilesAboveLevel(level) {
Object.keys(this.tileLayers).forEach(key => {
let tiles = this.tileLayers[key]
if (tiles.level > level &amp;&amp; !tiles.keep) {
for (let url of tiles.available.keys()) {
let quad = this.quadTrees.get(url)
if (quad) this.removeTileQuadNode(quad)
}
this.destroyTiles(key)
}
})
}
destroyAllTiles() {
Object.keys(this.tileLayers).forEach(key => {
this.destroyTiles(key)
})
}
/**
* Tint tiles in all layers that are no longer needed
*
* @memberof DeepZoomImage
*/
tintObsoleteTiles() {
Object.keys(this.tileLayers).forEach(key => {
let tiles = this.tileLayers[key]
tiles.untintTiles()
if (!tiles.keep) {
tiles.tintObsoleteTiles()
}
})
}
/**
* Destroy tiles in all layers that are no longer needed
*
* @memberof DeepZoomImage
*/
destroyUnneededTiles() {
Object.keys(this.tileLayers).forEach(key => {
let tiles = this.tileLayers[key]
if (!tiles.keep) {
tiles.destroyUnneededTiles()
}
})
}
/**
* Destroy tiles in all layers that are no longer needed
*
* @memberof DeepZoomImage
*/
destroyObsoleteTiles() {
Object.keys(this.tileLayers).forEach(key => {
let tiles = this.tileLayers[key]
if (!tiles.keep) {
tiles.destroyObsoleteTiles()
}
})
}
/**
* Destroy tiles in all layers that are not part of the
* visible quadTrees
*
* @memberof DeepZoomImage
*/
destroyTiles() {
Object.keys(this.tileLayers).forEach(key => {
let tiles = this.tileLayers[key]
if (!tiles.keep) {
tiles.destroyTiles(this.quadTrees)
}
})
}
/* Tint all tiles
* @param {number} level - The zoom level of the grid
*/
tintTilesBelowLevel(level) {
Object.keys(this.tileLayers).forEach(key => {
let tiles = this.tileLayers[key]
if (tiles.level &lt; level) {
tiles.tintTiles(this.quadTrees)
}
})
}
/**
* Ensure that the given tiles layer is the topmost one and visible.
* @param {*} tiles
*/
bringTilesToFront(tiles) {
this.tileContainer.addChild(tiles)
tiles.visible = true
}
/** A callback function that can be used by a Scatter view to inform
* the zoomable image that it has been moved, rotated or scaled, and should
* load tiles accordingly.
* @param {PIXI.Point} translated - the movement of the scatter
* @param {number} scale - the zoom factor
* @param {PIXI.Point} about - the anchor point of the zoom
* @param {boolean} fast - informs the callback to return as fast as possible,
* i.e. after loading a single tile
* @param {boolean} debug - log debug infos
*/
transformed(event) {
if (!this.active) {
return
}
let key = this.currentLevel.toString()
let currentTiles = this.tileLayers[key]
if (typeof currentTiles == 'undefined') {
return
}
if (event.fast) {
this.fastLoads += 1
this.populateTiles(currentTiles, this.currentLevel, {
onlyone: false,
about: event.about
})
if (this.fastLoads == 3) {
this.fastLoads = 0
}
else {
return
}
}
if (event.scale == null) {
this.ensureTiles(this.currentLevel, event.about)
return
}
let level = this.levelForScale(event.scale)
let newLevel = Math.max(level, this.minimumLevel)
if (newLevel != this.currentLevel) {
if (!currentTiles.keep) {
currentTiles.loader.cancel()
}
this.hideTilesAboveLevel(newLevel)
currentTiles = this.ensureTiles(newLevel, event.about)
this.currentLevel = newLevel
} else {
this.ensureTiles(this.currentLevel, event.about)
}
this.bringTilesToFront(currentTiles)
if (this._foreground) {
this.addChild(this._foreground)
}
}
/**
*Activates the textures on the DeepZoomImage.
*
* @memberof DeepZoomImage
*/
activate() {
this.active = true
this.destroyTilesAboveLevel(this.currentLevel)
this.ensureTiles(this.currentLevel, null)
//console.log("Activate Textures!", this.currentLevel)
}
/**
*Dectivates the textures on the DeepZoomImage.
*
* @memberof DeepZoomImage
*/
deactivate() {
this.active = false
this.destroyAllTiles()
this.tileContainer.destroy({ children: true })
}
throwFinished() {
//console.log("throwFinished")
let key = this.currentLevel.toString()
let currentTiles = this.tileLayers[key]
if (typeof currentTiles == 'undefined') {
return
}
this.ensureTiles(this.currentLevel)
}
}
</code></pre>
</article>
</section>
<footer class="content-size">
<div class="footer">
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.3</a> on Tue Jul 30 2019 10:48:36 GMT+0200 (Mitteleuropäische Sommerzeit)
</div>
</footer>
</div>
</div>
<script>prettyPrint();</script>
<script src="scripts/main.js"></script>
</body>
</html>