Changes for the CircleStyle inconsistency seen in #9395
Change hit detection test to reflect fix for #9395 CircleStyle inconsistency Update ol/style/Circle and ol/style/RegularShapen tests Revise test for no fill Add test for transparent fill Update Upgrade notes Changes to hit detection with unfilled styles
This commit is contained in:
@@ -279,6 +279,10 @@ The `getGetFeatureInfoUrl` of `ol/source/ImageWMS` and `ol/source/TileWMS` is no
|
||||
|
||||
`getFeaturesAtPixel` now returns an empty array instead of null if no features were found.
|
||||
|
||||
##### Hit detection with unfilled styles
|
||||
|
||||
Hit detection over styled Circle geometry and Circle and RegularShape styles is now consistent with that for styled Polygon geometry. There is no hit detection over the interior of unfilled shapes. To get the previous behavior, specify a Fill style with transparent color.
|
||||
|
||||
#### Other changes
|
||||
|
||||
##### Allow declutter in image render mode
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* @module ol/style/RegularShape
|
||||
*/
|
||||
|
||||
import {asArray} from '../color.js';
|
||||
import {asColorLike} from '../colorlike.js';
|
||||
import {createCanvasContext2D} from '../dom.js';
|
||||
import ImageState from '../ImageState.js';
|
||||
@@ -429,17 +430,31 @@ class RegularShape extends ImageStyle {
|
||||
*/
|
||||
createHitDetectionCanvas_(renderOptions) {
|
||||
this.hitDetectionImageSize_ = [renderOptions.size, renderOptions.size];
|
||||
this.hitDetectionCanvas_ = this.canvas_;
|
||||
if (this.fill_) {
|
||||
this.hitDetectionCanvas_ = this.canvas_;
|
||||
return;
|
||||
let color = this.fill_.getColor();
|
||||
|
||||
// determine if fill is transparent (or pattern or gradient)
|
||||
let opacity = 0;
|
||||
if (typeof color === 'string') {
|
||||
color = asArray(color);
|
||||
}
|
||||
if (color === null) {
|
||||
opacity = 1;
|
||||
} else if (Array.isArray(color)) {
|
||||
opacity = color.length === 4 ? color[3] : 1;
|
||||
}
|
||||
if (opacity === 0) {
|
||||
|
||||
// if a transparent fill style is set, create an extra hit-detection image
|
||||
// with a default fill style
|
||||
const context = createCanvasContext2D(renderOptions.size, renderOptions.size);
|
||||
this.hitDetectionCanvas_ = context.canvas;
|
||||
|
||||
this.drawHitDetectionCanvas_(renderOptions, context, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// if no fill style is set, create an extra hit-detection image with a
|
||||
// default fill style
|
||||
const context = createCanvasContext2D(renderOptions.size, renderOptions.size);
|
||||
this.hitDetectionCanvas_ = context.canvas;
|
||||
|
||||
this.drawHitDetectionCanvas_(renderOptions, context, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -393,23 +393,21 @@ describe('ol.renderer.canvas.VectorLayer', function() {
|
||||
geometry: new Circle([7.5, 7.5], 1.5),
|
||||
fillType: 'transparent'
|
||||
}),
|
||||
// CircleStyle transparent and no fill hit detection
|
||||
// is currently the opposite of ol/Style
|
||||
new Feature({
|
||||
geometry: new Point([1.5, 1.5]),
|
||||
fillType: 'transparent'
|
||||
fillType: 'none'
|
||||
}),
|
||||
new Feature({
|
||||
geometry: new Point([2.5, 2.5]),
|
||||
fillType: 'transparent'
|
||||
fillType: 'none'
|
||||
}),
|
||||
new Feature({
|
||||
geometry: new Point([6.5, 1.5]),
|
||||
fillType: 'none'
|
||||
fillType: 'transparent'
|
||||
}),
|
||||
new Feature({
|
||||
geometry: new Point([7.5, 2.5]),
|
||||
fillType: 'none'
|
||||
fillType: 'transparent'
|
||||
})
|
||||
]
|
||||
});
|
||||
|
||||
@@ -14,13 +14,31 @@ describe('ol.style.Circle', function() {
|
||||
expect(style.getImageSize()).to.eql([21, 21]);
|
||||
expect(style.getOrigin()).to.eql([0, 0]);
|
||||
expect(style.getAnchor()).to.eql([10.5, 10.5]);
|
||||
// hit-detection image is created, because no fill style is set
|
||||
// no hit-detection image is created, because no fill style is set
|
||||
expect(style.getImage()).to.be(style.getHitDetectionImage());
|
||||
expect(style.getHitDetectionImage()).to.be.an(HTMLCanvasElement);
|
||||
expect(style.getHitDetectionImageSize()).to.eql([21, 21]);
|
||||
});
|
||||
|
||||
it('creates a canvas (transparent fill-style)', function() {
|
||||
const style = new CircleStyle({
|
||||
radius: 10,
|
||||
fill: new Fill({
|
||||
color: 'transparent'
|
||||
})
|
||||
});
|
||||
expect(style.getImage()).to.be.an(HTMLCanvasElement);
|
||||
expect(style.getSize()).to.eql([21, 21]);
|
||||
expect(style.getImageSize()).to.eql([21, 21]);
|
||||
expect(style.getOrigin()).to.eql([0, 0]);
|
||||
expect(style.getAnchor()).to.eql([10.5, 10.5]);
|
||||
// hit-detection image is created, because transparent fill style is set
|
||||
expect(style.getImage()).to.not.be(style.getHitDetectionImage());
|
||||
expect(style.getHitDetectionImage()).to.be.an(HTMLCanvasElement);
|
||||
expect(style.getHitDetectionImageSize()).to.eql([21, 21]);
|
||||
});
|
||||
|
||||
it('creates a canvas (fill-style)', function() {
|
||||
it('creates a canvas (non-transparent fill-style)', function() {
|
||||
const style = new CircleStyle({
|
||||
radius: 10,
|
||||
fill: new Fill({
|
||||
@@ -32,7 +50,7 @@ describe('ol.style.Circle', function() {
|
||||
expect(style.getImageSize()).to.eql([21, 21]);
|
||||
expect(style.getOrigin()).to.eql([0, 0]);
|
||||
expect(style.getAnchor()).to.eql([10.5, 10.5]);
|
||||
// no hit-detection image is created, because fill style is set
|
||||
// no hit-detection image is created, because non-transparent fill style is set
|
||||
expect(style.getImage()).to.be(style.getHitDetectionImage());
|
||||
expect(style.getHitDetectionImage()).to.be.an(HTMLCanvasElement);
|
||||
expect(style.getHitDetectionImageSize()).to.eql([21, 21]);
|
||||
|
||||
@@ -40,13 +40,31 @@ describe('ol.style.RegularShape', function() {
|
||||
expect(style.getImageSize()).to.eql([21, 21]);
|
||||
expect(style.getOrigin()).to.eql([0, 0]);
|
||||
expect(style.getAnchor()).to.eql([10.5, 10.5]);
|
||||
// hit-detection image is created, because no fill style is set
|
||||
// no hit-detection image is created, because no fill style is set
|
||||
expect(style.getImage()).to.be(style.getHitDetectionImage());
|
||||
expect(style.getHitDetectionImage()).to.be.an(HTMLCanvasElement);
|
||||
expect(style.getHitDetectionImageSize()).to.eql([21, 21]);
|
||||
});
|
||||
|
||||
it('creates a canvas (transparent fill-style)', function() {
|
||||
const style = new RegularShape({
|
||||
radius: 10,
|
||||
fill: new Fill({
|
||||
color: 'transparent'
|
||||
})
|
||||
});
|
||||
expect(style.getImage()).to.be.an(HTMLCanvasElement);
|
||||
expect(style.getSize()).to.eql([21, 21]);
|
||||
expect(style.getImageSize()).to.eql([21, 21]);
|
||||
expect(style.getOrigin()).to.eql([0, 0]);
|
||||
expect(style.getAnchor()).to.eql([10.5, 10.5]);
|
||||
// hit-detection image is created, because transparent fill style is set
|
||||
expect(style.getImage()).to.not.be(style.getHitDetectionImage());
|
||||
expect(style.getHitDetectionImage()).to.be.an(HTMLCanvasElement);
|
||||
expect(style.getHitDetectionImageSize()).to.eql([21, 21]);
|
||||
});
|
||||
|
||||
it('creates a canvas (fill-style)', function() {
|
||||
it('creates a canvas (non-transparent fill-style)', function() {
|
||||
const style = new RegularShape({
|
||||
radius: 10,
|
||||
fill: new Fill({
|
||||
@@ -58,7 +76,7 @@ describe('ol.style.RegularShape', function() {
|
||||
expect(style.getImageSize()).to.eql([21, 21]);
|
||||
expect(style.getOrigin()).to.eql([0, 0]);
|
||||
expect(style.getAnchor()).to.eql([10.5, 10.5]);
|
||||
// no hit-detection image is created, because fill style is set
|
||||
// no hit-detection image is created, because non-transparent fill style is set
|
||||
expect(style.getImage()).to.be(style.getHitDetectionImage());
|
||||
expect(style.getHitDetectionImage()).to.be.an(HTMLCanvasElement);
|
||||
expect(style.getHitDetectionImageSize()).to.eql([21, 21]);
|
||||
|
||||
Reference in New Issue
Block a user