React
by Lexogram
HTML
<div id="app"></div>
CSS
html, body {
height: 100vh;
}
body {
margin: 0;
font-size: 20vmin;
}
* {
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
span.selected {
background-color: #9c9;
opacity: 0.5;
}
span.removed {
opacity: 0.05;
}
div#board{
background-color: #efe;
height: 100vh;
}
div[class|="row"] {
display: flex;
justify-content: center;
}
@keyframes ants {
from { stroke-dashoffset: 0; }
to { stroke-dashoffset: 10; }
}
@keyframes tsan {
from { stroke-dashoffset: -5; }
to { stroke-dashoffset: 5; }
}
React
class Board extends React.Component {
_getClassName(id) {
let className = ""
if (this.props.removed.indexOf(id) < 0) {
if (this.props.selected.indexOf(id) < 0) {
// This span is neither selected nor removed. Leave it alone
} else {
className = "selected"
}
} else {
className = "removed"
}
return className
}
render () {
const rows = this.props.data.map((rowData, rowIndex) => {
const cells = rowData.map((cellData, cellIndex) => {
const id = "cell-" + rowIndex + "-" + cellIndex
const className = this._getClassName(id)
return (
<span
key={cellIndex}
id={id}
className={className}
>
{cellData}
</span>
)
})
return (
<div
key={rowIndex}
className={"row-" + rowIndex}
>
{cells}
</div>
)
})
return (
<div
id="board"
onMouseDown={this.props.drag}
>
{rows}
</div>
)
}
}
const Ants = ({ rect }) => {
if (!rect) {
console.log("No ants")
return ""
}
const svg = (
<svg
width="100vw"
height="100vh"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
style={{
position: "fixed"
, top: 0
, left: 0
, pointerEvents: "none"
}}
>
<rect
x={rect.x}
y={rect.y}
width={rect.width}
height={rect.height}
stroke="#000"
strokeWidth="1"
strokeOpacity="0.75"
strokeDasharray="5,5"
style={{ animation: "ants 1s linear infinite" }}
fill="#030"
fillOpacity="0.1"
/>
<rect
x={rect.x}
y={rect.y}
width={rect.width}
height={rect.height}
stroke="#fff"
strokeWidth="1"
strokeOpacity="0.75"
...