X-Git-Url: https://scm.cri.minesparis.psl.eu/git/Portfolio.git/blobdiff_plain/2da869b2b46179d64c05eaac4081226fdbbbc9ff..e73353500c67453ef9663d67eaeee7dd46c358ee:/skins/mosaique.js diff --git a/skins/mosaique.js b/skins/mosaique.js deleted file mode 100755 index 47b8d1e..0000000 --- a/skins/mosaique.js +++ /dev/null @@ -1,735 +0,0 @@ -/* -* © 2007-2008 Benoît Pin – Centre de recherche en informatique – École des mines de Paris -* http://plinn.org -* Licence Creative Commons http://creativecommons.org/licenses/by-nc/2.0/ -* -* -*/ - -var Mosaique; - -(function(){ - -var hiddenTilesNumber = 1; -var batchSize = 5; -var reNb = /\-?\d+/ ; - -Mosaique = function(screenArea, imgUrlBase, margins) { - this.screenArea = screenArea; - if (!margins) - margins = {'top':0, 'right':0, 'bottom':0, 'left':0}; - this.margins = margins; - this.prepareScreen(); - this.setContainerPosition(new Point(0,0)); - - this.imgUrlBase = imgUrlBase; - this.xmlPath = imgUrlBase + "/tiling_infos.xml"; - - this.tiles = null; - this.xTileRange = [0,0]; - this.yTileRange = [0,0]; - - this._loadingQueue = new Array(); - this._currentSequence = null; - this._loadingIterator = 0; - this.loadingState = 0; - - this.dragInProgress = false; - this.initialClickPoint = null; - this.initialPosition = null; - var thisMos = this; - this._ddHandlers = {'down' : function(evt){thisMos._mouseDownHandler(evt);}, - 'move' : function(evt){thisMos._mouseMoveHandler(evt);}, - 'up' : function(evt){thisMos._mouseUpHandler(evt);}}; - this.ddHandlers = null; - - this.rcsItoC = new Point(0, 0); // vector to translate coordinate systems - - this.remainD = new Point(0, 0); - this.getXmlInfo(); -} - -Mosaique.prototype.getXmlInfo = function() { - var req = new XMLHttpRequest(); - var thisMosaique = this; - req.onreadystatechange = function() { - if(req.readyState == 4) - thisMosaique._loadXmlInfo(req); - }; - req.open("GET",thisMosaique.xmlPath,true); - req.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); - req.send(null); -}; - -Mosaique.prototype._loadXmlInfo = function(req) { - var doc = req.responseXML.documentElement; - this.thumbnailWidth = parseInt(doc.getElementsByTagName('thumbnailwidth')[0].firstChild.data); - this.thumbnailHeight = parseInt(doc.getElementsByTagName('thumbnailheight')[0].firstChild.data); - this.tileSize = parseInt(doc.getElementsByTagName('tilesize')[0].firstChild.data); - - var zoomList = doc.getElementsByTagName("zoom"); - this.zoomTable = new Array(zoomList.length); - var zoom; - for (var i=0 ; i= this.imageHeight) - ulc.y = this.imageHeight/2 - this.screenHeight/2; - this.loadScreen(ulc); - this.addEventListeners(); -}; - -Mosaique.prototype.addEventListeners = function() { - var thisMos = this; - addListener(document, 'mousedown', function(evt){thisMos.mouseDownHandler(evt);}, 'mosaique.dd'); - addListener(document, 'mouseup', function(evt){thisMos.mouseUpHandler(evt);}, 'mosaique.dd'); -}; - -Mosaique.prototype.getBestFitZoom = function() { - var i; - for (i = 1 ; i < this.zoomTable.length ; i++) - if (this.screenWidth - this.zoomTable[i]['width'] < 0 || - this.screenHeight - this.zoomTable[i]['height'] < 0) - break; - return i-1; -}; - -Mosaique.prototype.setCurrentDimensionValues = function(zoomIndex) { - var zoomInfo = this.zoomTable[zoomIndex]; - this.zoomIndex = zoomIndex; - this.zoomLevel = zoomInfo['level']; - this.imageWidth = zoomInfo['width']; - this.imageHeight = zoomInfo['height']; - this.xtiles = zoomInfo['tilesX']; - this.ytiles = zoomInfo['tilesY']; - this.halfTileSize = this.tileSize / 2; - this.gridWidth = this.xtiles*this.tileSize; - this.gridHeight = this.ytiles*this.tileSize; - - var WnbTiles = Math.ceil(this.screenWidth/this.tileSize) + 2 * hiddenTilesNumber; - var HnbTiles = Math.ceil(this.screenHeight/this.tileSize) + 2 * hiddenTilesNumber; - this.WnbTiles = (WnbTiles > this.xtiles) ? this.xtiles : WnbTiles; - this.HnbTiles = (HnbTiles > this.ytiles) ? this.ytiles : HnbTiles; - -}; - -Mosaique.prototype.prepareScreen = function() { - this.screenWidth = getObjectWidth(this.screenArea); - this.screenHeight = getObjectHeight(this.screenArea); - var mask = this.rootElement = document.createElement('div'); - with (mask.style) { - position = 'absolute'; - width = this.screenWidth - this.margins['right'] + 'px'; - height = this.screenHeight - this.margins['bottom'] + 'px'; - background = base_properties["contentBackgroundColor"]; - overflow = 'hidden'; - } - this.screenArea.insertBefore(mask, this.screenArea.firstChild); - - var container = document.createElement('div'); - with (container.style) { - position = 'absolute'; - top = '0px'; - left = '0px'; - cursor = 'move'; - } - - mask.appendChild(container); - this.container = container; -}; - -Mosaique.prototype.prepareContainer = function() { - var __getImg; - if (browser.isGecko) { - __getImg = function(evt, o) { - return o; - } - } - else { - __getImg = function(evt) { - return getTargetedObject(evt); - } - } - var thisMos = this; - var loadNext; - if (browser.isIE) { - loadNext = function(evt) { - var tile = __getImg(evt, this); - tile.style.visibility = 'visible'; - setTimeout(function(){thisMos._loadNextTile();}, 1); - } - } - else { - loadNext = function(evt) { - var tile = __getImg(evt, this); - tile.style.visibility = 'visible'; - thisMos._loadNextTile(); - } - } - - this.setContainerPosition(new Point(0,0)); - this.xTileRange = [0,0]; - this.yTileRange = [0,0]; - - var size = parseInt(this.tileSize); - this.tiles = new Array(this.WnbTiles); - for (var x = 0 ; x < this.WnbTiles ; x++) { - this.tiles[x] = new Array(this.HnbTiles); - for (var y = 0 ; y < this.HnbTiles ; y++) { - var img = document.createElement("img"); - with(img) { - width = size; - height = size; - } - addListener(img, 'load', loadNext, 'mosaique.tiles'); - img.style.position='absolute'; - img.style.left = x * size + 'px'; - img.style.top = y * size + 'px'; - this.container.appendChild(img); - this.tiles[x][y] = img; - } - } - with(this.container.style) { - width = size * this.WnbTiles + 'px'; - height = size * this.HnbTiles + 'px'; - } -}; - - -Mosaique.prototype.setContainerPosition = function(point) { - with(this.container.style) { - left = point.x + 'px'; - top = point.y + 'px'; - } -}; - -Mosaique.prototype.getContainerPosition = function() { - var x = parseInt(this.container.style.left); - var y = parseInt(this.container.style.top); - var p = new Point(x, y); - return p; -}; - -Mosaique.prototype.setImagePosition = function(point) { - this.setContainerPosition(this.rcsItoC.diff(point)); -}; - -Mosaique.prototype.getImagePosition = function() { - var cp = this.getContainerPosition(); - return this.rcsItoC.diff(cp); -}; - -Mosaique.prototype.getImageCenterPosition = function() { - var ip = this.getImagePosition(); - return ip.add(new Point(this.screenWidth/2, this.screenHeight/2)); -} - - - -Mosaique.prototype.loadScreen = function(position) { - - var tSize = this.tileSize; - var ulTileCoord = new Point(Math.floor(position.x/tSize), Math.floor(position.y/tSize)); - var modulo = new Point(position.x % tSize, position.y % tSize); - - var adjX, adjY; - if (modulo.x > this.halfTileSize) { - adjX = function(n){return n - hiddenTilesNumber + 1;}; - this.remainD.x = - (modulo.x - tSize); - } - else { - adjX = function(n){return n - hiddenTilesNumber;}; - this.remainD.x = - modulo.x; - } - if (modulo.y > this.halfTileSize) { - this.remainD.y = - (modulo.y - tSize); - adjY = function(n){return n - hiddenTilesNumber + 1;}; - } - else { - adjY = function(n){return n - hiddenTilesNumber;}; - this.remainD.y = - modulo.y; - } - - var xTileRange, yTileRange; - xTileRange = [ulTileCoord.x, ulTileCoord.x + this.WnbTiles].map(adjX); - yTileRange = [ulTileCoord.y, ulTileCoord.y + this.HnbTiles].map(adjY); - - //console.assert(xTileRange[1] - xTileRange[0] == this.WnbTiles, xTileRange, this.WnbTiles); - //console.assert(yTileRange[1] - yTileRange[0] == this.HnbTiles, yTileRange, this.HnbTiles); - - if (xTileRange[0] < 0) { - this.remainD.x = Math.abs(xTileRange[0] + ((position.x < 0) ? 1 : 0)) * tSize - modulo.x; - xTileRange = [0, this.WnbTiles]; - } - else if (xTileRange[1] > this.xtiles) { - this.remainD.x = - (xTileRange[1] - this.xtiles - ((modulo.x > this.halfTileSize) ? 1 : 0)) * tSize - modulo.x; - xTileRange = [this.xtiles - this.WnbTiles, this.xtiles]; - } - - if (yTileRange[0] < 0) { - this.remainD.y = Math.abs(yTileRange[0] + ((position.y < 0) ? 1 : 0)) * tSize - modulo.y; - yTileRange = [0, this.HnbTiles]; - } - else if (yTileRange[1] > this.ytiles) { - this.remainD.y = - (yTileRange[1] - this.ytiles - ((modulo.y > this.halfTileSize) ? 1 : 0)) * tSize - modulo.y; - yTileRange = [this.ytiles - this.HnbTiles, this.ytiles]; - } - - //console.assert(xTileRange[0] >= 0 && xTileRange[1] <= this.xtiles); - //console.assert(yTileRange[0] >= 0 && yTileRange[1] <= this.ytiles); - - var dTx = this.xTileRange[0] - xTileRange[0]; - var dTy = this.yTileRange[0] - yTileRange[0]; - this.rcsItoC = this.rcsItoC.diff(new Point(dTx * tSize, dTy * tSize)); - - this.setImagePosition(position); - - this.xTileRange = xTileRange; - this.yTileRange = yTileRange; - - var xOffset = this.xTileRange[0]; - var yOffset = this.yTileRange[0]; - - var baseUrl = this.imgUrlBase + '/getTile?zoom=' + this.zoomLevel / 100.0; - - var tilesSrc = new Array(this.WnbTiles); - for (var x = 0 ; x < this.WnbTiles ; x++) { - tilesSrc[x] = new Array(this.HnbTiles); - for (var y = 0 ; y < this.HnbTiles ; y++) { - tilesSrc[x][y] = baseUrl + '&x=' + (x + xOffset) + '&y=' + (y + yOffset); - } - } - this.queueLoadingSequence({'type':'full', - 'src' : tilesSrc, - 'order' : this.loadingOrder, - 'length' : this.loadingOrder.length}); -}; - -Mosaique.prototype.loadColumns = function(n){ - /* - n > 0 <=> x displacement > 0 => shift columns from right to left - Returns the number of columns that have been loaded. - */ - - - var newRange; - - while (n != 0) { - newRange = [this.xTileRange[0] - n, this.xTileRange[1] - n] - if (newRange[0]<0 || newRange[1] > this.xtiles) { - (n>0) ? n-- : n++; - continue; - } - else { - this.xTileRange = newRange; - break; - } - return 0; - } - - - var shift, from, to, increment; - if (n>0) { - shift = - (this.WnbTiles) * this.tileSize; - from = 0; - to = n; - increment = 1; - } - else { - shift = (this.WnbTiles) * this.tileSize; - from = this.WnbTiles - 1; - to = this.WnbTiles + n -1; - increment = -1; - } - - var thisMos = this; - var beforeSequence = function(){thisMos._shiftColumns(n, shift, from, to, increment)}; - - var order = new Array(); - var tilesSrc = new Array(); - var baseUrl = this.imgUrlBase + '/getTile?zoom=' + this.zoomLevel / 100.0; - var xOffset = this.xTileRange[0]; - var yOffset = this.yTileRange[0]; - - for (var x = from ; x != to ; x += increment) { - tilesSrc[x] = new Array(); - for (var y = 0 ; y < this.HnbTiles ; y++) { - order.push([x, y]); - tilesSrc[x][y] = baseUrl + '&x=' + (x + xOffset) + '&y=' + (y + yOffset); - } - } - order = order.reverse(); - this.queueLoadingSequence({'type':'column', - 'src' : tilesSrc, - 'order' : order, - 'length' : order.length, - 'beforeSequence' : beforeSequence}); - return n; -}; - -Mosaique.prototype._shiftColumns = function(n, shift, from, to, increment){ - /* rows rotations */ - this.tiles = rotateArray(this.tiles, -n); - var tile, left; - /* positional shifting */ - for (var x = from ; x != to ; x += increment) { - left = parseInt(this.tiles[x][0].style.left); - for (var y = 0 ; y < this.HnbTiles ; y++) { - var tile = this.tiles[x][y]; - tile.style.left = left + shift + 'px'; - tile.style.visibility = 'hidden'; - } - } - -}; - - - -Mosaique.prototype.loadRows = function(n) { - /* - n > 0 <=> y displacement > 0 => shift rows from bottom to top - Returns the number of rows that's have been loaded. - */ - - var newRange; - - while (n != 0) { - newRange = [this.yTileRange[0] - n, this.yTileRange[1] - n] - if (newRange[0]<0 || newRange[1] > this.ytiles) { - (n>0) ? n-- : n++; - continue; - } - else { - this.yTileRange = newRange; - break; - } - return 0; - } - - var shift, from, to, increment; - if (n>0) { - shift = - (this.HnbTiles) * this.tileSize; - from = 0; - to = n; - increment = 1; - } - else { - shift = (this.HnbTiles) * this.tileSize; - from = this.HnbTiles - 1; - to = this.HnbTiles + n -1; - increment = -1; - } - - var thisMos = this; - var beforeSequence = function(){thisMos._shiftRows(n, shift, from, to, increment)}; - - var order = new Array(); - var tilesSrc = new Array(); - var baseUrl = this.imgUrlBase + '/getTile?zoom=' + this.zoomLevel / 100.0; - var xOffset = this.xTileRange[0]; - var yOffset = this.yTileRange[0]; - - for (var y = from ; y != to ; y += increment) { - for (var x = 0 ; x < this.WnbTiles ; x++) { - order.push([x, y]); - if (!tilesSrc[x]) - tilesSrc[x] = new Array(); - tilesSrc[x][y] = baseUrl + '&x=' + (x + xOffset) + '&y=' + (y + yOffset); - } - } - order = order.reverse(); - this.queueLoadingSequence({'type':'row', - 'src' : tilesSrc, - 'order' : order, - 'length' : order.length, - 'beforeSequence' : beforeSequence}); - return n; -}; - -Mosaique.prototype._shiftRows = function(n, shift, from, to, increment) { - /* columns rotations */ - for (var x = 0 ; x < this.WnbTiles ; x++) - this.tiles[x] = rotateArray(this.tiles[x], -n); - - var tile, top; - - /* positional shifting */ - for (var y = from ; y != to ; y += increment) { - top = parseInt(this.tiles[0][y].style.top); - for (var x = 0 ; x < this.WnbTiles ; x++) { - var tile = this.tiles[x][y]; - tile.style.top = top + shift + 'px'; - tile.style.visibility = 'hidden'; - } - } -}; - - -Mosaique.prototype.queueLoadingSequence = function(sequenceInfo) { - if(!sequenceInfo.length) return; - this._loadingQueue.push(sequenceInfo); - if (!this.loadingState && this._loadingQueue.length) - this._loadNextSequence(); -}; - -Mosaique.prototype._loadNextSequence = function() { - var seq = this._loadingQueue.shift(); - if (seq == null) { - this._loadingQueue = new Array(); - this.loadingState = 0; - return; - } - switch(seq['type']) { - case 'full' : - this.loadingState = 1; - break; - case 'row' : - case 'column' : - this.loadingState = 2; - seq['beforeSequence'](); - break; - } - this._loadingIterator = 0; - //this._loadNextTile(); - this._startSequence(seq); -}; - -Mosaique.prototype._startSequence = function(seq) { - this._currentSequence = seq; - - var size = Math.min(batchSize, this._currentSequence.length); - this._loadingIterator += size; - - var coord, src, tile; - for (var i=0 ; i= this._currentSequence['length']) { - this._loadNextSequence(); - return; - } - - var coord = this._currentSequence.order[this._loadingIterator]; - this._loadingIterator++; - - var src = this._currentSequence.src[coord[0]][coord[1]]; - var tile = this.tiles[coord[0]][coord[1]]; - tile.src = src; -}; - - -/* drag and drop generic handlers */ -Mosaique.prototype.mouseDownHandler = function(evt) { - var target = getTargetedObject(evt); - if (target.tagName == 'INPUT' || target.tagName == 'TEXTAREA') - return; - disableDefault(evt); - evt = getEventObject(evt); - var navDisp = this.navigateur.display; - - if (target.parentNode.parentNode == navDisp) { - if (target == this.navigateur.frame.firstChild) - this.ddHandlers = this.navigateur._ddHandlers; - else { - this.ddHandlers = null; - return; - } - } - else - this.ddHandlers = this._ddHandlers; - - addListener(document, 'mousemove', this.ddHandlers['move'], 'mosaique.dd'); - - this.ddHandlers['down'](evt); -}; - -Mosaique.prototype.mouseUpHandler = function(evt) { - if (this.ddHandlers != null) { - removeListener(document, 'mousemove', this.ddHandlers['move']); - this.ddHandlers['up'](evt); - this.ddHandlers = null; - } -} - - -/* Mosaique drag and drop handlers */ -Mosaique.prototype._mouseDownHandler = function(evt) { - this.initialClickPoint = new Point(evt.clientX, evt.clientY); - this.initialPosition = this.getContainerPosition(); - this.rShift = 0; - this.cShift = 0; - this.dragInProgress = true; -} - -Mosaique.prototype._mouseMoveHandler = function(evt) { - disableDefault(evt); - if(!this.dragInProgress) - return; - - evt = getEventObject(evt); - var currentPoint = new Point(evt.clientX, evt.clientY); - var displacement = currentPoint.diff(this.initialClickPoint); - this.setContainerPosition(this.initialPosition.add(displacement)); - - var r = (displacement.y + this.halfTileSize + this.remainD.y) / this.tileSize; - r = Math.floor(r); - - if (this.rShift - r != 0) - this.rShift += this.loadRows(r - this.rShift); - - var c = (displacement.x + this.halfTileSize + this.remainD.x) / this.tileSize; - c = Math.floor(c); - - if (this.cShift - c != 0) - this.cShift += this.loadColumns(c - this.cShift); -}; - -Mosaique.prototype._mouseUpHandler = function(evt) { - this.dragInProgress = false; - evt = getEventObject(evt); - this._mouseMoveHandler(evt); - var finalPoint = new Point(evt.clientX, evt.clientY); - var displacement = finalPoint.diff(this.initialClickPoint); - this.remainD = this.remainD.add(new Point(displacement.x - this.cShift * this.tileSize, displacement.y - this.rShift * this.tileSize)); - this.navigateur.alignFrame(); -}; - - - -Mosaique.prototype.setLoadingOrder = function() { - var startX = 0; - var stopX = this.WnbTiles; - var startY = 0; - var stopY = this.HnbTiles; - var x = 0, y = 0; - var order = new Array(); - - var direction=0; - - - while((startX != stopX) && (startY != stopY)) { - switch(direction) { - case 0 : // left -> right - startY++; - - for (x = startX ; x < stopX ; x++) - order.push([x, y]); - x--; - break; - - case 1 : // up -> bottom - stopX--; - for (y = startY ; y < stopY ; y++) - order.push([x, y]); - y--; - break; - - case 2 : // right -> left - stopY--; - - for (x = stopX-1 ; x >= startX ; x--) - order.push([x, y]) - x++; - break; - - case 3 : // bottom -> up - startX++; - - for (y = stopY-1 ; y >= startY ; y--) - order.push([x,y]); - y++; - break; - } - - direction++; - if (direction % 4 == 0) - direction = 0; - } - - - this.loadingOrder = order.reverse(); -} - -Mosaique.prototype.cleanContainer = function() { - removeGroupListeners('mosaique.tiles'); - while (this.container.childNodes[0]) - this.container.removeChild(this.container.childNodes[0]); -} - -Mosaique.prototype.loadZoomLevel = function(zoomIndex) { - this.loadingState = 0; - var oldWnbTiles = this.WnbTiles; - var oldHnbTiles = this.HnbTiles; - var oldCenter = this.getImageCenterPosition(); - var zoomInfo = this.zoomTable[zoomIndex]; - var newLevel = zoomInfo['level']; - - // center coordinates translated into target zoom level - var center = oldCenter.mul(newLevel / this.zoomLevel); - var ulc = center.diff(new Point(this.screenWidth/2, this.screenHeight/2)); // upper left corner - - this.setCurrentDimensionValues(zoomIndex); - - if (oldWnbTiles != this.WnbTiles || oldHnbTiles != this.HnbTiles) { - this.cleanContainer(); - this.prepareContainer(); - this.rcsItoC = new Point(0,0); - this.setLoadingOrder(); - } - this.loadScreen(ulc); -}; - -Mosaique.prototype.unload = function() { - this.navigateur.unload(); - removeGroupListeners('mosaique.dd'); - removeGroupListeners('mosaique.tiles'); - this.screenArea.removeChild(this.rootElement); -}; - -})(); - -/* UTILS */ -function Point(x, y) { - this.x = Math.round(x); - this.y = Math.round(y); -} -Point.prototype.diff = function(point) { return new Point(this.x - point.x, this.y - point.y); }; -Point.prototype.add = function(point) { return new Point(this.x + point.x, this.y + point.y); }; -Point.prototype.mul = function(k) { return new Point(this.x * k, this.y *k)}; -Point.prototype.toString = function() { return "(" + String(this.x) + ", " + String(this.y) + ")"; }; - -function rotateArray(t, n) { - return t.slice(n,t.length).concat(t.slice(0,n)); -} - -if (!Array.prototype.map) { - Array.prototype.map = function(f) { - var r = new Array(this.length); - for (var i = 0 ; i < this.length ; i++ ){ - r[i] = f(this[i]); - } - return r; - }; -}