Ticket #1433: 1433-r6497-A0.patch
| File 1433-r6497-A0.patch, 10.3 kB (added by ahocevar, 10 months ago) |
|---|
-
examples/styles-rotation.html
old new 1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <style type="text/css"> 4 #map { 5 width: 800px; 6 height: 475px; 7 border: 1px solid black; 8 } 9 </style> 10 <script src="../lib/OpenLayers.js" type="text/javascript"></script> 11 <script type="text/javascript"> 12 13 var map; 14 var vectors; 15 16 function init(){ 17 map = new OpenLayers.Map('map'); 18 var wms = new OpenLayers.Layer.WMS( 19 "OpenLayers WMS", 20 "http://labs.metacarta.com/wms/vmap0", 21 {layers: 'basic'} 22 ); 23 24 vectors = new OpenLayers.Layer.Vector( 25 "Simple Geometry", 26 { 27 styleMap: new OpenLayers.StyleMap({ 28 "default": { 29 externalGraphic: "../img/marker-gold.png", 30 //graphicWidth: 17, 31 graphicHeight: 20, 32 graphicYOffset: -19, 33 rotation: "${angle}", 34 fillOpacity: "${opacity}" 35 }, 36 "select": { 37 externalGraphic: "../img/marker.png" 38 } 39 }) 40 } 41 ); 42 43 map.addLayers([wms, vectors]); 44 45 var features = []; 46 var x = -111.04; 47 var y = 45.68; 48 for(var i = 0; i < 10; i++){ 49 x += i * .5; 50 y += i * .1; 51 features.push( 52 new OpenLayers.Feature.Vector( 53 new OpenLayers.Geometry.Point(x, y), {angle: (i*36)%360-180, opacity:i/10+.1} 54 ) 55 ); 56 features.push( 57 new OpenLayers.Feature.Vector( 58 new OpenLayers.Geometry.Point(x, y), {angle: (i*36)%360, opacity:i/10+.1} 59 ) 60 ); 61 } 62 63 map.setCenter(new OpenLayers.LonLat(x-10, y), 5); 64 vectors.addFeatures(features); 65 }; 66 67 </script> 68 </head> 69 <body onload="init()"> 70 <div id="map"></div> 71 <p>Use the pan buttons. See flicker at end of animated pan.</p> 72 </body> 73 </html> -
lib/OpenLayers/Renderer/SVG.js
old new 222 223 } else { 223 224 node.setAttributeNS(null, "r", style.pointRadius); 224 225 } 226 227 if (style.rotation) { 228 var rotation = OpenLayers.String.format( 229 "rotate(${0} ${1} ${2})", [style.rotation, x, y]); 230 node.setAttributeNS(null, "transform", rotation); 231 } 225 232 } 226 233 227 234 if (options.isFilled) { -
lib/OpenLayers/Renderer/VML.js
old new 171 171 node.style.top = ((geometry.y/resolution)-(yOffset+height)).toFixed(); 172 172 node.style.width = width; 173 173 node.style.height = height; 174 node.style.flip = "y"; 174 175 175 176 // modify style/options for fill and stroke styling below 176 177 style.fillColor = "none"; … … 176 177 style.fillColor = "none"; 177 178 options.isStroked = false; 178 179 180 // alternative way of graphic rendering for rotated graphics 181 if (style.rotation) { 182 this.graphicRotate(node, xOffset, yOffset); 183 } 184 179 185 } else { 180 186 this.drawCircle(node, geometry, style.pointRadius); 181 187 } … … 209 215 210 216 fill.setAttribute("src", style.externalGraphic); 211 217 fill.setAttribute("type", "frame"); 212 node.style.flip = "y";213 218 214 219 if (!(style.graphicWidth && style.graphicHeight)) { 215 220 fill.aspect = "atmost"; … … 250 255 }, 251 256 252 257 /** 258 * Method: graphicRotate 259 * If a point is to be styled with externalGraphic and rotation, VML fills 260 * cannot be used to display the graphic, because rotation of graphic 261 * fills is not supported by the VML implementation of Internet Explorer. 262 * This method creates a HTML div inside the VML node, uses 263 * DXImageTransform.AlphaImageLoader to load the image (which results 264 * in smooth bilinear scaling of the graphic and better alpha handling), 265 * and DXImageTransform.Matrix and Alpha filters for rotation and opacity. 266 * Finally, OpenLayers methods are used to determine the correct insertion 267 * point of the rotated image, because DXImageTransform.Matrix does the 268 * rotation without the ability to specify a rotation center point. 269 * 270 * Parameters: 271 * node - {DOMElement} 272 * xOffset - {Number} 273 * yOffset - {Number} 274 */ 275 graphicRotate: function(node, xOffset, yOffset) { 276 var style = node._style; 277 var options = node._options; 278 279 var aspectRatio, size; 280 if (!(style.graphicWidth && style.graphicHeight)) { 281 // load the image to determine its size 282 var img = new Image(); 283 img.src = style.externalGraphic; 284 aspectRatio = img.width / img.height; 285 size = Math.max(style.pointRadius * 2, style.graphicWidth || 0, 286 style.graphicHeight || 0); 287 xOffset = xOffset * aspectRatio; 288 } else { 289 size = Math.max(style.graphicWidth, style.graphicHeight); 290 aspectRatio = style.graphicWidth / style.graphicHeight; 291 } 292 293 width = Math.round(style.graphicWidth || size * aspectRatio); 294 height = Math.round(style.graphicHeight || size); 295 node.style.width = width; 296 node.style.height = height; 297 298 var image = document.getElementById(node.id + "_image"); 299 if (!image) { 300 image = this.createNode("div", node.id + "_image"); 301 node.appendChild(image); 302 } 303 image.style.width = width; 304 image.style.height = height; 305 // load the image 306 image.style.filter = 307 "progid:DXImageTransform.Microsoft.AlphaImageLoader(" + 308 "src='" + style.externalGraphic + "', sizingMethod='scale')"; 309 310 var rotation = style.rotation * Math.PI / 180; 311 var sintheta = Math.sin(rotation); 312 var costheta = Math.cos(rotation); 313 314 // do the rotation on the image 315 var filter = 316 "progid:DXImageTransform.Microsoft.Matrix(M11=" + costheta + 317 ",M12=" + (-sintheta) + ",M21=" + sintheta + ",M22=" + costheta + 318 ",SizingMethod='auto expand')\n" 319 320 var opacity = style.graphicOpacity || style.fillOpacity; 321 if (opacity && opacity != 1) { 322 filter += 323 "progid:DXImageTransform.Microsoft.Alpha(opacity=" + 324 opacity*100+")\n"; 325 } 326 node.style.filter = filter; 327 328 // do the rotation again on a box, so we know the insertion point 329 var centerPoint = new OpenLayers.Geometry.Point(-xOffset, -yOffset); 330 var imgBox = new OpenLayers.Bounds(0, 0, width, height).toGeometry(); 331 imgBox.rotate(style.rotation, centerPoint); 332 var imgBounds = imgBox.getBounds(); 333 334 node.style.left = Math.round( 335 parseInt(node.style.left) + imgBounds.left); 336 node.style.top = Math.round( 337 parseInt(node.style.top) - imgBounds.bottom); 338 339 // turn off fill (we already have the graphic, and do not need the 340 // fill which we use for non-rotated graphics) 341 options.isFilled = false; 342 }, 343 344 /** 253 345 * Method: postDraw 254 346 * Some versions of Internet Explorer seem to be unable to set fillcolor 255 347 * and strokecolor to "none" correctly before the fill node is appended to -
tests/Renderer/test_VML.html
old new 143 143 t.eq(node.style.width, (2 * radius) + "px", "width is correct"); 144 144 t.eq(node.style.height, (2 * radius) + "px", "height is correct"); 145 145 } 146 147 function test_VML_drawGraphic(t) { 148 if (!OpenLayers.Renderer.VML.prototype.supported()) { 149 t.plan(0); 150 return; 151 } 152 153 t.plan(6); 154 155 var r = new OpenLayers.Renderer.VML(document.body); 156 r.resolution = 1; 157 158 var node = document.createElement('div'); 159 node.id = "test" 160 node._geometryClass = "OpenLayers.Geometry.Point"; 161 162 var geometry = { 163 x: 1, 164 y: 2 165 } 166 167 var style = { 168 externalGraphic: "foo.png", 169 graphicWidth: 7, 170 graphicHeight: 10 171 } 172 173 r.drawGeometryNode(node, geometry, style); 174 175 t.eq(node.childNodes[0].id, "test_fill", "fill child node correctly created"); 176 t.eq(node.style.left, "-3px", "x of insertion point with calculated xOffset correct"); 177 t.eq(node.style.top, "-3px", "y of insertion point with calculated yOffset correct"); 178 179 style.rotation = 90; 180 181 r.drawGeometryNode(node, geometry, style); 182 183 t.eq(node.childNodes[0].id, "test_image", "image child node correctly created"); 184 t.eq(node.style.left, "-4px", "x of insertion point of rotated image correct"); 185 t.eq(node.style.top, "-4px", "y of insertion point of rotated image correct"); 186 } 146 187 147 188 function test_VML_drawlinestring(t) { 148 189 if (!OpenLayers.Renderer.VML.prototype.supported()) {
