From 90d28854867add54e5a37742291a2f716c039c25 Mon Sep 17 00:00:00 2001 From: pixelzoom Date: Mon, 5 Dec 2022 15:41:33 -0700 Subject: [PATCH] improve performance of ParticlesNode (Canvas), https://github.com/phetsims/beers-law-lab/issues/209 --- js/concentration/model/SoluteParticle.ts | 11 +++++++++++ js/concentration/view/ParticlesNode.ts | 16 +++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/js/concentration/model/SoluteParticle.ts b/js/concentration/model/SoluteParticle.ts index 17d3483c..87258046 100644 --- a/js/concentration/model/SoluteParticle.ts +++ b/js/concentration/model/SoluteParticle.ts @@ -41,6 +41,12 @@ export default class SoluteParticle extends PhetioObject { public readonly positionProperty: Property; public readonly orientation: number; + // Precompute these things, to improve the performance of ParticlesNode. + public readonly cos: number; // cosine of orientation + public readonly sin: number; // since of orientation + public readonly fillStyle: string; // fillStyle for rendering with Canvas + public readonly strokeStyle: string; // strokeStyle for rendering with Canvas + /** * @param color * @param size particles are square, this is the length of one side @@ -57,6 +63,11 @@ export default class SoluteParticle extends PhetioObject { this.size = size; this.positionProperty = new Vector2Property( position ); this.orientation = orientation; + + this.cos = Math.cos( orientation ); + this.sin = Math.sin( orientation ); + this.fillStyle = color.getCanvasStyle(); + this.strokeStyle = color.darkerColor().getCanvasStyle(); } public toStateObject(): SoluteParticleStateObject { diff --git a/js/concentration/view/ParticlesNode.ts b/js/concentration/view/ParticlesNode.ts index b2c14d7d..aceb238c 100644 --- a/js/concentration/view/ParticlesNode.ts +++ b/js/concentration/view/ParticlesNode.ts @@ -42,7 +42,7 @@ export default class ParticlesNode extends CanvasNode { */ public override paintCanvas( context: CanvasRenderingContext2D ): void { - const particles = this.particleGroup.getArray(); + const particles = this.particleGroup.getArray(); // reference - do not modify! const numberOfParticles = particles.length; // Set and compute static properties that should be shared by all the particles, and start the path. @@ -51,8 +51,8 @@ export default class ParticlesNode extends CanvasNode { const halfViewSize = this.modelViewTransform.modelToViewDeltaX( particles[ 0 ].size ) * Math.SQRT2 / 2; - context.fillStyle = particles[ 0 ].color.getCanvasStyle(); - context.strokeStyle = particles[ 0 ].color.darkerColor().getCanvasStyle(); + context.fillStyle = particles[ 0 ].fillStyle; + context.strokeStyle = particles[ 0 ].strokeStyle; context.lineWidth = 1; context.beginPath(); @@ -60,12 +60,10 @@ export default class ParticlesNode extends CanvasNode { // draw into one big path for ( let i = 0; i < numberOfParticles; i++ ) { const particle = particles[ i ]; - - const position = this.modelViewTransform.modelToViewPosition( particle.positionProperty.value ); - const x = position.x; - const y = position.y; - const cos = Math.cos( particle.orientation ) * halfViewSize; - const sin = Math.sin( particle.orientation ) * halfViewSize; + const x = this.modelViewTransform.modelToViewX( particle.positionProperty.value.x ); + const y = this.modelViewTransform.modelToViewY( particle.positionProperty.value.y ); + const cos = particle.cos * halfViewSize; + const sin = particle.sin * halfViewSize; context.moveTo( x + cos, y + sin ); context.lineTo( x - sin, y + cos ); context.lineTo( x - cos, y - sin );