Ticket #933: resize_transition.patch
| File resize_transition.patch, 11.8 kB (added by crschmidt, 1 year ago) |
|---|
-
lib/OpenLayers/Tile/Image.js
old new 146 146 this.events.triggerEvent("loadstart"); 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(); 151 161 } … … 162 172 OpenLayers.Util.modifyAlphaImageDiv(this.imgDiv, 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; 170 180 }, … … 176 186 */ 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"; 182 192 } … … 223 233 OpenLayers.Event.observe( this.imgDiv, "load", 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); 228 239 … … 300 311 if (this.layer) { 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";314 this.hide(); 304 315 } 305 316 } 306 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 } 307 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 } 310 403 ); -
lib/OpenLayers/Tile.js
old new 80 80 */ 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. 85 109 * … … 111 135 * Nullify references to prevent circular references and memory leaks. 112 136 */ 113 137 destroy:function() { 138 this.layer.events.unregister("loadend", this, this.resetBackBuffer); 139 this.events.unregister('loadend', this, this.resetBackBuffer); 114 140 this.layer = null; 115 141 this.bounds = null; 116 142 this.size = null; … … 118 144 119 145 this.events.destroy(); 120 146 this.events = null; 147 148 /* clean up the backBufferTile if it exists */ 149 if (this.backBufferTile) { 150 this.backBufferTile.destroy(); 151 this.backBufferTile = null; 152 } 121 153 }, 122 154 123 155 /** … … 157 189 */ 158 190 draw: function() { 159 191 160 //clear tile's contents and mark as not drawn161 this.clear();162 163 192 var maxExtent = this.layer.maxExtent; 164 193 var withinMaxExtent = (maxExtent && 165 194 this.bounds.intersectsBounds(maxExtent, false)); 166 195 167 196 // The only case where we *wouldn't* want to draw the tile is if the 168 197 // tile is outside its layer's maxExtent. 169 return (withinMaxExtent || this.layer.displayOutsideMaxExtent); 198 var drawTile = (withinMaxExtent || this.layer.displayOutsideMaxExtent); 199 200 if (drawTile) { 201 //we use a clone of this tile to create a double buffer for visual 202 //continuity. The backBufferTile is used to create transition 203 //effects while the tile in the grid is repositioned and redrawn 204 if (!this.backBufferTile) { 205 this.backBufferTile = this.clone(); 206 this.backBufferTile.hide(); 207 // this is important. It allows the backBuffer to place itself 208 // appropriately in the DOM. The Image subclass needs to put 209 // the backBufferTile behind the main tile so the tiles can 210 // load over top and display as soon as they are loaded. 211 this.backBufferTile.isBackBuffer = true; 212 213 // potentially end any transition effects when the tile loads 214 this.events.register('loadend', this, this.resetBackBuffer); 215 216 // clear transition back buffer tile only after all tiles in 217 // this layer have loaded to avoid visual glitches 218 this.layer.events.register("loadend", this, this.resetBackBuffer); 219 } 220 // run any transition effects 221 this.startTransition(); 222 } else { 223 // if we aren't going to draw the tile, then the backBuffer should 224 // be hidden too! 225 if (this.backBufferTile) { 226 this.backBufferTile.clear(); 227 } 228 } 229 this.shouldDraw = drawTile; 230 231 //clear tile's contents and mark as not drawn 232 this.clear(); 233 234 return drawTile; 170 235 }, 171 236 172 237 /** … … 240 305 topLeft.lat); 241 306 return bounds; 242 307 }, 243 308 309 /** 310 * Method: startTransition 311 * 312 * prepare the tile for a transition effect. To be 313 * implemented by subclasses. 314 */ 315 startTransition: function() {}, 316 317 /** 318 * Method: resetBackBuffer 319 * 320 * triggered by two different events, layer loadend, and tile loadend. 321 * In any of these cases, we check to see if we can hide the 322 * backBufferTile yet and update its parameters to match the 323 * foreground tile. Basic logic: 324 * 325 * - If the backBufferTile hasn't been drawn yet, reset it 326 * - If layer is still loading, show foreground tile but don't hide 327 * the backBufferTile yet 328 * - If layer is done loading, reset backBuffer tile and show 329 * foreground tile 330 */ 331 resetBackBuffer: function(args) { 332 if (this.backBufferTile && 333 (this.isFirstDraw || !this.layer.numLoadingTiles)) { 334 this.backBufferTile.hide(); 335 this.backBufferTile.position = this.position.clone(); 336 this.backBufferTile.bounds = this.bounds.clone(); 337 this.backBufferTile.size = this.size.clone(); 338 this.backBufferTile.resolution = this.layer.getResolution(); 339 this.backBufferTile.renderTile(); 340 this.isFirstDraw = false; 341 } 342 if (this.shouldDraw) { 343 this.show(); 344 } 345 }, 346 347 /** 348 * Method: show 349 * 350 * show the tile. To be implemented by subclasses. 351 */ 352 show: function() { }, 353 354 /** 355 * Method: hide 356 * 357 * hide the tile. To be implemented by subclasses. 358 */ 359 hide: function() { }, 360 244 361 CLASS_NAME: "OpenLayers.Tile" 245 362 }); -
lib/OpenLayers/Layer.js
old new 231 231 */ 232 232 wrapDateLine: false, 233 233 234 /** 235 * APIProperty: transitionEffect 236 * {String} The transition effect to use when the map is panned or 237 * zoomed. There is currently two supported values: 238 * null - no transition effect (the default). 239 * resize - existing tiles are resized on zoom to provide a visual 240 * effect of the zoom having taken place immediately. As the 241 * new tiles become available, they are drawn over top of the 242 * resized tiles. 243 */ 244 transitionEffect: null, 234 245 235 246 /** 236 247 * Constructor: OpenLayers.Layer
