components: rewrite layout with CSS Grid, add line drawing
This commit is contained in:
parent
6468f94c61
commit
9001deaf3a
@ -1,5 +1,9 @@
|
||||
.App {
|
||||
max-width: 80vw;
|
||||
max-height: 100vh;
|
||||
margin: 0 auto;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-rows: 1fr;
|
||||
grid-column-gap: 0;
|
||||
grid-row-gap: 0;
|
||||
}
|
||||
|
@ -8,8 +8,15 @@ import './App.scss';
|
||||
export default function App(): JSX.Element {
|
||||
return (
|
||||
<div className="App">
|
||||
<Logo />
|
||||
<Board />
|
||||
<div />
|
||||
<div>
|
||||
<Logo />
|
||||
<Board
|
||||
numRows={10}
|
||||
numCols={10}
|
||||
/>
|
||||
</div>
|
||||
<div />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -1,24 +1,56 @@
|
||||
$LetterBaseColor: ghostwhite;
|
||||
$LetterHoverColor: #d9d9ff;
|
||||
|
||||
.Container {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.Content, .Overlay {
|
||||
grid-area: 1 / 1;
|
||||
}
|
||||
|
||||
.Overlay {
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.Canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.Line {
|
||||
stroke: red;
|
||||
stroke-width: 10px;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.Board {
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
grid-template-columns: repeat(8, 8vw);
|
||||
column-gap: 15px;
|
||||
row-gap: 15px;
|
||||
user-select: none;
|
||||
text-align: center;
|
||||
grid-template-columns: repeat(10, 60px);
|
||||
}
|
||||
|
||||
.Letter {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
font-weight: bold;
|
||||
font-size: larger;
|
||||
padding: 20px;
|
||||
background: ghostwhite;
|
||||
border-radius: 1rem;
|
||||
border-color: #e5e5ea;
|
||||
font-size: x-large;
|
||||
font-family: monospace;
|
||||
padding: 15px;
|
||||
background: $LetterBaseColor;
|
||||
text-align: center;
|
||||
border: 5px solid #e5e5ea;
|
||||
border-radius: 100%;
|
||||
color: brown;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: #e4e4ff;
|
||||
border-color: $LetterHoverColor;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-color: #8b8be5;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,48 +1,90 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import './Board.scss';
|
||||
|
||||
export default class Board extends React.Component {
|
||||
interface IBoardProps {
|
||||
numRows: number;
|
||||
numCols: number;
|
||||
}
|
||||
|
||||
static propTypes = {
|
||||
clickHandler: PropTypes.func,
|
||||
};
|
||||
type Position = [x: number, y: number];
|
||||
|
||||
genSquares() {
|
||||
let squares = [];
|
||||
for (let i = 0; i < 64; i++) {
|
||||
let x = String.fromCharCode(i % 8 + 65);
|
||||
let y = String.fromCharCode(i / 8 + 49);
|
||||
let letter = x + y;
|
||||
squares.push(
|
||||
<div
|
||||
id={letter}
|
||||
className="Letter"
|
||||
>
|
||||
{letter}
|
||||
</div>
|
||||
);
|
||||
interface IBoardState {
|
||||
board: string[][];
|
||||
isSelectingWord: boolean;
|
||||
startPos: Position;
|
||||
}
|
||||
|
||||
export default class Board extends React.Component<IBoardProps, IBoardState> {
|
||||
private line: React.RefObject<SVGLineElement>;
|
||||
private line_x1: string;
|
||||
private line_y1: string;
|
||||
|
||||
constructor(props: IBoardProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
board: Array(props.numCols).fill(Array(props.numRows).fill('·')),
|
||||
isSelectingWord: false,
|
||||
startPos: [0, 0],
|
||||
}
|
||||
return squares;
|
||||
|
||||
this.line = React.createRef();
|
||||
this.line_x1 = "0px";
|
||||
this.line_y1 = "0px";
|
||||
}
|
||||
|
||||
onMouseMove() {
|
||||
return 1;
|
||||
handleMouseDown(startPos: Position) {
|
||||
this.setState({...this.state, startPos, isSelectingWord: true});
|
||||
}
|
||||
|
||||
onMouseDown() {
|
||||
return 1;
|
||||
handleMouseUp(startPos: Position) {
|
||||
let [x, y] = startPos;
|
||||
this.line_x1 = `${y * 100}px`;
|
||||
this.line_y1 = `${x * 100}px`;
|
||||
|
||||
this.setState({...this.state, startPos, isSelectingWord: false});
|
||||
}
|
||||
|
||||
render() {
|
||||
handleMouseOver(currentPos: Position) {
|
||||
if (!this.state.isSelectingWord)
|
||||
return;
|
||||
}
|
||||
|
||||
render(): JSX.Element {
|
||||
let letters =
|
||||
this.state.board.map((ox, x) =>
|
||||
ox.map((s, y) =>
|
||||
<button
|
||||
key={`${x}${y}`}
|
||||
className="Letter"
|
||||
onMouseUp={() => this.handleMouseUp([x, y])}
|
||||
onMouseDown={() => this.handleMouseDown([x, y])}
|
||||
onMouseOver={() => this.handleMouseOver([x, y])}
|
||||
>
|
||||
{s}
|
||||
</button>
|
||||
));
|
||||
|
||||
return (
|
||||
<div
|
||||
className="Board"
|
||||
onMouseDown={this.onMouseDown}
|
||||
onMouseMove={this.onMouseMove}
|
||||
>
|
||||
{this.genSquares()}
|
||||
<div className="Container">
|
||||
<div className="Content">
|
||||
<div className="Board">
|
||||
{letters}
|
||||
</div>
|
||||
</div>
|
||||
<div className="Overlay">
|
||||
<svg className="Canvas">
|
||||
<line
|
||||
className="Line"
|
||||
ref={this.line}
|
||||
x1={this.line_x1}
|
||||
y1={this.line_y1}
|
||||
x2="0"
|
||||
y2="0"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user