(function() {
/**
* @typedef {Help4.control2.hotspot.Hotspot.Params} Help4.control2.hotspot.Circle.Params
* @property {Help4.control2.PositionXY} [point = {x: 0, y: 0}] - center point of hotspot
* @property {Help4.control2.PositionLeftTop} [delta = {left: 0, top: 0}] - in case hotspot is moved
* @property {string} [size = ''] - size of hotspot
*/
/**
* Creates a circle hotspot.
* @augments Help4.control2.hotspot.Hotspot
* @property {Help4.control2.PositionXY} point - center point of hotspot
* @property {Help4.control2.PositionLeftTop} delta - in case hotspot is moved
* @property {string} size - size of hotspot
*/
Help4.control2.hotspot.Circle = class extends Help4.control2.hotspot.Hotspot {
/**
* @override
* @param {Help4.control2.hotspot.Circle.Params} [params]
*/
constructor(params) {
const T = Help4.jscore.ControlBase.TYPES;
super(params, {
params: {
point: {type: T.xy},
delta: {type: T.leftTop},
size: {type: T.string}
},
statics: {
_midpoint: {destroy: false}
},
config: {
css: 'circle'
}
});
}
/**
* @override
*/
calcMeetingPoint(point) {
const ra = _sizeToRadius(this.size);
const {point: pt, delta} = this;
const {x, y} = {
x: pt.x + delta.left,
y: pt.y + delta.top
};
const dx = x - point.x;
const dy = y - point.y;
const dist = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
// size of hotspot is: radius + border; line should start right at the border (so border-w + 1)
// see H4H.Connected._create for borderSize information
const norm = 1 - (ra + this.borderSize + 1) / dist;
return norm > 0
? {x: point.x + norm * dx, y: point.y + norm * dy}
: point;
}
/**
* get possible connection points for this control; this is an incompatible override with the base class!
* @param {object} [params] - includes whether to use the midpoint of the circle
* @returns {Help4.control2.ConnectionPoints} - points top,left,bottom,right and middle of this control
*/
getConnectionPoints(params) {
const {useMidPoint = false} = params || {};
const {x, y} = this._midpoint;
return !this.spotlight && useMidPoint
? {c: {x, y}}
: super.getConnectionPoints(params);
}
/**
* @override
* @param {Help4.control2.hotspot.Circle.Params} params - same params as provided to the constructor
*/
_onAfterInit(params) {
super._onAfterInit(params);
this._midpoint = {x: 0, y: 0};
}
/**
* @override
* @param {HTMLElement} dom - control DOM
*/
_onDomCreated(dom) {
super._onDomCreated(dom);
this._content = this._createElement('div', {css: 'inner'});
_apply.call(this);
}
/**
* @override
* @param {Help4.jscore.ControlBase.PropertyChangeEvent} event - the change event
*/
_applyPropertyToDom(event) {
({point: 1, delta: 1, size: 1}[event.name])
? _apply.call(this)
: super._applyPropertyToDom(event);
}
/**
* @override
*/
getDragStartPosition() {
const {point: {x, y}} = this;
const ra = _sizeToRadius(this.size);
return {
x: x - ra,
y: y - ra
};
}
}
/**
* @memberof Help4.control2.hotspot.Circle#
* @private
*/
function _apply() {
const dom = this.getDom();
if (!dom) return;
const {point: {x, y}, delta: {left: dx, top: dy}} = this;
const {x: mx, y: my} = this._midpoint = {x: x + dx, y: y + dy};
const ra = _sizeToRadius(this.size);
const wh = ra * 2 + 'px';
Help4.extendObject(dom.style, {
left: mx - ra + 'px', // left of box that contains the hotspot
top: my - ra + 'px', // top of ...
width: wh,
height: wh,
lineHeight: wh
});
}
/**
* @memberof Help4.control2.hotspot.Circle#
* @param {string} size
* @returns {number}
* @private
*/
function _sizeToRadius(size) {
const {HOTSPOT_SIZES} = Help4;
return (HOTSPOT_SIZES.find(hs => hs.size === size) || HOTSPOT_SIZES[0]).radius;
}
})();