Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add scale to Marker options #9414

Merged
merged 11 commits into from
Apr 21, 2020
3 changes: 3 additions & 0 deletions debug/markers.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@
var g = Math.round(Math.random() * 255);
var b = Math.round(Math.random() * 255);

var sc = Math.random() * 2.5 + 0.5;

var marker = new mapboxgl.Marker({
color: `rgb(${r}, ${g}, ${b})`,
scale: sc,
draggable: true,
rotationAlignment,
pitchAlignment
Expand Down
15 changes: 12 additions & 3 deletions src/ui/marker.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type Options = {
offset?: PointLike,
anchor?: Anchor,
color?: string,
scale?: number,
draggable?: boolean,
rotation?: number,
rotationAlignment?: string,
Expand All @@ -33,6 +34,7 @@ type Options = {
* Options are `'center'`, `'top'`, `'bottom'`, `'left'`, `'right'`, `'top-left'`, `'top-right'`, `'bottom-left'`, and `'bottom-right'`.
* @param {PointLike} [options.offset] The offset in pixels as a {@link PointLike} object to apply relative to the element's center. Negatives indicate left and up.
* @param {string} [options.color='#3FB1CE'] The color to use for the default marker if options.element is not provided. The default is light blue.
* @param {number} [options.scale=1] The scale to use for the default marker if options.element is not provided. The default scale corresponds to a height of `41px` and a width of `27px`.
* @param {boolean} [options.draggable=false] A boolean indicating whether or not a marker is able to be dragged to a new position on the map.
* @param {number} [options.rotation=0] The rotation angle of the marker in degrees, relative to its respective `rotationAlignment` setting. A positive value will rotate the marker clockwise.
* @param {string} [options.pitchAlignment='auto'] `map` aligns the `Marker` to the plane of the map. `viewport` aligns the `Marker` to the plane of the viewport. `auto` automatically matches the value of `rotationAlignment`.
Expand All @@ -53,6 +55,7 @@ export default class Marker extends Evented {
_lngLat: LngLat;
_pos: ?Point;
_color: ?string;
_scale: number;
_defaultMarker: boolean;
_draggable: boolean;
_state: 'inactive' | 'pending' | 'active'; // used for handling drag events
Expand Down Expand Up @@ -81,6 +84,7 @@ export default class Marker extends Evented {

this._anchor = options && options.anchor || 'center';
this._color = options && options.color || '#3FB1CE';
this._scale = options && options.scale || 1;
this._draggable = options && options.draggable || false;
this._state = 'inactive';
this._rotation = options && options.rotation || 0;
Expand All @@ -94,10 +98,12 @@ export default class Marker extends Evented {

// create default map marker SVG
const svg = DOM.createNS('http://www.w3.org/2000/svg', 'svg');
const defaultHeight = 41;
const defaultWidth = 27;
svg.setAttributeNS(null, 'display', 'block');
svg.setAttributeNS(null, 'height', '41px');
svg.setAttributeNS(null, 'width', '27px');
svg.setAttributeNS(null, 'viewBox', '0 0 27 41');
svg.setAttributeNS(null, 'height', `${defaultHeight}px`);
svg.setAttributeNS(null, 'width', `${defaultWidth}px`);
svg.setAttributeNS(null, 'viewBox', `0 0 ${defaultWidth} ${defaultHeight}`);

const markerLarge = DOM.createNS('http://www.w3.org/2000/svg', 'g');
markerLarge.setAttributeNS(null, 'stroke', 'none');
Expand Down Expand Up @@ -181,6 +187,9 @@ export default class Marker extends Evented {

svg.appendChild(page1);

svg.setAttributeNS(null, 'height', `${defaultHeight * this._scale}px`);
svg.setAttributeNS(null, 'width', `${defaultWidth * this._scale}px`);

this._element.appendChild(svg);

// if no element and no offset option given apply an offset for the default marker
Expand Down
29 changes: 29 additions & 0 deletions test/unit/ui/marker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,35 @@ test('Marker uses a default marker element with custom color', (t) => {
t.end();
});

test('Marker uses a default marker element with custom scale', (t) => {
const map = createMap(t);
const defaultMarker = new Marker()
.setLngLat([0, 0])
.addTo(map);
// scale smaller than default
const smallerMarker = new Marker({scale: 0.8})
.setLngLat([0, 0])
.addTo(map);
// scale larger than default
const largerMarker = new Marker({scale: 2})
.setLngLat([0, 0])
.addTo(map);

// initial dimensions of svg element
t.ok(defaultMarker.getElement().firstChild.getAttribute('height').includes('41'));
t.ok(defaultMarker.getElement().firstChild.getAttribute('width').includes('27'));

// (41 * 0.8) = 32.8, (27 * 0.8) = 21.6
t.ok(smallerMarker.getElement().firstChild.getAttribute('height').includes(`32.8`));
t.ok(smallerMarker.getElement().firstChild.getAttribute('width').includes(`21.6`));

// (41 * 2) = 82, (27 * 2) = 54
t.ok(largerMarker.getElement().firstChild.getAttribute('height').includes('82'));
t.ok(largerMarker.getElement().firstChild.getAttribute('width').includes('54'));

t.end();
});

test('Marker uses a default marker with custom offset', (t) => {
const marker = new Marker({offset: [1, 2]});
t.ok(marker.getElement());
Expand Down