diff --git a/src/ol/render/canvas/Immediate.js b/src/ol/render/canvas/Immediate.js index 5290d0a897..0577c846b7 100644 --- a/src/ol/render/canvas/Immediate.js +++ b/src/ol/render/canvas/Immediate.js @@ -386,18 +386,9 @@ class CanvasImmediateRenderer extends VectorContext { this.textScale_[0] != 1 || this.textScale_[1] != 1 ) { - const localTransform = composeTransform( - this.tmpLocalTransform_, - x, - y, - 1, - 1, - rotation, - -x, - -y - ); - context.setTransform.apply(context, localTransform); - context.translate(x, y); + context.translate(x - this.textOffsetX_, y - this.textOffsetY_); + context.rotate(rotation); + context.translate(this.textOffsetX_, this.textOffsetY_); context.scale(this.textScale_[0], this.textScale_[1]); if (this.textStrokeState_) { context.strokeText(this.text_, 0, 0); diff --git a/test/rendering/cases/text-style-offset/expected.png b/test/rendering/cases/text-style-offset/expected.png new file mode 100644 index 0000000000..e7167fc1d0 Binary files /dev/null and b/test/rendering/cases/text-style-offset/expected.png differ diff --git a/test/rendering/cases/text-style-offset/main.js b/test/rendering/cases/text-style-offset/main.js new file mode 100644 index 0000000000..398eef4fa8 --- /dev/null +++ b/test/rendering/cases/text-style-offset/main.js @@ -0,0 +1,121 @@ +import Circle from '../../../../src/ol/style/Circle.js'; +import Feature from '../../../../src/ol/Feature.js'; +import Fill from '../../../../src/ol/style/Fill.js'; +import Map from '../../../../src/ol/Map.js'; +import Point from '../../../../src/ol/geom/Point.js'; +import Stroke from '../../../../src/ol/style/Stroke.js'; +import Style from '../../../../src/ol/style/Style.js'; +import Text from '../../../../src/ol/style/Text.js'; +import VectorLayer from '../../../../src/ol/layer/Vector.js'; +import VectorSource from '../../../../src/ol/source/Vector.js'; +import View from '../../../../src/ol/View.js'; +import {getVectorContext} from '../../../../src/ol/render.js'; + +const offsetX = new Style({ + image: new Circle({ + radius: 5, + fill: new Fill({ + color: 'green', + }), + }), + text: new Text({ + font: '24px Ubuntu', + text: 'offsetX', + offsetX: -40, + rotation: Math.PI / 4, + fill: new Stroke({ + color: 'green', + }), + }), +}); + +const noOffset = new Style({ + image: new Circle({ + radius: 5, + fill: new Fill({ + color: 'black', + }), + }), + text: new Text({ + font: '24px Ubuntu', + text: 'no offset', + rotation: Math.PI / 4, + fill: new Stroke({ + color: 'black', + }), + }), +}); + +const offsetY = new Style({ + image: new Circle({ + radius: 5, + fill: new Fill({ + color: 'red', + }), + }), + text: new Text({ + font: '24px Ubuntu', + text: 'offsetY', + offsetY: -20, + rotation: Math.PI / 4, + fill: new Stroke({ + color: 'red', + }), + }), +}); + +const vectorSource = new VectorSource(); +const vectorLayer = new VectorLayer({ + source: vectorSource, +}); + +let feature; + +feature = new Feature({ + geometry: new Point([-50, -50]), +}); +feature.setStyle(offsetX); +vectorSource.addFeature(feature); + +feature = new Feature({ + geometry: new Point([-50, 0]), +}); +feature.setStyle(noOffset); +vectorSource.addFeature(feature); + +feature = new Feature({ + geometry: new Point([-50, 50]), +}); +feature.setStyle(offsetY); +vectorSource.addFeature(feature); + +vectorLayer.on('postrender', function (event) { + const vectorContext = getVectorContext(event); + + feature = new Feature({ + geometry: new Point([50, -50]), + }); + vectorContext.drawFeature(feature, offsetX); + + feature = new Feature({ + geometry: new Point([50, 0]), + }); + vectorContext.drawFeature(feature, noOffset); + + feature = new Feature({ + geometry: new Point([50, 50]), + }); + vectorContext.drawFeature(feature, offsetY); +}); + +new Map({ + pixelRatio: 1, + layers: [vectorLayer], + target: 'map', + view: new View({ + center: [0, 0], + resolution: 1, + }), +}); + +render({tolerance: 0.02});