This commit is contained in:
nora 2021-06-17 14:03:36 +02:00
parent 10ca04b98e
commit add4166030
11 changed files with 157 additions and 14 deletions

View file

@ -1,5 +1,5 @@
import React, {useEffect, useRef} from 'react'; import React, {useEffect, useRef} from 'react';
import {draw, init, update} from "./draw/MainDraw"; import {canvasClick, draw, init, update, canvasMouseMove} from "./draw/MainDraw";
let CANVAS_WIDTH = 1500; let CANVAS_WIDTH = 1500;
let CANVAS_HEIGHT = 700; let CANVAS_HEIGHT = 700;
@ -24,10 +24,11 @@ function App() {
return ( return (
<div> <div>
<h1>Redox</h1> <h1>Redox</h1>
<canvas ref={canvasRef} height={CANVAS_HEIGHT} width={CANVAS_WIDTH}/> <canvas onMouseMove={canvasMouseMove} onClick={canvasClick} ref={canvasRef} height={CANVAS_HEIGHT}
width={CANVAS_WIDTH}/>
</div> </div>
); );
} }
export {CANVAS_WIDTH, CANVAS_HEIGHT}; export {CANVAS_WIDTH, CANVAS_HEIGHT};
export default App; export default App;

View file

@ -1,17 +1,23 @@
import {rect} from "./Shapes"; import {rect} from "./Shapes";
import {updateParticles, particlesInit, drawParticles} from "./Particles"; import {drawParticles, initParticles, updateParticles} from "./Particles";
import {CANVAS_HEIGHT, CANVAS_WIDTH} from "../App"; import {CANVAS_HEIGHT, CANVAS_WIDTH} from "../App";
import {MouseEvent} from "react";
import Vector from "./classes/Vector";
import {drawUI, handleUIMouseMove, handleUIClick, initUI} from "./ui/UI";
type FillStyle = string | CanvasGradient | CanvasPattern; type FillStyle = string | CanvasGradient | CanvasPattern;
type Ctx = CanvasRenderingContext2D; type Ctx = CanvasRenderingContext2D;
type MouseEvt = MouseEvent<HTMLCanvasElement>;
function init() { function init() {
particlesInit(); initParticles();
initUI();
} }
function draw(ctx: Ctx) { function draw(ctx: Ctx) {
rect(ctx, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, "lightgrey"); rect(ctx, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, "lightgrey");
drawParticles(ctx); drawParticles(ctx);
drawUI(ctx);
requestAnimationFrame(() => draw(ctx)); requestAnimationFrame(() => draw(ctx));
} }
@ -19,5 +25,23 @@ function update() {
updateParticles(); updateParticles();
} }
export type {Ctx, FillStyle}; function canvasMouseMove(e: MouseEvt) {
export {update, init, draw}; console.log(getMousePos(e))
handleUIMouseMove(getMousePos(e));
}
function canvasClick(e: MouseEvt) {
console.log(getMousePos(e))
handleUIClick(e);
}
function getMousePos(evt: MouseEvt): Vector {
const rect = evt.currentTarget.getBoundingClientRect();
return new Vector(
evt.clientX - rect.left,
evt.clientY - rect.top
);
}
export type {Ctx, FillStyle, MouseEvt};
export {update, init, draw, canvasClick, canvasMouseMove};

View file

@ -5,15 +5,14 @@ import {CANVAS_HEIGHT, CANVAS_WIDTH} from "../App";
const particles: Particle[] = []; const particles: Particle[] = [];
export function initParticles() {
export function particlesInit() {
const chargeToMass = [0.1, 1, 10]; const chargeToMass = [0.1, 1, 10];
for (let i = 0; i < 200; i++) { for (let i = 0; i < 200; i++) {
const charge = Math.random() < 0.3 ? 0 : Math.random() < 0.5 ? 1 : -1; const charge = Math.random() < 0.3 ? 0 : Math.random() < 0.5 ? 1 : -1;
particles.push(new Particle(new Vector( particles.push(new Particle(new Vector(
Math.random() * (CANVAS_WIDTH - 100) + 50, Math.random() * (CANVAS_WIDTH - 100) + 50,
Math.random() * (CANVAS_HEIGHT - 100) + 50 Math.random() * (CANVAS_HEIGHT - 100) + 50
), charge, chargeToMass[charge - 1])); ), charge, chargeToMass[charge + 1]));
} }
} }

