UNPKG

jsroot

Version:
109 lines (87 loc) 3.6 kB
import { TLinePainter } from './TLinePainter.mjs'; import { ensureTCanvas } from '../gpad/TCanvasPainter.mjs'; /** * @summary Painter for TArrow class * @private */ class TArrowPainter extends TLinePainter { #beg; #mid; #end; #angle2; // half of angle in rad #wsize; // arrow size /** @summary Create line segment with rotation */ rotate(angle, x0, y0) { let dx = this.#wsize * Math.cos(angle), dy = this.#wsize * Math.sin(angle), res = ''; if ((x0 !== undefined) && (y0 !== undefined)) res = `M${Math.round(x0 - dx)},${Math.round(y0 - dy)}`; else { dx = -dx; dy = -dy; } res += `l${Math.round(dx)},${Math.round(dy)}`; if (x0 && (y0 === undefined)) res += 'z'; return res; } /** @summary Create SVG path for the arrow */ createPath() { const angle = Math.atan2(this.y2 - this.y1, this.x2 - this.x1), dlen = this.#wsize * Math.cos(this.#angle2), dx = dlen * Math.cos(angle), dy = dlen * Math.sin(angle); let path = ''; if (this.#beg) { path += this.rotate(angle - Math.PI - this.#angle2, this.x1, this.y1) + this.rotate(angle - Math.PI + this.#angle2, this.#beg > 10); } if (this.#mid % 10 === 2) { path += this.rotate(angle - Math.PI - this.#angle2, (this.x1 + this.x2 - dx) / 2, (this.y1 + this.y2 - dy) / 2) + this.rotate(angle - Math.PI + this.#angle2, this.#mid > 10); } if (this.#mid % 10 === 1) { path += this.rotate(angle - this.#angle2, (this.x1 + this.x2 + dx) / 2, (this.y1 + this.y2 + dy) / 2) + this.rotate(angle + this.#angle2, this.#mid > 10); } if (this.#end) { path += this.rotate(angle - this.#angle2, this.x2, this.y2) + this.rotate(angle + this.#angle2, this.#end > 10); } return `M${Math.round(this.x1 + (this.#beg > 10 ? dx : 0))},${Math.round(this.y1 + (this.#beg > 10 ? dy : 0))}` + `L${Math.round(this.x2 - (this.#end > 10 ? dx : 0))},${Math.round(this.y2 - (this.#end > 10 ? dy : 0))}` + path; } /** @summary calculate all TArrow coordinates */ prepareDraw() { super.prepareDraw(); const arrow = this.getObject(), oo = arrow.fOption, rect = this.getPadPainter().getPadRect(); this.#wsize = Math.max(3, Math.round(Math.max(rect.width, rect.height) * arrow.fArrowSize * 0.8)); this.#angle2 = arrow.fAngle / 2 / 180 * Math.PI; this.#beg = this.#mid = this.#end = 0; if (oo.indexOf('<') === 0) this.#beg = (oo.indexOf('<|') === 0) ? 12 : 2; if (oo.indexOf('->-') >= 0) this.#mid = 1; else if (oo.indexOf('-|>-') >= 0) this.#mid = 11; else if (oo.indexOf('-<-') >= 0) this.#mid = 2; else if (oo.indexOf('-<|-') >= 0) this.#mid = 12; const p1 = oo.lastIndexOf('>'), p2 = oo.lastIndexOf('|>'), len = oo.length; if ((p1 >= 0) && (p1 === len - 1)) this.#end = ((p2 >= 0) && (p2 === len - 2)) ? 11 : 1; this.createAttFill({ attr: arrow, enable: (this.#beg > 10) || (this.#end > 10) }); } /** @summary Add extras to path for TArrow */ addExtras(elem) { elem.call(this.fillatt.func); } /** @summary Draw TArrow object */ static async draw(dom, obj, opt) { const painter = new TArrowPainter(dom, obj, opt); return ensureTCanvas(painter, false).then(() => painter.redraw()); } } // class TArrowPainter export { TArrowPainter };