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

Properly size the canvas based on image size and rotation angle #275

Merged
merged 4 commits into from
Sep 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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