Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #275 from agpixdev/rotated-mapicon-pixels-chopped-pr
Browse files Browse the repository at this point in the history
Properly size the canvas based on image size and rotation angle
  • Loading branch information
adube committed Sep 7, 2019
2 parents 1ad6ff9 + 01bcfb0 commit dd97877
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 5 deletions.
Binary file added examples/data/linux.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions examples/icon.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import GoogleLayer from 'olgm/layer/Google.js';
import {defaults as defaultInteractions} from 'olgm/interaction.js';

const center = [-7908084, 6177492];
const left = [-7928084, 6177492];

const googleLayer = new GoogleLayer();

Expand All @@ -36,6 +37,26 @@ feature.setStyle(new Style({
}))
}));
source.addFeature(feature);

const bigIcon = new Feature(new Point(left));
bigIcon.setStyle(new Style({
image: new Icon(({
anchor: [132, 468],
anchorXUnits: 'pixels',
anchorYUnits: 'pixels',
src: 'data/linux.png',
opacity: 0.5
}))
}));

source.addFeature(bigIcon);

setInterval(function() {
const image = bigIcon.getStyle().getImage();
image.setRotation(image.getRotation() + Math.PI / 180.0);
bigIcon.changed();
}, 30);

const vector = new VectorLayer({
source: source
});
Expand Down
39 changes: 34 additions & 5 deletions src/olgm/gm/MapIcon.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ class MapIcon extends MapElement {
}
}

/**
* Rotate a point around the origin by a given angle expressed as a (cos, sin) pair.
* @private
*/

rotate_(cosTheta, sinTheta, x, y) {
return [x * cosTheta - y * sinTheta, x * sinTheta + y * cosTheta];
}

/**
* Draws the icon to the canvas 2d context.
Expand All @@ -74,17 +82,39 @@ class MapIcon extends MapElement {

style.zIndex = /** @type {number} */ (this.get('zIndex'));

const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);

const anchor = this.imageStyle_.getAnchor() || [0, 0];
const scale = this.imageStyle_.getScale() || 1;
const anchor = this.imageStyle_.getAnchor() || [0, 0];
const rotation = this.imageStyle_.getRotation() || 0;
const opacity = this.imageStyle_.getOpacity() || 1;

const offsetX = anchor[0] * scale;
const offsetY = anchor[1] * scale;

let w_2 = image.width * scale * 0.5;
let h_2 = image.height * scale * 0.5;

w_2 += Math.abs(w_2 - offsetX);
h_2 += Math.abs(h_2 - offsetY);

const cosTheta = Math.cos(rotation);
const sinTheta = Math.sin(rotation);

const p1 = this.rotate_(cosTheta, sinTheta, -w_2, -h_2);
const p2 = this.rotate_(cosTheta, sinTheta, +w_2, -h_2);
const p3 = this.rotate_(cosTheta, sinTheta, -w_2, +h_2);
const p4 = this.rotate_(cosTheta, sinTheta, +w_2, +h_2);

const minX = Math.min(p1[0], p2[0], p3[0], p4[0]);
const maxX = Math.max(p1[0], p2[0], p3[0], p4[0]);
const minY = Math.min(p1[1], p2[1], p3[1], p4[1]);
const maxY = Math.max(p1[1], p2[1], p3[1], p4[1]);

canvas.width = Math.round(maxX - minX);
canvas.height = Math.round(maxY - minY);

const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);

const x = canvas.width / 2 - offsetX;
const y = canvas.height / 2 - offsetY;

Expand All @@ -97,7 +127,6 @@ class MapIcon extends MapElement {
image.width * scale, image.height * scale);
}


/**
* Manage feature being added to the map
* @api
Expand Down

0 comments on commit dd97877

Please sign in to comment.