Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9042579518 | |||
| 11bc20fad5 | |||
| 8b9ed733dd | |||
| 5c95128dfc | |||
| beca78d7a7 | |||
| 54a1e74e27 | |||
| 909ef9d242 | |||
| 6ec0e9631a | |||
| 6f7a18d6b8 | |||
| 322fdf8deb | |||
| 012fe4bc4a | |||
| 502bdf47a3 | |||
| 437320b4ad | |||
| 3b6402a682 | |||
| fa25d13469 | |||
| 4c08359394 | |||
| b5400c8223 | |||
| 5a336e8d40 | |||
| 2d1a6b1b7f | |||
| 636e2e439c | |||
| b208592e3a | |||
| 95d1941545 | |||
| 086dfff19e | |||
| 0442df4287 | |||
| e3d167bd7f | |||
| da5ed78558 |
@@ -7,7 +7,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const puppeteer = require('puppeteer');
|
const puppeteer = require('puppeteer');
|
||||||
const fs = require("fs")
|
const fs_bare = require("fs") // required for fs-extra
|
||||||
|
const fs = require("fs-extra")
|
||||||
const path = require("path")
|
const path = require("path")
|
||||||
const start_dir = process.cwd()
|
const start_dir = process.cwd()
|
||||||
const start_file = path.join(start_dir,"lib","index.html")
|
const start_file = path.join(start_dir,"lib","index.html")
|
||||||
@@ -39,18 +40,24 @@ async function makeScreenshot(href){
|
|||||||
page.once("load",logPageEvent)
|
page.once("load",logPageEvent)
|
||||||
|
|
||||||
await page.goto(href)
|
await page.goto(href)
|
||||||
|
href = href.replace("file:///","")
|
||||||
const fname = path.parse(href).name
|
const fname = path.parse(href).name
|
||||||
|
let fpath
|
||||||
if (fname != "index"){
|
if (fname != "index"){
|
||||||
image_url = href.replace(fname + ".html" ,"thumbnails/" + fname + ".png")
|
image_url = href.replace(fname + ".html" ,"thumbnails/" + fname + ".png")
|
||||||
|
fpath = href.replace(fname + ".html", "thumbnails")
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
image_url = href.replace(fname + ".html" ,"thumbnail.png")
|
image_url = href.replace(fname + ".html" ,"thumbnail.png")
|
||||||
|
fpath = href.replace(fname + ".html", "")
|
||||||
}
|
}
|
||||||
image_url = image_url.replace("file:///","")
|
// image_url = image_url.replace("file:///","")
|
||||||
|
// fpath = fpath.replace("file:///","")
|
||||||
|
|
||||||
page.removeAllListeners()
|
page.removeAllListeners()
|
||||||
|
|
||||||
|
fs.ensureDir(fpath)
|
||||||
|
|
||||||
await page.screenshot({path: image_url});
|
await page.screenshot({path: image_url});
|
||||||
await browser.close();
|
await browser.close();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2336,8 +2336,6 @@
|
|||||||
onMouseWheel(event) {
|
onMouseWheel(event) {
|
||||||
if (this.capture(event) && this.target.onMouseWheel) {
|
if (this.capture(event) && this.target.onMouseWheel) {
|
||||||
this.target.onMouseWheel(event);
|
this.target.onMouseWheel(event);
|
||||||
} else {
|
|
||||||
//console.warn('Target has no onMouseWheel callback')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2531,8 +2529,6 @@
|
|||||||
}
|
}
|
||||||
if (this.target.onMouseWheel) {
|
if (this.target.onMouseWheel) {
|
||||||
this.target.onMouseWheel(event);
|
this.target.onMouseWheel(event);
|
||||||
} else {
|
|
||||||
//console.warn('Target has no onMouseWheel callback', this.target)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2999,11 +2995,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
animateThrow(time) {
|
_throwDeltaTime() {
|
||||||
if (this.velocity != null) {
|
|
||||||
let t = performance.now();
|
let t = performance.now();
|
||||||
let dt = t - this.lastframe;
|
let dt = t - this.lastframe;
|
||||||
this.lastframe = t;
|
this.lastframe = t;
|
||||||
|
return dt
|
||||||
|
}
|
||||||
|
|
||||||
|
animateThrow(time) {
|
||||||
|
if (this.velocity != null) {
|
||||||
|
let dt = this._throwDeltaTime();
|
||||||
// console.log("animateThrow", dt)
|
// console.log("animateThrow", dt)
|
||||||
let next = this.nextVelocity(this.velocity);
|
let next = this.nextVelocity(this.velocity);
|
||||||
let prevLength = Points.length(this.velocity);
|
let prevLength = Points.length(this.velocity);
|
||||||
@@ -4206,10 +4207,7 @@
|
|||||||
let event = new ResizeEvent(this, { width: w, height: h });
|
let event = new ResizeEvent(this, { width: w, height: h });
|
||||||
this.onResize(event);
|
this.onResize(event);
|
||||||
}
|
}
|
||||||
if (this.resizeButton != null) {
|
if (this.resizeButton != null) ;
|
||||||
// this.resizeButton.style.width = 50/this.scale+"px"
|
|
||||||
// this.resizeButton.style.height = 50/this.scale+"px"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
startResize(e) {
|
startResize(e) {
|
||||||
@@ -4260,7 +4258,7 @@
|
|||||||
let resizeW = r * Math.cos(Angle.degree2radian(phiCorrected));
|
let resizeW = r * Math.cos(Angle.degree2radian(phiCorrected));
|
||||||
let resizeH = -r * Math.sin(Angle.degree2radian(phiCorrected));
|
let resizeH = -r * Math.sin(Angle.degree2radian(phiCorrected));
|
||||||
|
|
||||||
if (this.element.offsetWidth + resizeW / this.scale > this.width * 0.3 && this.element.offsetHeight + resizeH / this.scale > this.height * 0.3) TweenLite.to(this.element, 0, { width: this.element.offsetWidth + resizeW / this.scale, height: this.element.offsetHeight + resizeH / this.scale });
|
if ((this.element.offsetWidth + resizeW) / this.scale > this.width * 0.5 / this.scale && (this.element.offsetHeight + resizeH) / this.scale > this.height * 0.3 / this.scale) TweenLite.to(this.element, 0, { width: this.element.offsetWidth + resizeW / this.scale, height: this.element.offsetHeight + resizeH / this.scale });
|
||||||
|
|
||||||
this.oldX = e.clientX;
|
this.oldX = e.clientX;
|
||||||
this.oldY = e.clientY;
|
this.oldY = e.clientY;
|
||||||
|
|||||||
@@ -5500,8 +5500,6 @@
|
|||||||
onMouseWheel(event) {
|
onMouseWheel(event) {
|
||||||
if (this.capture(event) && this.target.onMouseWheel) {
|
if (this.capture(event) && this.target.onMouseWheel) {
|
||||||
this.target.onMouseWheel(event);
|
this.target.onMouseWheel(event);
|
||||||
} else {
|
|
||||||
//console.warn('Target has no onMouseWheel callback')
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5695,8 +5693,6 @@
|
|||||||
}
|
}
|
||||||
if (this.target.onMouseWheel) {
|
if (this.target.onMouseWheel) {
|
||||||
this.target.onMouseWheel(event);
|
this.target.onMouseWheel(event);
|
||||||
} else {
|
|
||||||
//console.warn('Target has no onMouseWheel callback', this.target)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6163,11 +6159,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
animateThrow(time) {
|
_throwDeltaTime() {
|
||||||
if (this.velocity != null) {
|
|
||||||
let t = performance.now();
|
let t = performance.now();
|
||||||
let dt = t - this.lastframe;
|
let dt = t - this.lastframe;
|
||||||
this.lastframe = t;
|
this.lastframe = t;
|
||||||
|
return dt
|
||||||
|
}
|
||||||
|
|
||||||
|
animateThrow(time) {
|
||||||
|
if (this.velocity != null) {
|
||||||
|
let dt = this._throwDeltaTime();
|
||||||
// console.log("animateThrow", dt)
|
// console.log("animateThrow", dt)
|
||||||
let next = this.nextVelocity(this.velocity);
|
let next = this.nextVelocity(this.velocity);
|
||||||
let prevLength = Points.length(this.velocity);
|
let prevLength = Points.length(this.velocity);
|
||||||
@@ -7208,10 +7209,7 @@
|
|||||||
let event = new ResizeEvent(this, { width: w, height: h });
|
let event = new ResizeEvent(this, { width: w, height: h });
|
||||||
this.onResize(event);
|
this.onResize(event);
|
||||||
}
|
}
|
||||||
if (this.resizeButton != null) {
|
if (this.resizeButton != null) ;
|
||||||
// this.resizeButton.style.width = 50/this.scale+"px"
|
|
||||||
// this.resizeButton.style.height = 50/this.scale+"px"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
startResize(e) {
|
startResize(e) {
|
||||||
@@ -7262,7 +7260,7 @@
|
|||||||
let resizeW = r * Math.cos(Angle.degree2radian(phiCorrected));
|
let resizeW = r * Math.cos(Angle.degree2radian(phiCorrected));
|
||||||
let resizeH = -r * Math.sin(Angle.degree2radian(phiCorrected));
|
let resizeH = -r * Math.sin(Angle.degree2radian(phiCorrected));
|
||||||
|
|
||||||
if (this.element.offsetWidth + resizeW / this.scale > this.width * 0.3 && this.element.offsetHeight + resizeH / this.scale > this.height * 0.3) TweenLite.to(this.element, 0, { width: this.element.offsetWidth + resizeW / this.scale, height: this.element.offsetHeight + resizeH / this.scale });
|
if ((this.element.offsetWidth + resizeW) / this.scale > this.width * 0.5 / this.scale && (this.element.offsetHeight + resizeH) / this.scale > this.height * 0.3 / this.scale) TweenLite.to(this.element, 0, { width: this.element.offsetWidth + resizeW / this.scale, height: this.element.offsetHeight + resizeH / this.scale });
|
||||||
|
|
||||||
this.oldX = e.clientX;
|
this.oldX = e.clientX;
|
||||||
this.oldY = e.clientY;
|
this.oldY = e.clientY;
|
||||||
@@ -7803,11 +7801,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ES Lint */
|
||||||
|
/* globals PIXI, console*/
|
||||||
|
|
||||||
const registeredTiles = new Map();
|
const registeredTiles = new Map();
|
||||||
const pendingTiles = new Map();
|
// const pendingTiles = new Map()
|
||||||
/** Implements a baseTexture cache. The last textures are kept for reuse */
|
/** Implements a baseTexture cache. The last textures are kept for reuse */
|
||||||
const keepBaseTextures = 0;
|
let keepTextures = 0;
|
||||||
const keptBaseTextures = [];
|
const keptTextures = [];
|
||||||
|
|
||||||
/** The current Tile implementation simply uses PIXI.Sprites.
|
/** The current Tile implementation simply uses PIXI.Sprites.
|
||||||
*
|
*
|
||||||
@@ -7828,8 +7829,8 @@
|
|||||||
* @param {*} value
|
* @param {*} value
|
||||||
* @memberof Tile
|
* @memberof Tile
|
||||||
*/
|
*/
|
||||||
static enableKeepBaseTextures(value = 1000) {
|
static enableKeepTextures(value = 1000) {
|
||||||
keepBaseTextures = value;
|
keepTextures = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7839,25 +7840,14 @@
|
|||||||
* @param {*} url
|
* @param {*} url
|
||||||
* @memberof Tile
|
* @memberof Tile
|
||||||
*/
|
*/
|
||||||
static schedule(url) {
|
/* static schedule(url) {
|
||||||
let count = 0;
|
let count = 0
|
||||||
if (pendingTiles.has(url)) {
|
if (pendingTiles.has(url)) {
|
||||||
count = pendingTiles.get(url);
|
count = pendingTiles.get(url)
|
||||||
}
|
}
|
||||||
pendingTiles.set(url, count + 1);
|
pendingTiles.set(url, count + 1)
|
||||||
// console.log("Tile.scheduled", url, pendingTiles.size)
|
// console.log("Tile.scheduled", url, pendingTiles.size)
|
||||||
}
|
} */
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true iff the url is pending
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
* @returns
|
|
||||||
* @memberof Tile
|
|
||||||
*/
|
|
||||||
static isPending() {
|
|
||||||
return pendingTiles.has(url) && pendingTiles.get(url) > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the given url from pending urls.
|
* Removes the given url from pending urls.
|
||||||
@@ -7866,17 +7856,37 @@
|
|||||||
* @param {*} url
|
* @param {*} url
|
||||||
* @memberof Tile
|
* @memberof Tile
|
||||||
*/
|
*/
|
||||||
static unschedule(url) {
|
/* static unschedule(url) {
|
||||||
if (pendingTiles.has(url)) {
|
if (pendingTiles.has(url)) {
|
||||||
let count = pendingTiles.get(url);
|
let count = pendingTiles.get(url)
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
pendingTiles.set(url, count - 1);
|
pendingTiles.set(url, count - 1)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pendingTiles.clear(url);
|
pendingTiles.clear(url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// console.log("Tile.unscheduled", url, pendingTiles.size)
|
// console.log("Tile.unscheduled", url, pendingTiles.size)
|
||||||
|
} */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true iff the url is pending
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @param {*} url
|
||||||
|
* @returns
|
||||||
|
* @memberof Tile
|
||||||
|
*/
|
||||||
|
/*static isPending(url) {
|
||||||
|
return pendingTiles.has(url) && pendingTiles.get(url) > 0
|
||||||
|
} */
|
||||||
|
|
||||||
|
static isObsolete(url) {
|
||||||
|
if (registeredTiles.has(url) && registeredTiles.get(url) > 0) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7901,7 +7911,7 @@
|
|||||||
* @memberof Tile
|
* @memberof Tile
|
||||||
*/
|
*/
|
||||||
register(url, debug = false) {
|
register(url, debug = false) {
|
||||||
Tile.unschedule(url);
|
//Tile.unschedule(url)
|
||||||
if (registeredTiles.has(url)) {
|
if (registeredTiles.has(url)) {
|
||||||
let tiles = registeredTiles.get(url);
|
let tiles = registeredTiles.get(url);
|
||||||
tiles.add(this);
|
tiles.add(this);
|
||||||
@@ -7924,6 +7934,7 @@
|
|||||||
tiles.delete(this);
|
tiles.delete(this);
|
||||||
if (tiles.size == 0) {
|
if (tiles.size == 0) {
|
||||||
registeredTiles.delete(this.url);
|
registeredTiles.delete(this.url);
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
return tiles.size
|
return tiles.size
|
||||||
}
|
}
|
||||||
@@ -7934,28 +7945,27 @@
|
|||||||
* @param {*} options Part of the PIXI API, but ignored in the implementation
|
* @param {*} options Part of the PIXI API, but ignored in the implementation
|
||||||
* @memberof Tile
|
* @memberof Tile
|
||||||
*/
|
*/
|
||||||
destroy(options, debug = true) {
|
destroy(options, debug = false) {
|
||||||
let count = this.unregister();
|
let count = this.unregister();
|
||||||
|
|
||||||
if (keepBaseTextures > 0) {
|
if (keepTextures > 0) {
|
||||||
keptBaseTextures.push({ url: this.url, texture: this.texture.baseTexture});
|
keptTextures.push({ url: this.url, texture: this.texture });
|
||||||
|
|
||||||
let opts = { children: true, texture: false, baseTexture: false };
|
let opts = { children: true, texture: false, baseTexture: false };
|
||||||
if (debug) console.log("Tile.destroy", registeredTiles.size, opts);
|
if (debug) console.log("Tile.destroy", registeredTiles.size, opts);
|
||||||
super.destroy(opts);
|
super.destroy(opts);
|
||||||
|
|
||||||
while(keptBaseTextures.length > keepBaseTextures) {
|
while (keptTextures.length > keepTextures) {
|
||||||
let {url, texture} = keptBaseTextures.shift();
|
let { url, texture } = keptTextures.shift();
|
||||||
let tiles = registeredTiles.get(url);
|
if (Tile.isObsolete(url)) {
|
||||||
if (tiles.size > 0 && !Tile.isPending(url)) {
|
texture.destroy(true); // Destroy base as well
|
||||||
texture.destroy();
|
if (debug) console.log("Destroying texture and baseTexture", url);
|
||||||
if (debug) console.log("Destroying baseTexture", url);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// No longer registered and not pending
|
// No longer registered and not pending
|
||||||
if (count <= 0 && !Tile.isPending(url)) {
|
if (count <= 0) { // && !Tile.isPending(this.url)
|
||||||
let opts = { children: true, texture: true, baseTexture: true };
|
let opts = { children: true, texture: true, baseTexture: true };
|
||||||
super.destroy(opts);
|
super.destroy(opts);
|
||||||
if (debug) console.log("Tile.destroy", registeredTiles.size, opts);
|
if (debug) console.log("Tile.destroy", registeredTiles.size, opts);
|
||||||
@@ -7971,7 +7981,6 @@
|
|||||||
this.visible = false;
|
this.visible = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7992,6 +8001,16 @@
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Texture received too late. We do not need it.
|
||||||
|
* @param {*} url
|
||||||
|
* @param {*} texture
|
||||||
|
*/
|
||||||
|
static lateTexture(url, texture) {
|
||||||
|
let destroyBase = !registeredTiles.has(url);
|
||||||
|
texture.destroy(destroyBase);
|
||||||
|
}
|
||||||
|
|
||||||
static printInfos() {
|
static printInfos() {
|
||||||
let references = new Map();
|
let references = new Map();
|
||||||
let multiples = 0;
|
let multiples = 0;
|
||||||
@@ -8035,7 +8054,7 @@
|
|||||||
if (this.loaded.has(url)) return false
|
if (this.loaded.has(url)) return false
|
||||||
if (this.loading.has(url)) return false
|
if (this.loading.has(url)) return false
|
||||||
|
|
||||||
Tile.schedule(url);
|
//Tile.schedule(url)
|
||||||
this.map.set(url, [col, row]);
|
this.map.set(url, [col, row]);
|
||||||
this.loading.add(url);
|
this.loading.add(url);
|
||||||
this.loadQueue.push(url);
|
this.loadQueue.push(url);
|
||||||
@@ -8045,7 +8064,7 @@
|
|||||||
unschedule(url) {
|
unschedule(url) {
|
||||||
if (this.loaded.has(url)) this.loaded.delete(url);
|
if (this.loaded.has(url)) this.loaded.delete(url);
|
||||||
if (this.loading.has(url)) this.loading.delete(url);
|
if (this.loading.has(url)) this.loading.delete(url);
|
||||||
Tile.unschedule(url);
|
//Tile.unschedule(url)
|
||||||
this.loadQueue = this.loadQueue.filter(item => item != url);
|
this.loadQueue = this.loadQueue.filter(item => item != url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8105,7 +8124,7 @@
|
|||||||
if (this.loaded.has(url)) return false
|
if (this.loaded.has(url)) return false
|
||||||
if (this.loading.has(url)) return false
|
if (this.loading.has(url)) return false
|
||||||
|
|
||||||
Tile.schedule(url);
|
//Tile.schedule(url)
|
||||||
let reusableTexture = Tile.textureAvailable(url);
|
let reusableTexture = Tile.textureAvailable(url);
|
||||||
if (reusableTexture) {
|
if (reusableTexture) {
|
||||||
if (this.debug) console.log('Texture reusable', reusableTexture);
|
if (this.debug) console.log('Texture reusable', reusableTexture);
|
||||||
@@ -8166,8 +8185,8 @@
|
|||||||
_onLoaded(loader, resource) {
|
_onLoaded(loader, resource) {
|
||||||
if (this.destroyed) {
|
if (this.destroyed) {
|
||||||
let texture = resource.texture;
|
let texture = resource.texture;
|
||||||
let destroyBase = !deepZoomTileCache.has(resource.url);
|
let url = resource.url;
|
||||||
texture.destroy(destroyBase);
|
Tile.lateTexture(url, texture);
|
||||||
console.warn("Received resource after destroy", texture);
|
console.warn("Received resource after destroy", texture);
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -8628,9 +8647,6 @@
|
|||||||
return n % 2 == 0
|
return n % 2 == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
function printTileCacheInfos() {
|
|
||||||
Tile.printInfos();
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* A utility class that holds information typically provided by DZI files, i.e.
|
* A utility class that holds information typically provided by DZI files, i.e.
|
||||||
* height and width of the overall image, overlap, and image type.
|
* height and width of the overall image, overlap, and image type.
|
||||||
@@ -8985,6 +9001,7 @@
|
|||||||
: 1;
|
: 1;
|
||||||
this.alpha = alpha;
|
this.alpha = alpha;
|
||||||
this.fastLoads = 0;
|
this.fastLoads = 0;
|
||||||
|
this.active = true;
|
||||||
this.autoLoadTiles = autoLoadTiles;
|
this.autoLoadTiles = autoLoadTiles;
|
||||||
this.minimumLevel = minimumLevel;
|
this.minimumLevel = minimumLevel;
|
||||||
this.quadTrees = new Map(); // url as keys, TileQuadNodes as values
|
this.quadTrees = new Map(); // url as keys, TileQuadNodes as values
|
||||||
@@ -9256,9 +9273,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
worldBounds() {
|
worldBounds() {
|
||||||
let viewBounds = this.app.scene.getBounds();
|
let viewBounds = this.app.scene.bounds || this.app.scene.getBounds();
|
||||||
// Using getBounds extends visible scope after loading tiles and leads
|
// Using getBounds extends visible scope after loading tiles and leads
|
||||||
// to excessive loading
|
// to excessive loading. So we prefer bounds over getBounds()
|
||||||
if (this.world != null) {
|
if (this.world != null) {
|
||||||
let bounds = this.world.bounds;
|
let bounds = this.world.bounds;
|
||||||
let x = Math.max(-bounds.width, bounds.x);
|
let x = Math.max(-bounds.width, bounds.x);
|
||||||
@@ -9638,6 +9655,9 @@
|
|||||||
* @param {boolean} debug - log debug infos
|
* @param {boolean} debug - log debug infos
|
||||||
*/
|
*/
|
||||||
transformed(event) {
|
transformed(event) {
|
||||||
|
if (!this.active) {
|
||||||
|
return
|
||||||
|
}
|
||||||
let key = this.currentLevel.toString();
|
let key = this.currentLevel.toString();
|
||||||
let currentTiles = this.tileLayers[key];
|
let currentTiles = this.tileLayers[key];
|
||||||
if (typeof currentTiles == 'undefined') {
|
if (typeof currentTiles == 'undefined') {
|
||||||
@@ -9685,6 +9705,7 @@
|
|||||||
* @memberof DeepZoomImage
|
* @memberof DeepZoomImage
|
||||||
*/
|
*/
|
||||||
activate() {
|
activate() {
|
||||||
|
this.active = true;
|
||||||
this.destroyTilesAboveLevel(this.currentLevel);
|
this.destroyTilesAboveLevel(this.currentLevel);
|
||||||
this.ensureTiles(this.currentLevel, null);
|
this.ensureTiles(this.currentLevel, null);
|
||||||
//console.log("Activate Textures!", this.currentLevel)
|
//console.log("Activate Textures!", this.currentLevel)
|
||||||
@@ -9696,35 +9717,19 @@
|
|||||||
* @memberof DeepZoomImage
|
* @memberof DeepZoomImage
|
||||||
*/
|
*/
|
||||||
deactivate() {
|
deactivate() {
|
||||||
|
this.active = false;
|
||||||
this.destroyAllTiles();
|
this.destroyAllTiles();
|
||||||
Object.keys(this.tileLayers).forEach(key => {
|
|
||||||
this.destroyTiles(key);
|
|
||||||
});
|
|
||||||
this.tileContainer.destroy({ children: true });
|
this.tileContainer.destroy({ children: true });
|
||||||
printTileCacheInfos();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throwFinished() {
|
throwFinished() {
|
||||||
console.log("throwFinished");
|
//console.log("throwFinished")
|
||||||
let key = this.currentLevel.toString();
|
let key = this.currentLevel.toString();
|
||||||
let currentTiles = this.tileLayers[key];
|
let currentTiles = this.tileLayers[key];
|
||||||
if (typeof currentTiles == 'undefined') {
|
if (typeof currentTiles == 'undefined') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ensureTiles(this.currentLevel);
|
this.ensureTiles(this.currentLevel);
|
||||||
// let all = new Set()
|
|
||||||
// for (let tile of currentTiles.children) {
|
|
||||||
// all.add(tile.url)
|
|
||||||
// }
|
|
||||||
// let { centerCol, centerRow, needed } = this.neededTiles(currentTiles, this.currentLevel)
|
|
||||||
// for (let [url, col, row] of needed) {
|
|
||||||
// all.delete(url)
|
|
||||||
// }
|
|
||||||
// for (let url of all) {
|
|
||||||
// currentTiles.destroyTileByUrl(url)
|
|
||||||
// }
|
|
||||||
// currentTiles.loader.loader.reset()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ a single delegate pattern.
|
|||||||
<p>The main differences are that <code>PointerEvent</code> are fired for each
|
<p>The main differences are that <code>PointerEvent</code> are fired for each
|
||||||
touch point, whereas the <code>TouchEvent</code> collects multiple
|
touch point, whereas the <code>TouchEvent</code> collects multiple
|
||||||
<code>TouchPoints</code> into a single event. The basic PointMap and Interaction
|
<code>TouchPoints</code> into a single event. The basic PointMap and Interaction
|
||||||
classes unify this behavior by collection all contact points regardless
|
classes unify this behavior by collecting all contact points regardless
|
||||||
of their original mouse, touch, or pointer events.</p>
|
of their original mouse, touch, or pointer events.</p>
|
||||||
<h2>
|
<h2>
|
||||||
Point Maps
|
Point Maps
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
let ipc = null
|
let ipc = null
|
||||||
|
let logMessages = new Set()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ipc = require('electron').ipcRenderer
|
ipc = require('electron').ipcRenderer
|
||||||
} catch (e) {}
|
} catch (e) {
|
||||||
|
console.log("Cannot use electron logging.")
|
||||||
|
}
|
||||||
|
|
||||||
/** Basic class for app specific logging requirements.
|
/** Basic class for app specific logging requirements.
|
||||||
* Can be used to implement persistent logging in electron apps.
|
* Can be used to implement persistent logging in electron apps.
|
||||||
|
* Uses a logMessage cache to prevent error overflows. This is
|
||||||
|
* needed since errors may occur very frequently
|
||||||
|
* (e.g. display update loops at 60fps, programmatic loops, ...).
|
||||||
*/
|
*/
|
||||||
export default class Logging {
|
export default class Logging {
|
||||||
|
|
||||||
@@ -20,4 +26,36 @@ export default class Logging {
|
|||||||
console.log(message)
|
console.log(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static warn function.
|
||||||
|
* Emits each warning only once per session.
|
||||||
|
* @param {*} message
|
||||||
|
*/
|
||||||
|
static warn(message) {
|
||||||
|
if (!logMessages.has(message)) {
|
||||||
|
logMessages.add(message)
|
||||||
|
if (ipc) {
|
||||||
|
ipc.send('warn', message)
|
||||||
|
} else {
|
||||||
|
console.warn(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static error function.
|
||||||
|
* Emits each error message only once per session.
|
||||||
|
* @param {*} message
|
||||||
|
*/
|
||||||
|
static error(message) {
|
||||||
|
if (!logMessages.has(message)) {
|
||||||
|
logMessages.add(message)
|
||||||
|
if (ipc) {
|
||||||
|
ipc.send('error', message)
|
||||||
|
} else {
|
||||||
|
console.error(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,9 +7,6 @@ function isEven(n) {
|
|||||||
return n % 2 == 0
|
return n % 2 == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
function printTileCacheInfos() {
|
|
||||||
Tile.printInfos()
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* A utility class that holds information typically provided by DZI files, i.e.
|
* A utility class that holds information typically provided by DZI files, i.e.
|
||||||
* height and width of the overall image, overlap, and image type.
|
* height and width of the overall image, overlap, and image type.
|
||||||
@@ -364,6 +361,7 @@ export class DeepZoomImage extends PIXI.Container {
|
|||||||
: 1
|
: 1
|
||||||
this.alpha = alpha
|
this.alpha = alpha
|
||||||
this.fastLoads = 0
|
this.fastLoads = 0
|
||||||
|
this.active = true
|
||||||
this.autoLoadTiles = autoLoadTiles
|
this.autoLoadTiles = autoLoadTiles
|
||||||
this.minimumLevel = minimumLevel
|
this.minimumLevel = minimumLevel
|
||||||
this.quadTrees = new Map() // url as keys, TileQuadNodes as values
|
this.quadTrees = new Map() // url as keys, TileQuadNodes as values
|
||||||
@@ -635,9 +633,9 @@ export class DeepZoomImage extends PIXI.Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
worldBounds() {
|
worldBounds() {
|
||||||
let viewBounds = this.app.scene.getBounds()
|
let viewBounds = this.app.scene.bounds || this.app.scene.getBounds()
|
||||||
// Using getBounds extends visible scope after loading tiles and leads
|
// Using getBounds extends visible scope after loading tiles and leads
|
||||||
// to excessive loading
|
// to excessive loading. So we prefer bounds over getBounds()
|
||||||
if (this.world != null) {
|
if (this.world != null) {
|
||||||
let bounds = this.world.bounds
|
let bounds = this.world.bounds
|
||||||
let x = Math.max(-bounds.width, bounds.x)
|
let x = Math.max(-bounds.width, bounds.x)
|
||||||
@@ -1017,6 +1015,9 @@ export class DeepZoomImage extends PIXI.Container {
|
|||||||
* @param {boolean} debug - log debug infos
|
* @param {boolean} debug - log debug infos
|
||||||
*/
|
*/
|
||||||
transformed(event) {
|
transformed(event) {
|
||||||
|
if (!this.active) {
|
||||||
|
return
|
||||||
|
}
|
||||||
let key = this.currentLevel.toString()
|
let key = this.currentLevel.toString()
|
||||||
let currentTiles = this.tileLayers[key]
|
let currentTiles = this.tileLayers[key]
|
||||||
if (typeof currentTiles == 'undefined') {
|
if (typeof currentTiles == 'undefined') {
|
||||||
@@ -1064,6 +1065,7 @@ export class DeepZoomImage extends PIXI.Container {
|
|||||||
* @memberof DeepZoomImage
|
* @memberof DeepZoomImage
|
||||||
*/
|
*/
|
||||||
activate() {
|
activate() {
|
||||||
|
this.active = true
|
||||||
this.destroyTilesAboveLevel(this.currentLevel)
|
this.destroyTilesAboveLevel(this.currentLevel)
|
||||||
this.ensureTiles(this.currentLevel, null)
|
this.ensureTiles(this.currentLevel, null)
|
||||||
//console.log("Activate Textures!", this.currentLevel)
|
//console.log("Activate Textures!", this.currentLevel)
|
||||||
@@ -1075,34 +1077,18 @@ export class DeepZoomImage extends PIXI.Container {
|
|||||||
* @memberof DeepZoomImage
|
* @memberof DeepZoomImage
|
||||||
*/
|
*/
|
||||||
deactivate() {
|
deactivate() {
|
||||||
|
this.active = false
|
||||||
this.destroyAllTiles()
|
this.destroyAllTiles()
|
||||||
Object.keys(this.tileLayers).forEach(key => {
|
|
||||||
this.destroyTiles(key)
|
|
||||||
})
|
|
||||||
this.tileContainer.destroy({ children: true })
|
this.tileContainer.destroy({ children: true })
|
||||||
printTileCacheInfos()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throwFinished() {
|
throwFinished() {
|
||||||
console.log("throwFinished")
|
//console.log("throwFinished")
|
||||||
let key = this.currentLevel.toString()
|
let key = this.currentLevel.toString()
|
||||||
let currentTiles = this.tileLayers[key]
|
let currentTiles = this.tileLayers[key]
|
||||||
if (typeof currentTiles == 'undefined') {
|
if (typeof currentTiles == 'undefined') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
this.ensureTiles(this.currentLevel)
|
this.ensureTiles(this.currentLevel)
|
||||||
// let all = new Set()
|
|
||||||
// for (let tile of currentTiles.children) {
|
|
||||||
// all.add(tile.url)
|
|
||||||
// }
|
|
||||||
// let { centerCol, centerRow, needed } = this.neededTiles(currentTiles, this.currentLevel)
|
|
||||||
// for (let [url, col, row] of needed) {
|
|
||||||
// all.delete(url)
|
|
||||||
// }
|
|
||||||
// for (let url of all) {
|
|
||||||
// currentTiles.destroyTileByUrl(url)
|
|
||||||
// }
|
|
||||||
// currentTiles.loader.loader.reset()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export class TileLoader {
|
|||||||
if (this.loaded.has(url)) return false
|
if (this.loaded.has(url)) return false
|
||||||
if (this.loading.has(url)) return false
|
if (this.loading.has(url)) return false
|
||||||
|
|
||||||
Tile.schedule(url)
|
//Tile.schedule(url)
|
||||||
this.map.set(url, [col, row])
|
this.map.set(url, [col, row])
|
||||||
this.loading.add(url)
|
this.loading.add(url)
|
||||||
this.loadQueue.push(url)
|
this.loadQueue.push(url)
|
||||||
@@ -39,7 +39,7 @@ export class TileLoader {
|
|||||||
unschedule(url) {
|
unschedule(url) {
|
||||||
if (this.loaded.has(url)) this.loaded.delete(url)
|
if (this.loaded.has(url)) this.loaded.delete(url)
|
||||||
if (this.loading.has(url)) this.loading.delete(url)
|
if (this.loading.has(url)) this.loading.delete(url)
|
||||||
Tile.unschedule(url)
|
//Tile.unschedule(url)
|
||||||
this.loadQueue = this.loadQueue.filter(item => item != url)
|
this.loadQueue = this.loadQueue.filter(item => item != url)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ export class PIXITileLoader extends TileLoader {
|
|||||||
if (this.loaded.has(url)) return false
|
if (this.loaded.has(url)) return false
|
||||||
if (this.loading.has(url)) return false
|
if (this.loading.has(url)) return false
|
||||||
|
|
||||||
Tile.schedule(url)
|
//Tile.schedule(url)
|
||||||
let reusableTexture = Tile.textureAvailable(url)
|
let reusableTexture = Tile.textureAvailable(url)
|
||||||
if (reusableTexture) {
|
if (reusableTexture) {
|
||||||
if (this.debug) console.log('Texture reusable', reusableTexture)
|
if (this.debug) console.log('Texture reusable', reusableTexture)
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
|
/* ES Lint */
|
||||||
|
/* globals PIXI, console*/
|
||||||
|
|
||||||
const registeredTiles = new Map()
|
const registeredTiles = new Map()
|
||||||
const pendingTiles = new Map()
|
|
||||||
/** Implements a baseTexture cache. The last textures are kept for reuse */
|
/** Implements a baseTexture cache. The last textures are kept for reuse */
|
||||||
let keepTextures = 0
|
let keepTextures = 0
|
||||||
const keptTextures = []
|
const keptTextures = []
|
||||||
|
const lateTextures = new Map()
|
||||||
|
let lastSweepTime = 0
|
||||||
|
let sweepInterval = 2000.0
|
||||||
|
|
||||||
/** The current Tile implementation simply uses PIXI.Sprites.
|
/** The current Tile implementation simply uses PIXI.Sprites.
|
||||||
*
|
*
|
||||||
@@ -28,22 +32,6 @@ export default class Tile extends PIXI.Sprite {
|
|||||||
keepTextures = value
|
keepTextures = value
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Marks the given url as pending. Pending tiles should not be destroyed
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
* @param {*} url
|
|
||||||
* @memberof Tile
|
|
||||||
*/
|
|
||||||
static schedule(url) {
|
|
||||||
let count = 0
|
|
||||||
if (pendingTiles.has(url)) {
|
|
||||||
count = pendingTiles.get(url)
|
|
||||||
}
|
|
||||||
pendingTiles.set(url, count + 1)
|
|
||||||
// console.log("Tile.scheduled", url, pendingTiles.size)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true iff the url is pending
|
* Returns true iff the url is pending
|
||||||
*
|
*
|
||||||
@@ -52,9 +40,9 @@ export default class Tile extends PIXI.Sprite {
|
|||||||
* @returns
|
* @returns
|
||||||
* @memberof Tile
|
* @memberof Tile
|
||||||
*/
|
*/
|
||||||
static isPending(url) {
|
/*static isPending(url) {
|
||||||
return pendingTiles.has(url) && pendingTiles.get(url) > 0
|
return pendingTiles.has(url) && pendingTiles.get(url) > 0
|
||||||
}
|
} */
|
||||||
|
|
||||||
static isObsolete(url) {
|
static isObsolete(url) {
|
||||||
if (registeredTiles.has(url) && registeredTiles.get(url) > 0) {
|
if (registeredTiles.has(url) && registeredTiles.get(url) > 0) {
|
||||||
@@ -63,26 +51,6 @@ export default class Tile extends PIXI.Sprite {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the given url from pending urls.
|
|
||||||
*
|
|
||||||
* @static
|
|
||||||
* @param {*} url
|
|
||||||
* @memberof Tile
|
|
||||||
*/
|
|
||||||
static unschedule(url) {
|
|
||||||
if (pendingTiles.has(url)) {
|
|
||||||
let count = pendingTiles.get(url)
|
|
||||||
if (count > 1) {
|
|
||||||
pendingTiles.set(url, count - 1)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pendingTiles.clear(url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// console.log("Tile.unscheduled", url, pendingTiles.size)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a tile from image using the PIXI.Texture.fromImage method.
|
* Loads a tile from image using the PIXI.Texture.fromImage method.
|
||||||
*
|
*
|
||||||
@@ -105,7 +73,7 @@ export default class Tile extends PIXI.Sprite {
|
|||||||
* @memberof Tile
|
* @memberof Tile
|
||||||
*/
|
*/
|
||||||
register(url, debug = false) {
|
register(url, debug = false) {
|
||||||
Tile.unschedule(url)
|
//Tile.unschedule(url)
|
||||||
if (registeredTiles.has(url)) {
|
if (registeredTiles.has(url)) {
|
||||||
let tiles = registeredTiles.get(url)
|
let tiles = registeredTiles.get(url)
|
||||||
tiles.add(this)
|
tiles.add(this)
|
||||||
@@ -139,18 +107,18 @@ export default class Tile extends PIXI.Sprite {
|
|||||||
* @param {*} options Part of the PIXI API, but ignored in the implementation
|
* @param {*} options Part of the PIXI API, but ignored in the implementation
|
||||||
* @memberof Tile
|
* @memberof Tile
|
||||||
*/
|
*/
|
||||||
destroy(options, debug = true) {
|
destroy(options, debug = false) {
|
||||||
let count = this.unregister()
|
let count = this.unregister()
|
||||||
|
|
||||||
if (keepTextures > 0) {
|
if (keepTextures > 0) {
|
||||||
keptTextures.push({ url: this.url, texture: this.texture})
|
keptTextures.push({ url: this.url, texture: this.texture })
|
||||||
|
|
||||||
let opts = { children: true, texture: false, baseTexture: false }
|
let opts = { children: true, texture: false, baseTexture: false }
|
||||||
if (debug) console.log("Tile.destroy", registeredTiles.size, opts)
|
if (debug) console.log("Tile.destroy", registeredTiles.size, opts)
|
||||||
super.destroy(opts)
|
super.destroy(opts)
|
||||||
|
|
||||||
while(keptTextures.length > keepTextures) {
|
while (keptTextures.length > keepTextures) {
|
||||||
let {url, texture} = keptTextures.shift()
|
let { url, texture } = keptTextures.shift()
|
||||||
if (Tile.isObsolete(url)) {
|
if (Tile.isObsolete(url)) {
|
||||||
texture.destroy(true) // Destroy base as well
|
texture.destroy(true) // Destroy base as well
|
||||||
if (debug) console.log("Destroying texture and baseTexture", url)
|
if (debug) console.log("Destroying texture and baseTexture", url)
|
||||||
@@ -159,7 +127,7 @@ export default class Tile extends PIXI.Sprite {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// No longer registered and not pending
|
// No longer registered and not pending
|
||||||
if (count <= 0 && !Tile.isPending(this.url)) {
|
if (count <= 0) { // && !Tile.isPending(this.url)
|
||||||
let opts = { children: true, texture: true, baseTexture: true }
|
let opts = { children: true, texture: true, baseTexture: true }
|
||||||
super.destroy(opts)
|
super.destroy(opts)
|
||||||
if (debug) console.log("Tile.destroy", registeredTiles.size, opts)
|
if (debug) console.log("Tile.destroy", registeredTiles.size, opts)
|
||||||
@@ -195,14 +163,60 @@ export default class Tile extends PIXI.Sprite {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specialized renderWebGL to avoid freezing system
|
||||||
|
*
|
||||||
|
* @param {*} renderer
|
||||||
|
* @memberof Tile
|
||||||
|
*/
|
||||||
|
renderWebGL(renderer) {
|
||||||
|
try {
|
||||||
|
super.renderWebGL(renderer)
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
// We want persistent logging here
|
||||||
|
Logging.error("Error in Tile.renderWebGL: " + e.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes lately arrived texture if they have not been touched in the meanwhile.
|
||||||
|
*
|
||||||
|
* @static
|
||||||
|
* @memberof Tile
|
||||||
|
*/
|
||||||
|
static sweepLateTextures() {
|
||||||
|
let now = performance.now()
|
||||||
|
if (now > lastSweepTime + sweepInterval) {
|
||||||
|
lastSweepTime = now
|
||||||
|
let count = 0
|
||||||
|
for (let [url, texture] of lateTextures.entries()) {
|
||||||
|
if (texture) {
|
||||||
|
let base = texture.baseTexture
|
||||||
|
if (base != null && base.touched == 0) {
|
||||||
|
texture.destroy(true)
|
||||||
|
//console.info("Sweeping ", url)
|
||||||
|
count += 1
|
||||||
|
lateTextures.delete(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count > 0)
|
||||||
|
console.log("Sweeping textures", count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Texture received too late. We do not need it.
|
* Texture received too late. We do not need it.
|
||||||
* @param {*} url
|
* @param {*} url
|
||||||
* @param {*} texture
|
* @param {*} texture
|
||||||
*/
|
*/
|
||||||
static lateTexture(url, texture) {
|
static lateTexture(url, texture) {
|
||||||
let destroyBase = !registeredTiles.has(url)
|
lateTextures.set(url, texture)
|
||||||
texture.destroy(destroyBase)
|
//console.warn("Tile.lateTexture")
|
||||||
|
// We cannot destroy the texture since we got errors in t.renderWebGL.
|
||||||
|
// Perhaps we can destroy unsed textures later on
|
||||||
|
Tile.sweepLateTextures()
|
||||||
}
|
}
|
||||||
|
|
||||||
static printInfos() {
|
static printInfos() {
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
@@ -1,6 +1,6 @@
|
|||||||
import { Cycle, Colors, Dates, isEmpty } from '../utils.js'
|
import { Cycle, Colors, Dates, isEmpty } from '../utils.js'
|
||||||
import { Capabilities } from '../capabilities.js'
|
import { Capabilities } from '../capabilities.js'
|
||||||
import { BitmapLabeledGraphics, LabeledGraphics, FontInfo } from './labeledgraphics.js'
|
import { BitmapLabeledGraphics, FontInfo } from './labeledgraphics.js'
|
||||||
|
|
||||||
|
|
||||||
export class Ticks {
|
export class Ticks {
|
||||||
@@ -9,6 +9,10 @@ export class Ticks {
|
|||||||
return ['decade', 'year', 'month', 'day', 'hour', 'minute', 'second']
|
return ['decade', 'year', 'month', 'day', 'hour', 'minute', 'second']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get largeTickSize() {
|
||||||
|
return 4.2
|
||||||
|
}
|
||||||
|
|
||||||
get minWidth() {
|
get minWidth() {
|
||||||
return 10
|
return 10
|
||||||
}
|
}
|
||||||
@@ -83,7 +87,7 @@ export class Ticks {
|
|||||||
return date.toLocaleDateString('de', format)
|
return date.toLocaleDateString('de', format)
|
||||||
}
|
}
|
||||||
|
|
||||||
draw(timeline, range, width, height, available, format, nextFormat, level) {
|
draw(timeline, range, width, height, available, format, nextFormat, level, extraTicks=false) {
|
||||||
let first = null
|
let first = null
|
||||||
let last = null
|
let last = null
|
||||||
let keyedFormat = (format) ? format[this.formatKey] : null
|
let keyedFormat = (format) ? format[this.formatKey] : null
|
||||||
@@ -91,7 +95,6 @@ export class Ticks {
|
|||||||
let redundant = (nextFormat) ? this.formatKey in nextFormat : false
|
let redundant = (nextFormat) ? this.formatKey in nextFormat : false
|
||||||
let fullyRedundant = keyedFormat != null && keyedFormat == keyedNextFormat
|
let fullyRedundant = keyedFormat != null && keyedFormat == keyedNextFormat
|
||||||
let y = timeline.getY()
|
let y = timeline.getY()
|
||||||
|
|
||||||
for (let { start, end } of this.iterRanges(range)) {
|
for (let { start, end } of this.iterRanges(range)) {
|
||||||
let x = timeline.toX(start)
|
let x = timeline.toX(start)
|
||||||
let xx = x
|
let xx = x
|
||||||
@@ -100,11 +103,10 @@ export class Ticks {
|
|||||||
let key = this.dateKey(start)
|
let key = this.dateKey(start)
|
||||||
let text = this.toLocaleString(start, format)
|
let text = this.toLocaleString(start, format)
|
||||||
let align = 'center'
|
let align = 'center'
|
||||||
let downTick = false
|
|
||||||
if (nextFormat) {
|
if (nextFormat) {
|
||||||
yy = y + timeline.tickLabelOffset(-1, 1)
|
yy = y + timeline.tickLabelOffset(-1, 1)
|
||||||
align = 'left'
|
align = 'left'
|
||||||
timeline.drawTick(x, 4.2)
|
timeline.drawTick(x, Ticks.largeTickSize)
|
||||||
let nextX = timeline.toX(end) - 100
|
let nextX = timeline.toX(end) - 100
|
||||||
if (x < 0 && nextX > -100 && !redundant) {
|
if (x < 0 && nextX > -100 && !redundant) {
|
||||||
xx = Math.min(4, nextX)
|
xx = Math.min(4, nextX)
|
||||||
@@ -112,20 +114,18 @@ export class Ticks {
|
|||||||
else {
|
else {
|
||||||
xx -= 2
|
xx -= 2
|
||||||
}
|
}
|
||||||
downTick = true
|
|
||||||
}
|
}
|
||||||
else if (level > 0) {
|
else if (level > 0) {
|
||||||
xx = x + available / 2
|
xx = x + available / 2
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
downTick = true
|
|
||||||
}
|
|
||||||
if (!fullyRedundant) {
|
if (!fullyRedundant) {
|
||||||
timeline.ensureLabel(key, text,
|
timeline.ensureLabel(key, text,
|
||||||
{ x: xx, y: yy, align },
|
{ x: xx, y: yy, align },
|
||||||
FontInfo.small)
|
FontInfo.small)
|
||||||
}
|
}
|
||||||
if (downTick) timeline.drawTick(x, -1)
|
if (extraTicks)
|
||||||
|
timeline.drawTick(x, -level)
|
||||||
}
|
}
|
||||||
if (timeline.visibleRange(start, end)) {
|
if (timeline.visibleRange(start, end)) {
|
||||||
if (first == null)
|
if (first == null)
|
||||||
@@ -137,6 +137,15 @@ export class Ticks {
|
|||||||
return null
|
return null
|
||||||
return { start: first, end: last }
|
return { start: first, end: last }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drawExtra(timeline, range, size) {
|
||||||
|
for (let { start } of this.iterRanges(range)) {
|
||||||
|
if (timeline.visibleDate(start)) {
|
||||||
|
let x = timeline.toX(start)
|
||||||
|
timeline.drawTick(x, -size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DecadeTicks extends Ticks {
|
export class DecadeTicks extends Ticks {
|
||||||
@@ -434,15 +443,34 @@ export class TimeTicks {
|
|||||||
visible.push(ticks)
|
visible.push(ticks)
|
||||||
}
|
}
|
||||||
let level = 0
|
let level = 0
|
||||||
|
let ranges = []
|
||||||
for (let ticks of visible) {
|
for (let ticks of visible) {
|
||||||
if (range == null)
|
if (range == null)
|
||||||
return
|
continue
|
||||||
range = ticks.draw(timeline, range, width, height,
|
range = ticks.draw(timeline, range, width, height,
|
||||||
availables.get(ticks),
|
availables.get(ticks),
|
||||||
formats.get(ticks),
|
formats.get(ticks),
|
||||||
nextFormats.get(ticks), level)
|
nextFormats.get(ticks), level)
|
||||||
|
if (range) {
|
||||||
|
ranges.push({ticks, range})
|
||||||
|
}
|
||||||
level += 1
|
level += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let extraLevel = ranges.length - 1
|
||||||
|
let extraStart = extraLevel
|
||||||
|
for(let {ticks, range} of ranges) {
|
||||||
|
ticks.drawExtra(timeline, range, extraLevel)
|
||||||
|
extraLevel -= 1
|
||||||
|
if (extraLevel <= 0) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
timeline.drawTick(start, Ticks.largeTickSize)
|
||||||
|
timeline.drawTick(start, -extraStart)
|
||||||
|
timeline.drawTick(end, Ticks.largeTickSize)
|
||||||
|
timeline.drawTick(end, -extraStart)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -173,11 +173,16 @@ class Throwable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
animateThrow(time) {
|
_throwDeltaTime() {
|
||||||
if (this.velocity != null) {
|
|
||||||
let t = performance.now()
|
let t = performance.now()
|
||||||
let dt = t - this.lastframe
|
let dt = t - this.lastframe
|
||||||
this.lastframe = t
|
this.lastframe = t
|
||||||
|
return dt
|
||||||
|
}
|
||||||
|
|
||||||
|
animateThrow(time) {
|
||||||
|
if (this.velocity != null) {
|
||||||
|
let dt = this._throwDeltaTime()
|
||||||
// console.log("animateThrow", dt)
|
// console.log("animateThrow", dt)
|
||||||
let next = this.nextVelocity(this.velocity)
|
let next = this.nextVelocity(this.velocity)
|
||||||
let prevLength = Points.length(this.velocity)
|
let prevLength = Points.length(this.velocity)
|
||||||
@@ -1434,7 +1439,7 @@ export class DOMScatter extends AbstractScatter {
|
|||||||
let resizeW = r * Math.cos(Angle.degree2radian(phiCorrected))
|
let resizeW = r * Math.cos(Angle.degree2radian(phiCorrected))
|
||||||
let resizeH = -r * Math.sin(Angle.degree2radian(phiCorrected))
|
let resizeH = -r * Math.sin(Angle.degree2radian(phiCorrected))
|
||||||
|
|
||||||
if (this.element.offsetWidth + resizeW / this.scale > this.width * 0.3 && this.element.offsetHeight + resizeH / this.scale > this.height * 0.3) TweenLite.to(this.element, 0, { width: this.element.offsetWidth + resizeW / this.scale, height: this.element.offsetHeight + resizeH / this.scale });
|
if ((this.element.offsetWidth + resizeW) / this.scale > this.width * 0.5 / this.scale && (this.element.offsetHeight + resizeH) / this.scale > this.height * 0.3 / this.scale) TweenLite.to(this.element, 0, { width: this.element.offsetWidth + resizeW / this.scale, height: this.element.offsetHeight + resizeH / this.scale });
|
||||||
|
|
||||||
this.oldX = e.clientX
|
this.oldX = e.clientX
|
||||||
this.oldY = e.clientY
|
this.oldY = e.clientY
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 184 KiB After Width: | Height: | Size: 184 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 44 KiB |
@@ -1429,6 +1429,16 @@
|
|||||||
"map-cache": "^0.2.2"
|
"map-cache": "^0.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fs-extra": {
|
||||||
|
"version": "8.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.0.1.tgz",
|
||||||
|
"integrity": "sha512-W+XLrggcDzlle47X/XnS7FXrXu9sDo+Ze9zpndeBxdgv88FHLm1HtmkhEwavruS6koanBjp098rUpHs65EmG7A==",
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "^4.1.2",
|
||||||
|
"jsonfile": "^4.0.0",
|
||||||
|
"universalify": "^0.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"fs-mkdirp-stream": {
|
"fs-mkdirp-stream": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
|
||||||
@@ -1464,8 +1474,7 @@
|
|||||||
"ansi-regex": {
|
"ansi-regex": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"aproba": {
|
"aproba": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
@@ -1486,14 +1495,12 @@
|
|||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"brace-expansion": {
|
"brace-expansion": {
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
@@ -1508,20 +1515,17 @@
|
|||||||
"code-point-at": {
|
"code-point-at": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"concat-map": {
|
"concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"console-control-strings": {
|
"console-control-strings": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"core-util-is": {
|
"core-util-is": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@@ -1638,8 +1642,7 @@
|
|||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"ini": {
|
"ini": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
@@ -1651,7 +1654,6 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"number-is-nan": "^1.0.0"
|
"number-is-nan": "^1.0.0"
|
||||||
}
|
}
|
||||||
@@ -1666,7 +1668,6 @@
|
|||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
}
|
}
|
||||||
@@ -1674,14 +1675,12 @@
|
|||||||
"minimist": {
|
"minimist": {
|
||||||
"version": "0.0.8",
|
"version": "0.0.8",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"minipass": {
|
"minipass": {
|
||||||
"version": "2.3.5",
|
"version": "2.3.5",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"safe-buffer": "^5.1.2",
|
"safe-buffer": "^5.1.2",
|
||||||
"yallist": "^3.0.0"
|
"yallist": "^3.0.0"
|
||||||
@@ -1700,7 +1699,6 @@
|
|||||||
"version": "0.5.1",
|
"version": "0.5.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"minimist": "0.0.8"
|
"minimist": "0.0.8"
|
||||||
}
|
}
|
||||||
@@ -1781,8 +1779,7 @@
|
|||||||
"number-is-nan": {
|
"number-is-nan": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"object-assign": {
|
"object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
@@ -1794,7 +1791,6 @@
|
|||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
}
|
}
|
||||||
@@ -1880,8 +1876,7 @@
|
|||||||
"safe-buffer": {
|
"safe-buffer": {
|
||||||
"version": "5.1.2",
|
"version": "5.1.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"safer-buffer": {
|
"safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
@@ -1917,7 +1912,6 @@
|
|||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"code-point-at": "^1.0.0",
|
"code-point-at": "^1.0.0",
|
||||||
"is-fullwidth-code-point": "^1.0.0",
|
"is-fullwidth-code-point": "^1.0.0",
|
||||||
@@ -1937,7 +1931,6 @@
|
|||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"optional": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"ansi-regex": "^2.0.0"
|
"ansi-regex": "^2.0.0"
|
||||||
}
|
}
|
||||||
@@ -1981,14 +1974,12 @@
|
|||||||
"wrappy": {
|
"wrappy": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
},
|
},
|
||||||
"yallist": {
|
"yallist": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"bundled": true,
|
"bundled": true,
|
||||||
"dev": true,
|
"dev": true
|
||||||
"optional": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -4432,6 +4423,11 @@
|
|||||||
"through2-filter": "^3.0.0"
|
"through2-filter": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"universalify": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||||
|
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
|
||||||
|
},
|
||||||
"unset-value": {
|
"unset-value": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "iwmlib",
|
"name": "iwmlib",
|
||||||
"version": "1.0.10",
|
"version": "1.0.14",
|
||||||
"description": "An Open Source library for multi-touch, WebGL powered applications.",
|
"description": "An Open Source library for multi-touch, WebGL powered applications.",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"directories": {
|
"directories": {
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
"gulp-uglify": "^3.0.2"
|
"gulp-uglify": "^3.0.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"fs-extra": "^8.0.1",
|
||||||
"gsap": "^2.1.3",
|
"gsap": "^2.1.3",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"optimal-select": "^4.0.1",
|
"optimal-select": "^4.0.1",
|
||||||
|
|||||||