View file

@ -1,5 +1,5 @@
import Vector from "./Vector"; import Vector from "./Vector";
import SimObject from "./Drawable"; import SimObject from "./SimObject";
import {Ctx, FillStyle} from "../MainDraw"; import {Ctx, FillStyle} from "../MainDraw";
import {circle} from "../Shapes"; import {circle} from "../Shapes";
import {CANVAS_HEIGHT, CANVAS_WIDTH} from "../../App"; import {CANVAS_HEIGHT, CANVAS_WIDTH} from "../../App";
@ -12,8 +12,8 @@ const RANDOM_ACCELERATION = 2;
export default class Particle implements SimObject { export default class Particle implements SimObject {
private _position: Vector; private _position: Vector;
private _velocity: Vector; private _velocity: Vector;
private _mass: number; private readonly _mass: number;
private _charge: number; private readonly _charge: number;
constructor(position: Vector, charge = 0, mass = 1) { constructor(position: Vector, charge = 0, mass = 1) {
this._position = position; this._position = position;

View file

@ -39,4 +39,4 @@ export default class Vector {
const factor = this.magnitude(); const factor = this.magnitude();
return new Vector(this.x / factor, this.y / factor); return new Vector(this.x / factor, this.y / factor);
} }
} }

24
src/draw/ui/Button.ts Normal file
View file

@ -0,0 +1,24 @@
import {Ctx} from "../MainDraw";
import Vector from "../classes/Vector";
import {rect} from "../Shapes";
import UIComponent from "./UIComponent";
class Button extends UIComponent {
private _clicked: boolean;
constructor(pos: Vector, size: Vector) {
super(pos, size);
this._clicked = false;
}
public draw(ctx: Ctx) {
const color = this._isHovered ? "red" : "grey";
rect(ctx, this._position.x, this._position.y, this._size.x, this._size.y, color);
}
public click() {
this._clicked = true;
}
}
export default Button;

View file

@ -0,0 +1,8 @@
import Button from "./Button";
import Vector from "../classes/Vector";
export default class MouseChargeButton extends Button {
constructor(pos: Vector, size: Vector) {
super(pos, size);
}
}

View file

@ -0,0 +1,5 @@
import Button from "./Button";
export default class PauseButton extends Button {
}

38
src/draw/ui/UI.ts Normal file
View file

@ -0,0 +1,38 @@
import {Ctx, MouseEvt} from "../MainDraw";
import Vector from "../classes/Vector";
import Button from "./Button";
import {CANVAS_WIDTH} from "../../App";
import UIComponent from "./UIComponent";
const uiComponents: UIComponent[] = [];
export function initUI() {
uiComponents.push(new Button(
new Vector(CANVAS_WIDTH - 60, 10),
new Vector(50, 50),
));
uiComponents.push(new Button(
new Vector(CANVAS_WIDTH - 60, 70),
new Vector(50, 50)
));
}
export function handleUIMouseMove(coords: Vector) {
for (let component of uiComponents) {
const isInside = component.isInside(coords);
if (isInside && !component.wasHovered) {
component.onHoverEnter();
} else if (!isInside && component.wasHovered) {
component.onHoverLeave();
}
component.wasHovered = isInside;
}
}
export function handleUIClick(e: MouseEvt) {
}
export function drawUI(ctx: Ctx) {
uiComponents.forEach(uic => uic.draw(ctx))
}

View file

@ -0,0 +1,44 @@
import {Ctx} from "../MainDraw";
import Vector from "../classes/Vector";
export default abstract class UIComponent {
protected _size: Vector;
protected _position: Vector;
protected _isHovered: boolean;
private _wasHovered: boolean;
protected constructor(pos: Vector, size: Vector) {
this._position = pos;
this._size = size;
this._wasHovered = false;
this._isHovered = false;
}
abstract draw(ctx: Ctx): void;
abstract click(): void;
onHoverEnter(): void {
this._isHovered = true;
}
onHoverLeave(): void {
this._isHovered = false;
}
get wasHovered(): boolean {
return this._wasHovered;
}
set wasHovered(wasHovered) {
this._wasHovered = wasHovered;
}
public isInside(coords: Vector): boolean {
return coords.x > this._position.x
&& coords.x < this._position.x + this._size.x
&& coords.y > this._position.y
&& coords.y < this._position.y + this._size.y;
}
}