Changeset 6371
- Timestamp:
- 02/25/08 22:11:55 (11 months ago)
- Files:
-
- sandbox/crschmidt/demo/examples/transition.html (added)
- sandbox/crschmidt/demo/lib/OpenLayers/Layer.js (modified) (1 diff)
- sandbox/crschmidt/demo/lib/OpenLayers/Tile.js (modified) (6 diffs)
- sandbox/crschmidt/demo/lib/OpenLayers/Tile/Image.js (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
sandbox/crschmidt/demo/lib/OpenLayers/Layer.js
r6149 r6371 249 249 wrapDateLine: false, 250 250 251 /** 252 * APIProperty: transitionEffect 253 * {String} The transition effect to use when the map is panned or 254 * zoomed. There is currently two supported values: 255 * null - no transition effect (the default). 256 * keep - Keep tiles around. This uses double-buffering: this 257 * type of transition effect is only useful for singleTile layers, 258 * where the tile will be kept in place on drag. 259 * resize - existing tiles are resized on zoom to provide a visual 260 * effect of the zoom having taken place immediately. As the 261 * new tiles become available, they are drawn over top of the 262 * resized tiles. 263 */ 264 transitionEffect: null, 251 265 252 266 /** sandbox/crschmidt/demo/lib/OpenLayers/Tile.js
r6313 r6371 81 81 isLoading: false, 82 82 83 /** 84 * Property: isBackBuffer 85 * {Boolean} Is this tile a back buffer tile? 86 */ 87 isBackBuffer: false, 88 89 /** 90 * Property: isFirstDraw 91 * {Boolean} Is this the first time the tile is being drawn? 92 * This is used to force resetBackBuffer to synchronize 93 * the backBufferTile with the foreground tile the first time 94 * the foreground tile loads so that if the user zooms 95 * before the layer has fully loaded, the backBufferTile for 96 * tiles that have been loaded can be used. 97 */ 98 isFirstDraw: true, 99 100 /** 101 * Property: backBufferTile 102 * {<OpenLayers.Tile>} A clone of the tile used to create transition 103 * effects when the tile is moved or changes resolution. 104 */ 105 backBufferTile: null, 106 83 107 /** TBD 3.0 -- remove 'url' from the list of parameters to the constructor. 84 108 * there is no need for the base tile class to have a url. … … 112 136 */ 113 137 destroy:function() { 138 if (this.layer.transitionEffect) { 139 this.layer.events.unregister("loadend", this, this.resetBackBuffer); 140 this.events.unregister('loadend', this, this.resetBackBuffer); 141 } else { 142 this.events.unregister('loadend', this, this.showTile); 143 } 114 144 this.layer = null; 115 145 this.bounds = null; … … 119 149 this.events.destroy(); 120 150 this.events = null; 151 152 /* clean up the backBufferTile if it exists */ 153 if (this.backBufferTile) { 154 this.backBufferTile.destroy(); 155 this.backBufferTile = null; 156 } 121 157 }, 122 158 … … 158 194 draw: function() { 159 195 160 //clear tile's contents and mark as not drawn161 this.clear();162 163 196 var maxExtent = this.layer.maxExtent; 164 197 var withinMaxExtent = (maxExtent && … … 167 200 // The only case where we *wouldn't* want to draw the tile is if the 168 201 // tile is outside its layer's maxExtent. 169 return (withinMaxExtent || this.layer.displayOutsideMaxExtent); 202 var drawTile = (withinMaxExtent || this.layer.displayOutsideMaxExtent); 203 204 if (this.layer.transitionEffect != null) { 205 if (drawTile) { 206 //we use a clone of this tile to create a double buffer for visual 207 //continuity. The backBufferTile is used to create transition 208 //effects while the tile in the grid is repositioned and redrawn 209 if (!this.backBufferTile) { 210 this.backBufferTile = this.clone(); 211 this.backBufferTile.hide(); 212 // this is important. It allows the backBuffer to place itself 213 // appropriately in the DOM. The Image subclass needs to put 214 // the backBufferTile behind the main tile so the tiles can 215 // load over top and display as soon as they are loaded. 216 this.backBufferTile.isBackBuffer = true; 217 218 // potentially end any transition effects when the tile loads 219 this.events.register('loadend', this, this.resetBackBuffer); 220 221 // clear transition back buffer tile only after all tiles in 222 // this layer have loaded to avoid visual glitches 223 this.layer.events.register("loadend", this, this.resetBackBuffer); 224 } 225 // run any transition effects 226 this.startTransition(); 227 } else { 228 // if we aren't going to draw the tile, then the backBuffer should 229 // be hidden too! 230 if (this.backBufferTile) { 231 this.backBufferTile.clear(); 232 } 233 } 234 } else { 235 if (this.isFirstDraw) { 236 this.events.register('loadend', this, this.showTile); 237 this.isFirstDraw = false; 238 } 239 } 240 this.shouldDraw = drawTile; 241 242 //clear tile's contents and mark as not drawn 243 this.clear(); 244 245 return drawTile; 170 246 }, 171 247 … … 238 314 return bounds; 239 315 }, 240 316 317 /** 318 * Method: startTransition 319 * 320 * prepare the tile for a transition effect. To be 321 * implemented by subclasses. 322 */ 323 startTransition: function() {}, 324 325 /** 326 * Method: resetBackBuffer 327 * 328 * triggered by two different events, layer loadend, and tile loadend. 329 * In any of these cases, we check to see if we can hide the 330 * backBufferTile yet and update its parameters to match the 331 * foreground tile. Basic logic: 332 * 333 * - If the backBufferTile hasn't been drawn yet, reset it 334 * - If layer is still loading, show foreground tile but don't hide 335 * the backBufferTile yet 336 * - If layer is done loading, reset backBuffer tile and show 337 * foreground tile 338 */ 339 resetBackBuffer: function(args) { 340 if (this.backBufferTile && 341 (this.isFirstDraw || !this.layer.numLoadingTiles)) { 342 this.backBufferTile.hide(); 343 this.isFirstDraw = false; 344 // check to see if the backBufferTile is within the max extents 345 // before rendering it 346 var maxExtent = this.layer.maxExtent; 347 var withinMaxExtent = (maxExtent && 348 this.bounds.intersectsBounds(maxExtent, false)); 349 if (withinMaxExtent) { 350 this.backBufferTile.position = this.position.clone(); 351 this.backBufferTile.bounds = this.bounds.clone(); 352 this.backBufferTile.size = this.size.clone(); 353 this.backBufferTile.resolution = this.layer.getResolution(); 354 this.backBufferTile.renderTile(); 355 } 356 } 357 this.showTile(); 358 }, 359 360 /** 361 * Method: showTile 362 * 363 * show the tile only if it should be drawn. 364 */ 365 showTile: function() { 366 if (this.shouldDraw) { 367 this.show(); 368 } 369 }, 370 371 /** 372 * Method: show 373 * 374 * show the tile. To be implemented by subclasses. 375 */ 376 show: function() { }, 377 378 /** 379 * Method: hide 380 * 381 * hide the tile. To be implemented by subclasses. 382 */ 383 hide: function() { }, 384 241 385 CLASS_NAME: "OpenLayers.Tile" 242 386 }); sandbox/crschmidt/demo/lib/OpenLayers/Tile/Image.js
r6068 r6371 147 147 } 148 148 149 return this.renderTile(); 150 }, 151 152 /** 153 * Method: renderTile 154 * 155 * internal function to actually initialize the image tile, 156 * position it correctly, and set its url 157 */ 158 renderTile: function() { 149 159 if (this.imgDiv == null) { 150 160 this.initImgDiv(); … … 163 173 null, null, imageSize, this.url); 164 174 } else { 165 this.imgDiv.src = this.url;166 175 OpenLayers.Util.modifyDOMElement(this.imgDiv, 167 176 null, null, imageSize) ; 177 this.imgDiv.src = this.url; 168 178 } 169 179 return true; … … 177 187 clear: function() { 178 188 if(this.imgDiv) { 179 this. imgDiv.style.display = "none";189 this.hide(); 180 190 if (OpenLayers.Tile.Image.useBlankTile) { 181 191 this.imgDiv.src = OpenLayers.Util.getImagesLocation() + "blank.gif"; … … 224 234 OpenLayers.Function.bind(this.checkImgURL, this) ); 225 235 */ 236 this.frame.style.zIndex = this.isBackBuffer ? 0 : 1; 226 237 this.frame.appendChild(this.imgDiv); 227 238 this.layer.div.appendChild(this.frame); … … 301 312 var loaded = this.layerAlphaHack ? this.imgDiv.firstChild.src : this.imgDiv.src; 302 313 if (!OpenLayers.Util.isEquivalentUrl(loaded, this.url)) { 303 this.imgDiv.style.display = "none"; 304 } 305 } 306 }, 307 314 this.hide(); 315 } 316 } 317 }, 318 319 /** 320 * Method: startTransition 321 * 322 * This method is invoked on tiles that are backBuffers for tiles in the 323 * grid. The grid tile is about to be cleared and a new tile source 324 * loaded. This is where the transition effect needs to be started 325 * to provide visual continuity. 326 */ 327 startTransition: function() { 328 // backBufferTile has to be valid and ready to use 329 if (!this.backBufferTile || !this.backBufferTile.imgDiv) { 330 return; 331 } 332 333 // show the backBufferTile and hide this tile 334 this.hide(); 335 336 // calculate the ratio of change between the current resolution of the 337 // backBufferTile and the layer. If several animations happen in a 338 // row, then the backBufferTile will scale itself appropriately for 339 // each request. 340 var ratio = 1; 341 if (this.backBufferTile.resolution) { 342 ratio = this.backBufferTile.resolution / this.layer.getResolution() ; 343 } 344 345 // if the ratio is not 1 (i.e. we are zooming), then we might be 346 // resizing the backBuffer tile ... 347 if (ratio != 1) { 348 if (this.layer.transitionEffect == 'resize') { 349 // In this case, we can just immediately resize the 350 // backBufferTile. 351 var upperLeft = 352 new OpenLayers.LonLat(this.backBufferTile.bounds.left, 353 this.backBufferTile.bounds.top); 354 var size = 355 new OpenLayers.Size(this.backBufferTile.size.w * ratio, 356 this.backBufferTile.size.h * ratio); 357 358 var px = this.layer.map.getLayerPxFromLonLat(upperLeft); 359 OpenLayers.Util.modifyDOMElement(this.backBufferTile.frame, 360 null, px, size); 361 var imageSize = this.backBufferTile.size.clone(); 362 imageSize = new OpenLayers.Size(imageSize.w * ratio, 363 imageSize.h * ratio); 364 365 OpenLayers.Util.modifyDOMElement(this.backBufferTile.imgDiv, 366 null, null, imageSize) ; 367 368 this.backBufferTile.show(); 369 } 370 } else { 371 // default effect is just to leave the existing tile 372 // until the new one loads if this is a singleTile and 373 // there was no change in resolution. Otherwise we 374 // don't bother to show the backBufferTile at all 375 if (this.layer.singleTile && ratio == 1) { 376 this.backBufferTile.show(); 377 } else { 378 this.backBufferTile.hide(); 379 } 380 } 381 }, 382 383 /** 384 * Method: show 385 * 386 * show the tile by showing its frame. 387 */ 388 show: function() { 389 this.frame.style.display = ''; 390 }, 391 392 /** 393 * Method: hide 394 * 395 * hide the tile by hiding its frame. 396 */ 397 hide: function() { 398 this.frame.style.display = 'none'; 399 }, 400 308 401 CLASS_NAME: "OpenLayers.Tile.Image" 309 402 }
