diff --git a/src/App.tsx b/src/App.tsx
index bb2b6b4..719616a 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -15,7 +15,7 @@ function App() {
});
return (
-
+
{displayStore.displays.map((display) => {
return ;
diff --git a/src/components/display-list-container.tsx b/src/components/display-list-container.tsx
index f697e46..517db2b 100644
--- a/src/components/display-list-container.tsx
+++ b/src/components/display-list-container.tsx
@@ -1,15 +1,45 @@
-import { createEffect, createMemo, createSignal, on, ParentComponent } from 'solid-js';
+import {
+ createEffect,
+ createSignal,
+ onCleanup,
+ onMount,
+ ParentComponent,
+} from 'solid-js';
import { displayStore, setDisplayStore } from '../stores/display.store';
export const DisplayListContainer: ParentComponent = (props) => {
+ let root: HTMLElement;
const [olStyle, setOlStyle] = createSignal({
top: '0px',
left: '0px',
});
const [rootStyle, setRootStyle] = createSignal({
- width: '100%',
+ // width: '100%',
height: '100%',
});
+ const [bound, setBound] = createSignal({
+ left: 0,
+ top: 0,
+ right: 100,
+ bottom: 100,
+ });
+
+ const resetSize = () => {
+ const _bound = bound();
+
+ setDisplayStore({
+ viewScale: root.clientWidth / (_bound.right - _bound.left),
+ });
+
+ setOlStyle({
+ top: `${-_bound.top * displayStore.viewScale}px`,
+ left: `${-_bound.left * displayStore.viewScale}px`,
+ });
+
+ setRootStyle({
+ height: `${(_bound.bottom - _bound.top) * displayStore.viewScale}px`,
+ });
+ };
createEffect(() => {
const boundLeft = Math.min(0, ...displayStore.displays.map((display) => display.x));
@@ -23,22 +53,27 @@ export const DisplayListContainer: ParentComponent = (props) => {
...displayStore.displays.map((display) => display.y + display.height),
);
- setDisplayStore({
- viewScale: 1200 / (boundRight - boundLeft),
+ setBound({
+ left: boundLeft,
+ top: boundTop,
+ right: boundRight,
+ bottom: boundBottom,
+ });
+ let observer: ResizeObserver;
+ onMount(() => {
+ observer = new ResizeObserver(resetSize);
+ observer.observe(root);
});
- setOlStyle({
- top: `${-boundTop * displayStore.viewScale}px`,
- left: `${-boundLeft * displayStore.viewScale}px`,
- });
-
- setRootStyle({
- width: `${(boundRight - boundLeft) * displayStore.viewScale}px`,
- height: `${(boundBottom - boundTop) * displayStore.viewScale}px`,
+ onCleanup(() => {
+ observer?.unobserve(root);
});
});
+
+ createEffect(() => {});
+
return (
-
+
{props.children}
diff --git a/src/components/display-view.tsx b/src/components/display-view.tsx
index 088ae81..48ef2ac 100644
--- a/src/components/display-view.tsx
+++ b/src/components/display-view.tsx
@@ -16,18 +16,29 @@ export const DisplayView: Component = (props) => {
const style = createMemo(() => ({
top: `${props.display.y * displayStore.viewScale}px`,
left: `${props.display.x * displayStore.viewScale}px`,
+ height: `${size().height}px`,
+ width: `${size().width}px`,
}));
return (
-
+
+ Test
+ Test
+ Test
+ Test
);
};
diff --git a/src/components/screen-view.tsx b/src/components/screen-view.tsx
index f3a2df3..0216171 100644
--- a/src/components/screen-view.tsx
+++ b/src/components/screen-view.tsx
@@ -13,9 +13,7 @@ import {
type ScreenViewProps = {
displayId: number;
- height: number;
- width: number;
-} & Omit, 'height' | 'width'>;
+} & JSX.HTMLAttributes;
async function subscribeScreenshotUpdate(displayId: number) {
await invoke('subscribe_encoded_screenshot_updated', {
@@ -26,7 +24,63 @@ async function subscribeScreenshotUpdate(displayId: number) {
export const ScreenView: Component = (props) => {
const [localProps, rootProps] = splitProps(props, ['displayId']);
let canvas: HTMLCanvasElement;
+ let root: HTMLDivElement;
const [ctx, setCtx] = createSignal(null);
+ const [drawInfo, setDrawInfo] = createSignal({
+ drawX: 0,
+ drawY: 0,
+ drawWidth: 0,
+ drawHeight: 0,
+ });
+ const [imageData, setImageData] = createSignal<{
+ buffer: Uint8ClampedArray;
+ width: number;
+ height: number;
+ } | null>(null);
+
+ const resetSize = () => {
+ const aspectRatio = canvas.width / canvas.height;
+
+ const drawWidth = Math.round(
+ Math.min(root.clientWidth, root.clientHeight * aspectRatio),
+ );
+ const drawHeight = Math.round(
+ Math.min(root.clientHeight, root.clientWidth / aspectRatio),
+ );
+
+ const drawX = Math.round((root.clientWidth - drawWidth) / 2);
+ const drawY = Math.round((root.clientHeight - drawHeight) / 2);
+
+ setDrawInfo({
+ drawX,
+ drawY,
+ drawWidth,
+ drawHeight,
+ });
+
+ canvas.width = root.clientWidth;
+ canvas.height = root.clientHeight;
+
+ draw(true);
+ };
+
+ const draw = (cached: boolean = false) => {
+ const { drawX, drawY, drawWidth, drawHeight } = drawInfo();
+
+ let _ctx = ctx();
+ let raw = imageData();
+ if (_ctx && raw) {
+ _ctx.clearRect(0, 0, canvas.width, canvas.height);
+ if (cached) {
+ for (let i = 3; i < raw.buffer.length; i += 8) {
+ raw.buffer[i] = Math.floor(raw.buffer[i] * 0.7);
+ }
+ }
+ const img = new ImageData(raw.buffer, raw.width, raw.height);
+ _ctx.putImageData(img, drawX, drawY);
+ }
+ };
+
createEffect(() => {
const unlisten = listen<{
base64_image: string;
@@ -34,9 +88,10 @@ export const ScreenView: Component = (props) => {
height: number;
width: number;
}>('encoded-screenshot-updated', (event) => {
+ const { drawWidth, drawHeight } = drawInfo();
if (event.payload.display_id === localProps.displayId) {
const url = convertFileSrc(
- `displays/${localProps.displayId}?width=${canvas.width}&height=${canvas.height}`,
+ `displays/${localProps.displayId}?width=${drawWidth}&height=${drawHeight}`,
'ambient-light',
);
fetch(url, {
@@ -44,18 +99,17 @@ export const ScreenView: Component = (props) => {
})
.then((res) => res.body?.getReader().read())
.then((buffer) => {
- console.log(buffer?.value?.length);
-
- let _ctx = ctx();
- if (_ctx && buffer?.value) {
- _ctx.clearRect(0, 0, canvas.width, canvas.height);
- const img = new ImageData(
- new Uint8ClampedArray(buffer.value),
- canvas.width,
- canvas.height,
- );
- _ctx.putImageData(img, 0, 0);
+ // console.log(buffer?.value?.length);
+ if (buffer?.value) {
+ setImageData({
+ buffer: new Uint8ClampedArray(buffer?.value),
+ width: drawWidth,
+ height: drawHeight,
+ });
+ } else {
+ setImageData(null);
}
+ draw();
});
}
@@ -63,10 +117,6 @@ export const ScreenView: Component = (props) => {
});
subscribeScreenshotUpdate(localProps.displayId);
- onMount(() => {
- setCtx(canvas.getContext('2d'));
- });
-
onCleanup(() => {
unlisten.then((unlisten) => {
unlisten();
@@ -74,5 +124,28 @@ export const ScreenView: Component = (props) => {
});
});
- return ;
+ createEffect(() => {
+ let resizeObserver: ResizeObserver;
+
+ onMount(() => {
+ setCtx(canvas.getContext('2d'));
+ new ResizeObserver(() => {
+ resetSize();
+ }).observe(root);
+ });
+
+ onCleanup(() => {
+ resizeObserver?.unobserve(root);
+ });
+ });
+
+ return (
+
+
+
+ );
};