diff options
-rw-r--r-- | src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx | 261 |
1 files changed, 129 insertions, 132 deletions
diff --git a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx index 4b3daa0d8..2ae34374d 100644 --- a/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx +++ b/src/client/views/nodes/PhysicsBox/PhysicsSimulationWeight.tsx @@ -1,7 +1,7 @@ -import { Doc } from '../../../fields/Doc'; +import { Doc } from '../../../../fields/Doc'; import React = require('react'); import { useEffect, useState } from "react"; -import { IWallProps } from "./Wall"; +import { IWallProps } from "./PhysicsSimulationWall"; import "./Weight.scss"; export interface IForce { @@ -890,100 +890,97 @@ export default class Weight extends React.Component<IWeightProps, IState> { }; // Render weight, spring, rod(s), vectors - return ( + render () { <div style={{ zIndex: -1000 }}> <div className="weightContainer" onPointerDown={(e) => { - if (draggable) { + if (this.draggable) { e.preventDefault(); - setPaused(true); - setDragging(true); - setClickPositionX(e.clientX); - setClickPositionY(e.clientY); - } else if (this.props.dataDoc['mode'] == "Review") { - setSketching(true); - } + this.props.dataDoc['paused'] = true; + this.setState({dragging: true}); + this.setState({clickPositionX: e.clientX}); + this.setState({clickPositionY: e.clientY}); + } }} onPointerMove={(e) => { e.preventDefault(); - if (dragging) { - let newY = yPosition + e.clientY - clickPositionY; - if (newY > yMax - 2 * radius - 10) { - newY = yMax - 2 * radius - 10; + if (this.state.dragging) { + let newY = this.state.yPosition + e.clientY - this.state.clickPositionY; + if (newY > this.props.yMax - 2 * this.props.radius - 10) { + newY = this.props.yMax - 2 * this.props.radius - 10; } else if (newY < 10) { newY = 10; } - let newX = xPosition + e.clientX - clickPositionX; - if (newX > xMax - 2 * radius - 10) { - newX = xMax - 2 * radius - 10; + let newX = this.state.xPosition + e.clientX - this.state.clickPositionX; + if (newX > this.props.xMax - 2 * this.props.radius - 10) { + newX = this.props.xMax - 2 * this.props.radius - 10; } else if (newX < 10) { newX = 10; } if (this.props.dataDoc['simulationType'] == "Suspension") { - if (newX < (xMax + xMin) / 4 - radius - 15) { - newX = (xMax + xMin) / 4 - radius - 15; - } else if (newX > (3 * (xMax + xMin)) / 4 - radius / 2 - 15) { - newX = (3 * (xMax + xMin)) / 4 - radius / 2 - 15; + if (newX < (this.props.xMax + this.props.xMin) / 4 - this.props.radius - 15) { + newX = (this.props.xMax + this.props.xMin) / 4 - this.props.radius - 15; + } else if (newX > (3 * (this.props.xMax + this.props.xMin)) / 4 - this.props.radius / 2 - 15) { + newX = (3 * (this.props.xMax + this.props.xMin)) / 4 - this.props.radius / 2 - 15; } } - setYPosition(newY); - setDisplayYPosition( - Math.round((yMax - 2 * radius - newY + 5) * 100) / 100 - ); + this.setState({yPosition: newY}); + this.props.dataDoc['positionYDisplay'] = + Math.round((this.props.yMax - 2 * this.props.radius - newY + 5) * 100) / 100 if (this.props.dataDoc['simulationType'] != "Pulley") { - setXPosition(newX); - setDisplayXPosition(newX); + this.setState({xPosition: newX}); + this.props.dataDoc['positionXDisplay'] = newX } if (this.props.dataDoc['simulationType'] != "Suspension") { if (this.props.dataDoc['simulationType'] != "Pulley") { - setUpdatedStartPosX(newX); + this.setState({updatedStartPosX: newX}); } - setUpdatedStartPosY(newY); + this.setState({updatedStartPosY: newY}); } - setClickPositionX(e.clientX); - setClickPositionY(e.clientY); - setDisplayValues(); + this.setState({clickPositionX: e.clientX}); + this.setState({clickPositionY: e.clientY}); + this.setDisplayValues(); } }} onPointerUp={(e) => { - if (dragging) { + if (this.state.dragging) { e.preventDefault(); if ( this.props.dataDoc['simulationType'] != "Pendulum" && this.props.dataDoc['simulationType'] != "Suspension" ) { - resetEverything(); + this.resetEverything(); } - setDragging(false); - let newY = yPosition + e.clientY - clickPositionY; - if (newY > yMax - 2 * radius - 10) { - newY = yMax - 2 * radius - 10; + this.setState({dragging: false}); + let newY = this.state.yPosition + e.clientY - this.state.clickPositionY; + if (newY > this.props.yMax - 2 * this.props.radius - 10) { + newY = this.props.yMax - 2 * this.props.radius - 10; } else if (newY < 10) { newY = 10; } - let newX = xPosition + e.clientX - clickPositionX; - if (newX > xMax - 2 * radius - 10) { - newX = xMax - 2 * radius - 10; + let newX = this.state.xPosition + e.clientX - this.state.clickPositionX; + if (newX > this.props.xMax - 2 * this.props.radius - 10) { + newX = this.props.xMax - 2 * this.props.radius - 10; } else if (newX < 10) { newX = 10; } if (this.props.dataDoc['simulationType'] == "Spring") { - setSpringStartLength(newY); + this.props.dataDoc.springStartLength = newY } if (this.props.dataDoc['simulationType'] == "Suspension") { - let x1rod = (xMax + xMin) / 2 - radius - yMin - 200; - let x2rod = (xMax + xMin) / 2 + yMin + 200 + radius; - let deltaX1 = xPosition + radius - x1rod; - let deltaX2 = x2rod - (xPosition + radius); - let deltaY = yPosition + radius; + let x1rod = (this.props.xMax + this.props.xMin) / 2 - this.props.radius - this.props.yMin - 200; + let x2rod = (this.props.xMax + this.props.xMin) / 2 + this.props.yMin + 200 + this.props.radius; + let deltaX1 = this.state.xPosition + this.props.radius - x1rod; + let deltaX2 = x2rod - (this.state.xPosition + this.props.radius); + let deltaY = this.state.yPosition + this.props.radius; let dir1T = Math.PI - Math.atan(deltaY / deltaX1); let dir2T = Math.atan(deltaY / deltaX2); let tensionMag2 = - (mass * Math.abs(gravity)) / + (this.props.mass * Math.abs(this.props.gravity)) / ((-Math.cos(dir2T) / Math.cos(dir1T)) * Math.sin(dir1T) + Math.sin(dir2T)); let tensionMag1 = @@ -1004,7 +1001,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { }; const grav: IForce = { description: "Gravity", - magnitude: mass * Math.abs(gravity), + magnitude: this.props.mass * Math.abs(this.props.gravity), directionInDegrees: 270, component: false, }; @@ -1013,8 +1010,8 @@ export default class Weight extends React.Component<IWeightProps, IState> { } }} > - <div className="weight" style={weightStyle}> - <p className="weightLabel">{mass} kg</p> + <div className="weight" style={this.weightStyle}> + <p className="weightLabel">{this.props.mass} kg</p> </div> </div> {this.props.dataDoc['simulationType'] == "Spring" && ( @@ -1028,7 +1025,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { zIndex: -2, }} > - <svg width={xMax + "px"} height={window.innerHeight + "px"}> + <svg width={this.props.xMax + "px"} height={window.innerHeight + "px"}> {[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].map((val) => { const count = 10; let xPos1; @@ -1036,14 +1033,14 @@ export default class Weight extends React.Component<IWeightProps, IState> { let xPos2; let yPos2; if (val % 2 == 0) { - xPos1 = xPosition + radius - 20; - xPos2 = xPosition + radius + 20; + xPos1 = this.state.xPosition + this.props.radius - 20; + xPos2 = this.state.xPosition + this.props.radius + 20; } else { - xPos1 = xPosition + radius + 20; - xPos2 = xPosition + radius - 20; + xPos1 = this.state.xPosition + this.props.radius + 20; + xPos2 = this.state.xPosition + this.props.radius - 20; } - yPos1 = (val * yPosition) / count; - yPos2 = ((val + 1) * yPosition) / count; + yPos1 = (val * this.state.yPosition) / count; + yPos2 = ((val + 1) * this.state.yPosition) / count; return ( <line key={val} @@ -1070,11 +1067,11 @@ export default class Weight extends React.Component<IWeightProps, IState> { zIndex: -1, }} > - <svg width={xMax + "px"} height={window.innerHeight + "px"}> + <svg width={this.props.xMax + "px"} height={window.innerHeight + "px"}> <circle - cx={(xMax + xMin) / 2} - cy={radius} - r={radius * 1.5} + cx={(this.props.xMax + this.props.xMin) / 2} + cy={this.props.radius} + r={this.props.radius * 1.5} fill={"#808080"} /> </svg> @@ -1091,12 +1088,12 @@ export default class Weight extends React.Component<IWeightProps, IState> { zIndex: -2, }} > - <svg width={xMax + "px"} height={window.innerHeight + "px"}> + <svg width={this.props.xMax + "px"} height={window.innerHeight + "px"}> <line - x1={xPosition + radius} - y1={yPosition + radius} - x2={xPosition + radius} - y2={yMin} + x1={this.state.xPosition + this.props.radius} + y1={this.state.yPosition + this.props.radius} + x2={this.state.xPosition + this.props.radius} + y2={this.props.yMin} stroke={"#deb887"} strokeWidth="10" /> @@ -1114,12 +1111,12 @@ export default class Weight extends React.Component<IWeightProps, IState> { zIndex: -2, }} > - <svg width={xMax + "px"} height={window.innerHeight + "px"}> + <svg width={this.props.xMax + "px"} height={window.innerHeight + "px"}> <line - x1={xPosition + radius} - y1={yPosition + radius} - x2={(xMax + xMin) / 2 - radius - yMin - 200} - y2={yMin} + x1={this.state.xPosition + this.props.radius} + y1={this.state.yPosition + this.props.radius} + x2={(this.props.xMax + this.props.xMin) / 2 - this.props.radius - this.props.yMin - 200} + y2={this.props.yMin} stroke={"#deb887"} strokeWidth="10" /> @@ -1128,17 +1125,17 @@ export default class Weight extends React.Component<IWeightProps, IState> { style={{ position: "absolute", zIndex: 10, - left: (xMax + xMin) / 2 - radius - yMin - 200 + 80 + "px", + left: (this.props.xMax + this.props.xMin) / 2 - this.props.radius - this.props.yMin - 200 + 80 + "px", top: 10 + "px", - backgroundColor: labelBackgroundColor, + backgroundColor: this.labelBackgroundColor, }} > {Math.round( ((Math.atan( - (yPosition + radius) / - (xPosition + - radius - - ((xMax + xMin) / 2 - radius - yMin - 200)) + (this.state.yPosition + this.props.radius) / + (this.state.xPosition + + this.props.radius - + ((this.props.xMax + this.props.xMin) / 2 - this.props.radius - this.props.yMin - 200)) ) * 180) / Math.PI) * @@ -1159,12 +1156,12 @@ export default class Weight extends React.Component<IWeightProps, IState> { zIndex: -2, }} > - <svg width={xMax + "px"} height={window.innerHeight + "px"}> + <svg width={this.props.xMax + "px"} height={window.innerHeight + "px"}> <line - x1={xPosition + radius} - y1={yPosition + radius} - x2={(xMax + xMin) / 2 + yMin + 200 + radius} - y2={yMin} + x1={this.state.xPosition + this.props.radius} + y1={this.state.yPosition + this.props.radius} + x2={(this.props.xMax + this.props.xMin) / 2 + this.props.yMin + 200 + this.props.radius} + y2={this.props.yMin} stroke={"#deb887"} strokeWidth="10" /> @@ -1174,19 +1171,19 @@ export default class Weight extends React.Component<IWeightProps, IState> { style={{ position: "absolute", zIndex: 10, - left: (xMax + xMin) / 2 + yMin + 200 + radius - 80 + "px", + left: (this.props.xMax + this.props.xMin) / 2 + this.props.yMin + 200 + this.props.radius - 80 + "px", top: 10 + "px", - backgroundColor: labelBackgroundColor, + backgroundColor: this.labelBackgroundColor, }} > {Math.round( ((Math.atan( - (yPosition + radius) / - ((xMax + xMin) / 2 + - yMin + + (this.state.yPosition + this.props.radius) / + ((this.props.xMax + this.props.xMin) / 2 + + this.props.yMin + 200 + - radius - - (xPosition + radius)) + this.props.radius - + (this.state.xPosition + this.props.radius)) ) * 180) / Math.PI) * @@ -1207,12 +1204,12 @@ export default class Weight extends React.Component<IWeightProps, IState> { zIndex: -2, }} > - <svg width={xMax + "px"} height={window.innerHeight + "px"}> + <svg width={this.props.xMax + "px"} height={window.innerHeight + "px"}> <line - x1={xPosition + radius} - y1={yPosition + radius} - x2={(xMin + xMax) / 2} - y2={(yMin + yMax) / 2} + x1={this.state.xPosition + this.props.radius} + y1={this.state.yPosition + this.props.radius} + x2={(this.props.xMin + this.props.xMax) / 2} + y2={(this.props.yMin + this.props.yMax) / 2} stroke={"#deb887"} strokeWidth="10" /> @@ -1230,39 +1227,39 @@ export default class Weight extends React.Component<IWeightProps, IState> { zIndex: -2, }} > - <svg width={xMax + "px"} height={window.innerHeight + "px"}> + <svg width={this.props.xMax + "px"} height={window.innerHeight + "px"}> <line - x1={xPosition + radius} - y1={yPosition + radius} - x2={xMax / 2} + x1={this.state.xPosition + this.props.radius} + y1={this.state.yPosition + this.props.radius} + x2={this.props.xMax / 2} y2={-5} stroke={"#deb887"} strokeWidth="10" /> </svg> - {!dragging && ( + {!this.state.dragging && ( <div> <p style={{ position: "absolute", zIndex: 5, - left: xPosition + "px", - top: yPosition - 70 + "px", - backgroundColor: labelBackgroundColor, + left: this.state.xPosition + "px", + top: this.state.yPosition - 70 + "px", + backgroundColor: this.labelBackgroundColor, }} > - {Math.round(pendulumLength)} m + {Math.round(this.props.pendulumLength)} m </p> <p style={{ position: "absolute", zIndex: -1, - left: xMax / 2 + "px", + left: this.props.xMax / 2 + "px", top: 30 + "px", - backgroundColor: labelBackgroundColor, + backgroundColor: this.labelBackgroundColor, }} > - {Math.round(pendulumAngle * 100) / 100}° + {Math.round(this.props.pendulumAngle * 100) / 100}° </p> </div> )} @@ -1273,8 +1270,8 @@ export default class Weight extends React.Component<IWeightProps, IState> { <div style={{ position: "absolute", left: "0", top: "0", zIndex: -5 }} > - <svg width={xMax + "px"} height={yMax + "px"}> - <polygon points={coordinates} style={{ fill: "burlywood" }} /> + <svg width={this.props.xMax + "px"} height={this.props.yMax + "px"}> + <polygon points={this.state.coordinates} style={{ fill: "burlywood" }} /> </svg> </div> @@ -1282,18 +1279,18 @@ export default class Weight extends React.Component<IWeightProps, IState> { style={{ position: "absolute", zIndex: 500, - left: Math.round(xMax * 0.5 - 200 + wedgeWidth - 80) + "px", + left: Math.round(this.props.xMax * 0.5 - 200 + this.props.wedgeWidth - 80) + "px", top: Math.round(window.innerHeight * 0.8 - 40) + "px", }} > {Math.round( - ((Math.atan(wedgeHeight / wedgeWidth) * 180) / Math.PI) * 100 + ((Math.atan(this.props.wedgeHeight / this.props.wedgeWidth) * 180) / Math.PI) * 100 ) / 100} ° </p> </div> )} - {!dragging && showAcceleration && ( + {!this.state.dragging && this.props.showAcceleration && ( <div> <div style={{ @@ -1304,7 +1301,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { top: 0, }} > - <svg width={xMax + "px"} height={window.innerHeight + "px"}> + <svg width={this.props.xMax + "px"} height={window.innerHeight + "px"}> <defs> <marker id="accArrow" @@ -1319,10 +1316,10 @@ export default class Weight extends React.Component<IWeightProps, IState> { </marker> </defs> <line - x1={xPosition + radius} - y1={yPosition + radius} - x2={xPosition + radius + getNewAccelerationX(updatedForces) * 7} - y2={yPosition + radius + getNewAccelerationY(updatedForces) * 7} + x1={this.state.xPosition + this.props.radius} + y1={this.state.yPosition + this.props.radius} + x2={this.state.xPosition + this.props.radius + this.getNewAccelerationX(this.props.updatedForces) * 7} + y2={this.state.yPosition + this.props.radius + this.getNewAccelerationY(this.props.updatedForces) * 7} stroke={"green"} strokeWidth="5" markerEnd="url(#accArrow)" @@ -1332,15 +1329,15 @@ export default class Weight extends React.Component<IWeightProps, IState> { style={{ pointerEvents: "none", position: "absolute", - left: xPosition + radius + xAccel * 3 + 25 + "px", - top: yPosition + radius + yAccel * 3 + 70 + "px", + left: this.state.xPosition + this.props.radius + this.state.xAccel * 3 + 25 + "px", + top: this.state.yPosition + this.props.radius + this.state.yAccel * 3 + 70 + "px", zIndex: -1, lineHeight: 0.5, }} > <p> {Math.round( - 100 * Math.sqrt(xAccel * xAccel + yAccel * yAccel) + 100 * Math.sqrt(this.state.xAccel * this.state.xAccel + this.state.yAccel * this.state.yAccel) ) / 100}{" "} m/s <sup>2</sup> @@ -1349,7 +1346,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { </div> </div> )} - {!dragging && showVelocity && ( + {!this.state.dragging && this.props.showVelocity && ( <div> <div style={{ @@ -1360,7 +1357,7 @@ export default class Weight extends React.Component<IWeightProps, IState> { top: 0, }} > - <svg width={xMax + "px"} height={window.innerHeight + "px"}> + <svg width={this.props.xMax + "px"} height={window.innerHeight + "px"}> <defs> <marker id="velArrow" @@ -1375,10 +1372,10 @@ export default class Weight extends React.Component<IWeightProps, IState> { </marker> </defs> <line - x1={xPosition + radius} - y1={yPosition + radius} - x2={xPosition + radius + xVelocity * 3} - y2={yPosition + radius + yVelocity * 3} + x1={this.state.xPosition + this.props.radius} + y1={this.state.yPosition + this.props.radius} + x2={this.state.xPosition + this.props.radius + this.state.xVelocity * 3} + y2={this.state.yPosition + this.props.radius + this.state.yVelocity * 3} stroke={"blue"} strokeWidth="5" markerEnd="url(#velArrow)" @@ -1388,8 +1385,8 @@ export default class Weight extends React.Component<IWeightProps, IState> { style={{ pointerEvents: "none", position: "absolute", - left: xPosition + radius + xVelocity * 3 + 25 + "px", - top: yPosition + radius + yVelocity * 3 + "px", + left: this.state.xPosition + this.props.radius + this.state.xVelocity * 3 + 25 + "px", + top: this.state.yPosition + this.props.radius + this.state.yVelocity * 3 + "px", zIndex: -1, lineHeight: 0.5, }} @@ -1398,8 +1395,8 @@ export default class Weight extends React.Component<IWeightProps, IState> { {Math.round( 100 * Math.sqrt( - displayXVelocity * displayXVelocity + - displayYVelocity * displayYVelocity + this.props.displayXVelocity * this.props.displayXVelocity + + this.props.displayYVelocity * this.props.displayYVelocity ) ) / 100}{" "} m/s @@ -1630,5 +1627,5 @@ export default class Weight extends React.Component<IWeightProps, IState> { ); })} </div> - ); + } }; |