diff --git a/src/shapes/primitives/text.ts b/src/shapes/primitives/text.ts index 3853788..836a3c0 100644 --- a/src/shapes/primitives/text.ts +++ b/src/shapes/primitives/text.ts @@ -287,6 +287,16 @@ class Text implements Shape { return this._tex; } + changeText(text: string): this { + this._text = text; + + this._textMeasurement = new TextMeasurement(config.canvasInstance!, this._tex); + this._textWidth = this._textMeasurement.textWidth(this._text, this._size, this._font); + this._textHeight = this._textMeasurement.textHeight(this._text, this._size, this._font); + + return this; + } + private boundingBox(): { minX: number, maxX: number, minY: number, maxY: number } { const left = this._align === 'left' ? this._x : this._align === 'center' ? this._x - this._textWidth / 2 : this._x - this._textWidth; const top = this._baseline === 'top' ? this._y : this._baseline === 'middle' ? this._y - this._textHeight / 2 : this._y - this._textHeight; diff --git a/src/utils.ts b/src/utils.ts index d14e902..f68d9bc 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -49,4 +49,27 @@ function extractType(obj: any): T { } -export default { deepCopy, extractType }; +function throttle void>(func: T, wait: number): (...args: Parameters) => void { + let timeout: ReturnType | null = null; + let lastCallTime: number | null = null; + + return function(...args: Parameters): void { + const now = Date.now(); + + if (lastCallTime && now < lastCallTime + wait) { + if (timeout) { + clearTimeout(timeout); + } + timeout = setTimeout(() => { + lastCallTime = Date.now(); + func(...args); + }, wait - (now - lastCallTime)); + } else { + lastCallTime = Date.now(); + func(...args); + } + }; +} + + +export default { deepCopy, extractType, throttle, }; diff --git a/test/script_test.ts b/test/script_test.ts index 8ccb95c..702b7a3 100644 --- a/test/script_test.ts +++ b/test/script_test.ts @@ -451,27 +451,45 @@ class TestScene extends Scene { const p = axes.point([0.5, fn(0.5)]); const q = axes.point([0.69, fn(0.69)]); - const pText = new Text({ text: 'P' }).nextTo(p, [-1, 1]); - const qText = new Text({ text: 'Q' }).nextTo(q, LEFT(1.5)); + const pText = new Tex({ text: 'P' }).nextTo(p, [-1, 1]); + const qText = new Tex({ text: 'Q' }).nextTo(q, RIGHT(1.5)); const qDot = new Dot({ center: q, color: Colors.blue() }); const secant = new Line({ from: p, to: q, length: 6, lineColor: Colors.blue() }); + const tangent = new TangentLine({ plot, x: 0.5, length: 4, color: Colors.pink() }); + const tangentText = new Tex(`m`).changeColor(Colors.pink()).nextTo(tangent.to()); + const secantText = new Tex(`m_{\sec}`).nextTo(secant.to()).changeColor(Colors.blue()); + // const secantText = new Text(`m_{\\sec}`).nextTo(secant.to()).changeColor(Colors.blue()); this.add( axes, plot, secant, - new TangentLine({ plot, x: 0.5, length: 4, color: Colors.pink() }), + tangent, new Dot({ center: p, color: Colors.pink() }), qDot, - pText, qText + pText, qText, + tangentText, + secantText, ); + const updateText = utils.throttle(text => secantText.changeText(text), 200); + this.add(new Updater((pctComplete: number, starting: boolean) => { - const x = math.lerp(0.5, 0.69, 1 - pctComplete); + const rx = math.lerp(0.5, 0.75, 1 - pctComplete); + const m = (25 * rx * rx - 25 * 0.5 * 0.5) / (rx - 0.5); + + const x = math.lerp(0.51, 0.69, 1 - pctComplete); qDot.moveTo(plot.pointAtX(x)); secant.changeEndpoints(p, qDot, true); - }, { duration: 3000, easing: Easing.linear, repeat: true, yoyo: true, })); + qText.nextTo(qDot.center(), RIGHT(), 0.3); + secantText.nextTo(secant.to()) //.changeText(`m_{\\sec} = ${m.toFixed(2)}`); + + // console.log(m, pctComplete) + updateText(`m_{\\sec} = ${m.toFixed(2)}`); + + }, { duration: 5000, easing: Easing.linear, repeat: true, yoyo: true, })); + // }, { duration: 5000, easing: x => Easing.easeStep(x, 10), repeat: true, yoyo: true, })); } }