Skip to content

Commit

Permalink
feat(rotate): add new way to rotate the led matrix
Browse files Browse the repository at this point in the history
closes #3
  • Loading branch information
ph1p committed Jan 8, 2023
1 parent 14d66bc commit fceb4ef
Show file tree
Hide file tree
Showing 10 changed files with 1,543 additions and 1,708 deletions.
1,749 changes: 834 additions & 915 deletions frontend/package-lock.json

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
},
"devDependencies": {
"@gfx/zopfli": "^1.0.15",
"@preact/preset-vite": "^2.4.0",
"@preact/preset-vite": "^2.5.0",
"@vanilla-extract/css": "^1.9.2",
"@vanilla-extract/vite-plugin": "^3.7.0",
"sass": "^1.56.1",
"terser": "^5.15.1",
"typescript": "^4.9.3",
"vite": "^3.2.4",
"vite-plugin-singlefile": "^0.13.1"
"sass": "^1.57.1",
"terser": "^5.16.1",
"typescript": "^4.9.4",
"vite": "^4.0.4",
"vite-plugin-singlefile": "^0.13.2"
}
}
1 change: 0 additions & 1 deletion frontend/src/app.css.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { style } from '@vanilla-extract/css';
import { multiplier } from './main.css';

export const wrapper = style({
display: 'grid',
Expand Down
44 changes: 20 additions & 24 deletions frontend/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { useEffect, useState } from 'preact/hooks';
import { useMemo, useState } from 'preact/hooks';
import { ReadyState } from 'react-use-websocket/dist/lib/constants';
import { useWebSocket } from 'react-use-websocket/dist/lib/use-websocket';
import {
loadImageAndGetDataArray,
rotateArray,
rotateArrayByDegree,
} from './helpers';
import { loadImageAndGetDataArray, rotateArray } from './helpers';
import { MODE } from './types';
import { controlColumn, wrapper } from './app.css';
import { LedMatrix } from './components/LedMatrix';
Expand All @@ -22,6 +18,11 @@ export function App() {
const [leds, setLeds] = useState<number[]>([...new Array(256)].fill(0));
const [mode, setMode] = useState<MODE>(MODE.NONE);

const rotatedMatrix = useMemo(
() => rotateArray(indexMatrix, rotation),
[rotation, indexMatrix]
);

const { sendMessage, readyState } = useWebSocket(
`${
import.meta.env.PROD
Expand All @@ -46,14 +47,10 @@ export function App() {
setMode(Object.values(MODE)[json.mode as number]);
setRotation(json.rotation);

setIndexMatrix([
...rotateArrayByDegree(
[...new Array(256)].map((_, i) => i),
json.rotation
),
]);
setIndexMatrix([...new Array(256)].map((_, i) => i));

if (json.data) {
setLeds(rotateArrayByDegree(json.data, json.rotation));
setLeds(json.data);
}

break;
Expand All @@ -77,18 +74,17 @@ export function App() {
};

const rotate = (turnRight = false) => {
if (turnRight) {
setRotation(rotation + 90);
} else {
setRotation(rotation - 90);
}
let currentRotation = rotation;

if (rotation <= -360 || rotation >= 360) {
setRotation(0);
}
currentRotation = turnRight
? currentRotation > 3
? 1
: currentRotation + 1
: currentRotation <= 0
? 3
: currentRotation - 1;

setLeds((state: number[]) => rotateArray(state, turnRight));
setIndexMatrix((state: number[]) => rotateArray(state, turnRight));
setRotation(currentRotation);

sendMessage(
JSON.stringify({
Expand Down Expand Up @@ -151,7 +147,7 @@ export function App() {
<LedMatrix
disabled={mode !== MODE.NONE}
data={leds}
indexData={indexMatrix}
indexData={rotatedMatrix}
onSetLed={(data) => {
wsMessage('led', data);
}}
Expand Down
43 changes: 23 additions & 20 deletions frontend/src/components/LedMatrix.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,14 @@ export function LedMatrix(props: Props) {
const [isMouseDown, setMouseIsDown] = useState(false);

const setLed = (index: number) => {
const rotatedIndex = props.indexData[index];

const status = Number(!props.data[index]);
const newState = props.data.map((led, i) =>
i === index ? Number(status) : led
);

if (props.onSetLed) {
props.onSetLed({
index: rotatedIndex,
index,
status,
});
}
Expand All @@ -53,23 +51,28 @@ export function LedMatrix(props: Props) {
setMouseIsDown(false);
}}
>
{props.data.map((status, index) => (
<div
key={index}
className={ledWrapper}
onPointerDown={() => {
setLed(index);
setMouseIsDown(true);
}}
onPointerEnter={() => {
if (isMouseDown) {
setLed(index);
}
}}
>
<div className={`${ledInner} ${status ? 'active' : ''}`}></div>
</div>
))}
{props.data.map((_, index) => {
const rIndex = props.indexData[index];
return (
<div
key={rIndex}
className={ledWrapper}
onPointerDown={() => {
setLed(rIndex);
setMouseIsDown(true);
}}
onPointerEnter={() => {
if (isMouseDown) {
setLed(rIndex);
}
}}
>
<div
className={`${ledInner} ${props.data[rIndex] ? 'active' : ''}`}
></div>
</div>
);
})}
</div>
</div>
);
Expand Down
52 changes: 18 additions & 34 deletions frontend/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,46 +35,30 @@ export const loadImageAndGetDataArray = (cb: (data: number[]) => void) => {
};
};

export const rotateArrayByDegree = (data: number[], degree: number) => {
const numRotations = degree / 90;
const isRight = numRotations > 0;

[...new Array(Math.abs(numRotations))].forEach(() => {
data = rotateArray(data, isRight);
});

return data;
};

export const rotateArray = (matrix: number[], turnRight = false) => {
export const rotateArray = (matrix: number[], rotations: number) => {
const SIZE = 16;
const newState = [...matrix];
for (let i = 0; i < SIZE; i++) {
for (let j = i; j < SIZE; j++) {
let temp = newState[i * SIZE + j];
newState[i * SIZE + j] = newState[j * SIZE + i];
newState[j * SIZE + i] = temp;
}
}

for (let i = 0; i < SIZE; i++) {
let col1 = 0;
let col2 = SIZE - 1;
while (col1 < col2) {
let index1 = i * SIZE + col1;
let index2 = i * SIZE + col2;
if (!turnRight) {
index1 = col1 * SIZE + i;
index2 = col2 * SIZE + i;
}
const swap = (arr: number[], i: number, j: number) => {
const temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
};

let temp = newState[index1];
newState[index1] = newState[index2];
newState[index2] = temp;
col1++;
col2--;
for (let row = 0; row < SIZE / 2; row++) {
for (let col = row; col < SIZE - row - 1; col++) {
for (let r = 0; r < rotations; r++) {
swap(newState, row * SIZE + col, col * SIZE + (SIZE - 1 - row));
swap(
newState,
row * SIZE + col,
(SIZE - 1 - row) * SIZE + (SIZE - 1 - col)
);
swap(newState, row * SIZE + col, (SIZE - 1 - col) * SIZE + row);
}
}
}

return newState;
};

Expand Down
58 changes: 21 additions & 37 deletions include/screen.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,44 +10,28 @@ class Screen_
{
private:
Screen_() = default;
uint8_t defaultPositions[ROWS * COLS] = {
0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0, 0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0, 0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
int findPosition(uint8_t count);
void rotate();
uint8_t renderBuffer_[ROWS * COLS];
uint8_t positions[ROWS * COLS] = {
0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x30,
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x57, 0x56, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40,
0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60, 0x77, 0x76, 0x75, 0x74, 0x73, 0x72, 0x71, 0x70,
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x97, 0x96, 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0, 0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0,
0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xd7, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xd0, 0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0,
0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
uint8_t rotatedPositions[ROWS * COLS];
uint8_t rotatedRenderBuffer_[ROWS * COLS];
uint8_t cache[ROWS * COLS];
uint8_t positions[ROWS * COLS] = {
0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x4f, 0x4e, 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x61, 0x60, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x68, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x8f, 0x8e, 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0x87, 0x86, 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0xa7, 0xa6, 0xa5, 0xa4, 0xa3, 0xa2, 0xa1, 0xa0, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
0xaf, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9, 0xa8, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xcf, 0xce, 0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc8, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xc7, 0xc6, 0xc5, 0xc4, 0xc3, 0xc2, 0xc1, 0xc0, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};

public:
static Screen_ &getInstance();
Expand All @@ -59,14 +43,14 @@ class Screen_
int currentRotation;

void setRenderBuffer(const uint8_t *renderBuffer);
const uint8_t *getRenderBuffer() const;
uint8_t *getRenderBuffer();
uint8_t *getRotatedRenderBuffer();

void clear(bool rerender = true);
void drawLine(uint8_t line, bool isHorizontal);
void setPixel(uint8_t x, uint8_t y, uint8_t value);
void setPixelAtIndex(uint8_t index, uint8_t value);
void render();
void rotate(int degree = 90);
void loadFromStorage();
void persist();
void cacheCurrent();
Expand Down
Loading

0 comments on commit fceb4ef

Please sign in to comment.