|
|
|
let cacheDigits, cacheAppend, cacheRadius, cacheCircle; |
|
|
|
export default class PathString { |
|
constructor(digits) { |
|
this._append = digits == null ? append : appendRound(digits); |
|
this._radius = 4.5; |
|
this._ = ""; |
|
} |
|
pointRadius(_) { |
|
this._radius = +_; |
|
return this; |
|
} |
|
polygonStart() { |
|
this._line = 0; |
|
} |
|
polygonEnd() { |
|
this._line = NaN; |
|
} |
|
lineStart() { |
|
this._point = 0; |
|
} |
|
lineEnd() { |
|
if (this._line === 0) this._ += "Z"; |
|
this._point = NaN; |
|
} |
|
point(x, y) { |
|
switch (this._point) { |
|
case 0: { |
|
this._append`M${x},${y}`; |
|
this._point = 1; |
|
break; |
|
} |
|
case 1: { |
|
this._append`L${x},${y}`; |
|
break; |
|
} |
|
default: { |
|
this._append`M${x},${y}`; |
|
if (this._radius !== cacheRadius || this._append !== cacheAppend) { |
|
const r = this._radius; |
|
const s = this._; |
|
this._ = ""; |
|
this._append`m0,${r}a${r},${r} 0 1,1 0,${-2 * r}a${r},${r} 0 1,1 0,${2 * r}z`; |
|
cacheRadius = r; |
|
cacheAppend = this._append; |
|
cacheCircle = this._; |
|
this._ = s; |
|
} |
|
this._ += cacheCircle; |
|
break; |
|
} |
|
} |
|
} |
|
result() { |
|
const result = this._; |
|
this._ = ""; |
|
return result.length ? result : null; |
|
} |
|
} |
|
|
|
function append(strings) { |
|
let i = 1; |
|
this._ += strings[0]; |
|
for (const j = strings.length; i < j; ++i) { |
|
this._ += arguments[i] + strings[i]; |
|
} |
|
} |
|
|
|
function appendRound(digits) { |
|
const d = Math.floor(digits); |
|
if (!(d >= 0)) throw new RangeError(`invalid digits: ${digits}`); |
|
if (d > 15) return append; |
|
if (d !== cacheDigits) { |
|
const k = 10 ** d; |
|
cacheDigits = d; |
|
cacheAppend = function append(strings) { |
|
let i = 1; |
|
this._ += strings[0]; |
|
for (const j = strings.length; i < j; ++i) { |
|
this._ += Math.round(arguments[i] * k) / k + strings[i]; |
|
} |
|
}; |
|
} |
|
return cacheAppend; |
|
} |
|
|