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 {draw, init, update} from "./draw/MainDraw";
import {canvasClick, draw, init, update, canvasMouseMove} from "./draw/MainDraw";
let CANVAS_WIDTH = 1500;
let CANVAS_HEIGHT = 700;
@ -24,10 +24,11 @@ function App() {
return (
<div>
<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>
);
}
export {CANVAS_WIDTH, CANVAS_HEIGHT};
export default App;
export default App;

View file

@ -1,17 +1,23 @@
import {rect} from "./Shapes";
import {updateParticles, particlesInit, drawParticles} from "./Particles";
import {drawParticles, initParticles, updateParticles} from "./Particles";
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 Ctx = CanvasRenderingContext2D;
type MouseEvt = MouseEvent<HTMLCanvasElement>;
function init() {
particlesInit();
initParticles();
initUI();
}
function draw(ctx: Ctx) {
rect(ctx, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, "lightgrey");
drawParticles(ctx);
drawUI(ctx);
requestAnimationFrame(() => draw(ctx));
}
@ -19,5 +25,23 @@ function update() {
updateParticles();
}
export type {Ctx, FillStyle};
export {update, init, draw};
function canvasMouseMove(e: MouseEvt) {
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[] = [];
export function particlesInit() {
export function initParticles() {
const chargeToMass = [0.1, 1, 10];
for (let i = 0; i < 200; i++) {
const charge = Math.random() < 0.3 ? 0 : Math.random() < 0.5 ? 1 : -1;
particles.push(new Particle(new Vector(
Math.random() * (CANVAS_WIDTH - 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 SimObject from "./Drawable";
import SimObject from "./SimObject";
import {Ctx, FillStyle} from "../MainDraw";
import {circle} from "../Shapes";
import {CANVAS_HEIGHT, CANVAS_WIDTH} from "../../App";
@ -12,8 +12,8 @@ const RANDOM_ACCELERATION = 2;
export default class Particle implements SimObject {
private _position: Vector;
private _velocity: Vector;
private _mass: number;
private _charge: number;
private readonly _mass: number;
private readonly _charge: number;
constructor(position: Vector, charge = 0, mass = 1) {
this._position = position;

View file

@ -39,4 +39,4 @@ export default class Vector {
const factor = this.magnitude();
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;
}
}