mirror of
https://github.com/Noratrieb/redox.git
synced 2026-01-14 08:15:03 +01:00
button
This commit is contained in:
parent
10ca04b98e
commit
add4166030
11 changed files with 157 additions and 14 deletions
|
|
@ -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;
|
||||
|
|
@ -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};
|
||||
|
|
|
|||
|
|
@ -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]));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
24
src/draw/ui/Button.ts
Normal 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;
|
||||
8
src/draw/ui/MouseChargeButton.ts
Normal file
8
src/draw/ui/MouseChargeButton.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
5
src/draw/ui/PauseButton.ts
Normal file
5
src/draw/ui/PauseButton.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import Button from "./Button";
|
||||
|
||||
export default class PauseButton extends Button {
|
||||
|
||||
}
|
||||
38
src/draw/ui/UI.ts
Normal file
38
src/draw/ui/UI.ts
Normal 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))
|
||||
}
|
||||
44
src/draw/ui/UIComponent.ts
Normal file
44
src/draw/ui/UIComponent.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue