Merge pull request #13390 from MoonE/icon-clone

Fix clone of icon loses imgSize when cache is full
This commit is contained in:
MoonE
2022-02-17 20:04:32 +01:00
committed by GitHub
2 changed files with 51 additions and 16 deletions
+11 -9
View File
@@ -140,9 +140,10 @@ class Icon extends ImageStyle {
const image = options.img !== undefined ? options.img : null; const image = options.img !== undefined ? options.img : null;
/** /**
* @type {import("../size.js").Size} * @private
* @type {import("../size.js").Size|undefined}
*/ */
const imgSize = options.imgSize !== undefined ? options.imgSize : null; this.imgSize_ = options.imgSize;
/** /**
* @type {string|undefined} * @type {string|undefined}
@@ -150,7 +151,7 @@ class Icon extends ImageStyle {
let src = options.src; let src = options.src;
assert(!(src !== undefined && image), 4); // `image` and `src` cannot be provided at the same time assert(!(src !== undefined && image), 4); // `image` and `src` cannot be provided at the same time
assert(!image || (image && imgSize), 5); // `imgSize` must be set when `image` is provided assert(!image || (image && this.imgSize_), 5); // `imgSize` must be set when `image` is provided
if ((src === undefined || src.length === 0) && image) { if ((src === undefined || src.length === 0) && image) {
src = /** @type {HTMLImageElement} */ (image).src || getUid(image); src = /** @type {HTMLImageElement} */ (image).src || getUid(image);
@@ -176,7 +177,7 @@ class Icon extends ImageStyle {
this.iconImage_ = getIconImage( this.iconImage_ = getIconImage(
image, image,
/** @type {string} */ (src), /** @type {string} */ (src),
imgSize, this.imgSize_ !== undefined ? this.imgSize_ : null,
this.crossOrigin_, this.crossOrigin_,
imageState, imageState,
this.color_ this.color_
@@ -221,19 +222,20 @@ class Icon extends ImageStyle {
anchorOrigin: this.anchorOrigin_, anchorOrigin: this.anchorOrigin_,
anchorXUnits: this.anchorXUnits_, anchorXUnits: this.anchorXUnits_,
anchorYUnits: this.anchorYUnits_, anchorYUnits: this.anchorYUnits_,
crossOrigin: this.crossOrigin_,
color: color:
this.color_ && this.color_.slice this.color_ && this.color_.slice
? this.color_.slice() ? this.color_.slice()
: this.color_ || undefined, : this.color_ || undefined,
src: this.getSrc(), crossOrigin: this.crossOrigin_,
imgSize: this.imgSize_,
offset: this.offset_.slice(), offset: this.offset_.slice(),
offsetOrigin: this.offsetOrigin_, offsetOrigin: this.offsetOrigin_,
size: this.size_ !== null ? this.size_.slice() : undefined,
opacity: this.getOpacity(), opacity: this.getOpacity(),
scale: Array.isArray(scale) ? scale.slice() : scale,
rotation: this.getRotation(),
rotateWithView: this.getRotateWithView(), rotateWithView: this.getRotateWithView(),
rotation: this.getRotation(),
scale: Array.isArray(scale) ? scale.slice() : scale,
size: this.size_ !== null ? this.size_.slice() : undefined,
src: this.getSrc(),
}); });
} }
+40 -7
View File
@@ -11,6 +11,9 @@ describe('ol.style.Icon', function () {
'data:image/gif;base64,' + 'data:image/gif;base64,' +
'R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs='; 'R0lGODlhAQABAIAAAP///wAAACwAAAAAAQABAAACAkQBADs=';
beforeEach(function () {
iconImageCache.clear();
});
describe('constructor', function () { describe('constructor', function () {
it('caches canvas images with a uid as src', function () { it('caches canvas images with a uid as src', function () {
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
@@ -47,7 +50,7 @@ describe('ol.style.Icon', function () {
expect(clone).to.not.be(original); expect(clone).to.not.be(original);
}); });
it('copies all values ', function () { it('copies all values with img', function () {
const canvas = document.createElement('canvas'); const canvas = document.createElement('canvas');
const original = new Icon({ const original = new Icon({
anchor: [1, 0], anchor: [1, 0],
@@ -82,14 +85,44 @@ describe('ol.style.Icon', function () {
expect(original.getOpacity()).to.eql(clone.getOpacity()); expect(original.getOpacity()).to.eql(clone.getOpacity());
expect(original.getRotation()).to.eql(clone.getRotation()); expect(original.getRotation()).to.eql(clone.getRotation());
expect(original.getRotateWithView()).to.eql(clone.getRotateWithView()); expect(original.getRotateWithView()).to.eql(clone.getRotateWithView());
});
const original2 = new Icon({ it('copies all values with src', function () {
const original = new Icon({
src: src, src: src,
}); });
const clone2 = original2.clone(); const clone = original.clone();
expect(original2.getImage(1)).to.be(clone2.getImage(1)); expect(original.getImage(1)).to.be(clone.getImage(1));
expect(original2.iconImage_).to.be(clone2.iconImage_); expect(original.iconImage_).to.be(clone.iconImage_);
expect(original2.getSrc()).to.eql(clone2.getSrc()); expect(original.getSrc()).to.be(clone.getSrc());
});
it('copies all values with src without shared IconImageCache', function (done) {
const imgSize = [11, 13];
const original = new Icon({
src: src,
imgSize: imgSize.slice(),
});
iconImageCache.clear();
const clone = original.clone();
original.load();
clone.load();
Promise.all([
new Promise(function (resolve) {
original.iconImage_.addEventListener('change', resolve);
}),
new Promise(function (resolve) {
clone.iconImage_.addEventListener('change', resolve);
}),
]).then(function () {
expect(original.getSrc()).to.be(clone.getSrc());
expect(original.iconImage_).to.not.be(clone.iconImage_);
expect(original.getImage(1).width).to.be(imgSize[0]);
expect(original.getImage(1).height).to.be(imgSize[1]);
expect(original.getImage(1).width).to.be(clone.getImage(1).width);
expect(original.getImage(1).height).to.be(clone.getImage(1).height);
done();
});
}); });
it('the clone does not reference the same objects as the original', function () { it('the clone does not reference the same objects as the original', function () {