//////////////////////////////////////////////////////////////////////////////
// Label
//////////////////////////////////////////////////////////////////////////////
import Font from './Font';
/**
* Labels are used by [Annotation](Annotation.html) to control drawing
* [feature](Feature.html) names on the map.
* @private
*/
class Label {
/**
* Create a new label
* @param {Feature} feature - Feature this label is associated with
* @param {Object} options - ...
*/
constructor(feature, options = {}) {
this._feature = feature;
this.name = options.name;
// Minus 0.5 since features are drawn from start-0.5 to stop+0.5
this.bp = this.feature.mapStart - 0.5 + (this.feature.length / 2);
this.bpDefault = this.bp;
// this.lineAttachmentDefault = this.viewer.layout.clockPositionForBp(this.bp);
}
/**
* @member {String} - Get or set the label name.
*/
get name() {
return this._name;
}
set name(value) {
if (value === undefined || value === '') {
this.width = 0;
// Label was in Annotation, so remove it
if (!(this._name === '' || this._name === undefined)) {
this.annotation.removeLabels(this);
}
this._name = '';
} else {
// Label was not in Annotation, so add it
if (this._name === '' || this._name === undefined) {
this.annotation.addLabel(this);
}
this._name = value;
this.width = this.font.width(this.viewer.canvas.context('map'), this._name);
}
}
/**
* @member {Rect} - Get or set the label bounding rect.
*/
get rect() {
return this._rect;
}
set rect(value) {
this._rect = value;
}
/**
* @member {Number} - Get or set the label width.
*/
get width() {
return this._width;
}
set width(value) {
this._width = value;
}
/**
* @member {Number} - Get the label height which is based on the font size.
*/
get height() {
return this.font.height;
}
/**
* @member {Point} - Get or set the label origin. The upper-left corner of the label rect.
*/
// get origin() {
// return this._origin
// }
//
// set origin(value) {
// this._origin = value;
// }
/**
* @member {Number} - Get the default attachment point
*/
get lineAttachmentDefault() {
// FIXME: This may be slow. Consider calculating when ever the scales change???
return this.viewer.layout.clockPositionForBp(this.bp, true);
}
/**
* @member {Number} - Get or set the label attachment point. This number represents where on the label
* the label lines attaches in term of a hand on a clock. (e.g. 12 would be top middle of label)
*/
get lineAttachment() {
return this._lineAttachment || this.lineAttachmentDefault;
}
set lineAttachment(value) {
this._lineAttachment = value;
}
/**
* @member {Font} - Get or set the font. When setting the font, a string representing the font or a {@link Font} object can be used. For details see {@link Font}.
*/
get font() {
return this._font || this.annotation.font;
}
set font(value) {
if (value === undefined) {
this._font = this.annotation.font;
} else if (value.toString() === 'Font') {
this._font = value;
} else {
this._font = new Font(value);
}
}
/**
* @member {Viewer} - Get the *Viewer*
*/
get viewer() {
return this.feature.viewer;
}
/**
* @member {Annotation} - Get the *Annotation*
*/
get annotation() {
return this.viewer.annotation;
}
/**
* @member {Feature} - Get the Feature
*/
get feature() {
return this._feature;
}
/**
* @member {Number} - Get the mapStart position of the feature
*/
get mapStart() {
return this.feature.mapStart;
}
/**
* @member {Number} - Get the mapStop position of the feature
*/
get mapStop() {
return this.feature.mapStop;
}
/**
* Highlgith this label
*/
// highlight() {
// const canvas = this.viewer.canvas;
// canvas.clear('ui');
// const color = this.annotation.color || this.feature.color;
// const ctx = canvas.context('ui');
// const rect = this.rect;
// ctx.strokeStyle = color.rgbaString;
// ctx.lineWidth = 1;
// const padding = 2;
// ctx.strokeRect(rect.x - padding , rect.y - padding, rect.width + (2*padding), rect.height + (2*padding) );
// }
hightlight() {
this.feature.hightlight();
// this._highlight();
}
// Called from feature.highlight()
_highlight() {
if (!this.rect) { return; }
if (!this.annotation._visibleLabels.includes(this)) { return; }
const canvas = this.viewer.canvas;
// canvas.clear('ui');
const color = this.annotation.color || this.feature.color;
const ctx = canvas.context('ui');
const rect = this.rect;
ctx.strokeStyle = color.rgbaString;
ctx.lineWidth = 1;
// Rectangle Outline
// ctx.strokeRect(rect.x - padding , rect.y - padding, rect.width + (2*padding), rect.height + (2*padding) );
// Rounded Rectangle Outline
const padding = 2;
const corner = this.height / 4;
ctx.beginPath();
ctx.roundRect(rect.x - padding , rect.y - padding, rect.width + (2*padding), rect.height + (2*padding), [corner] );
ctx.stroke();
// Label Line
this.annotation.drawLabelLine(this, ctx, 1.5);
}
}
export default Label;