Skip to content

Commit

Permalink
DragBoard: split DragBoardItem in DragBoardItem and DragBoardHandle
Browse files Browse the repository at this point in the history
  • Loading branch information
tmunz committed Nov 15, 2024
1 parent 12de817 commit 987354a
Show file tree
Hide file tree
Showing 13 changed files with 104 additions and 47 deletions.
5 changes: 3 additions & 2 deletions src/app/content/art/Art.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useDimension } from '../../utils/useDimension';
import { DragBoardItem } from '../../ui/drag-board/DragBoardItem';
import { CitroenDsLamp } from './citroen-ds-lamp/CitroenDsLamp';
import { Mb300slPainting } from './mb300sl/Mb300slPainting';
import { DragBoardHandle } from '../../ui/drag-board/DragBoardHandle';


export function Art() {
Expand All @@ -18,9 +19,9 @@ export function Art() {
placementPattern={[{ x: -10, y: 0, rotation: 0.5 }, { x: 50, y: 5, rotation: -1.5 }, { x: -60, y: 10, rotation: -2 }]}
indicator
>
<DragBoardItem><CitroenDsLamp width={(dimension?.width ?? 600) * 0.6} height={(dimension?.height ?? 400) * 0.6} /></DragBoardItem>
<DragBoardItem><DragBoardHandle><CitroenDsLamp width={(dimension?.width ?? 600) * 0.6} height={(dimension?.height ?? 400) * 0.6} /></DragBoardHandle></DragBoardItem>
<DrawBoardItem width={dimension?.width ?? 600} height={dimension?.height ?? 400} />
<DragBoardItem><Mb300slPainting width={Math.max(500, (dimension?.width ?? 500) * 0.3)} /></DragBoardItem>
<DragBoardItem><DragBoardHandle><Mb300slPainting width={Math.max(500, (dimension?.width ?? 500) * 0.3)} /></DragBoardHandle></DragBoardItem>
</DragBoard>
</div>;
}
10 changes: 6 additions & 4 deletions src/app/content/art/draw/DrawBoardItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@ import React, { useState } from 'react';
import { PaperFolding } from '../../../effects/PaperFolding';
import { DrawWithControls } from '../../../ui/draw/DrawWithControls';
import { DragBoardItem } from '../../../ui/drag-board/DragBoardItem';
import { DragBoardHandle } from '../../../ui/drag-board/DragBoardHandle';

export function DrawBoardItem({ width, height, gap = 40 }: { width: number, height: number, gap?: number }) {

const [active, setActive] = useState(false);

return <DragBoardItem
disableDrag={active}
x={active ? 0 : undefined}
y={active ? 0 : undefined}
rotation={active ? 0 : undefined}
className='draw-board-item'
>
<PaperFolding onUnfold={() => setActive(true)} onInfold={() => setActive(false)} title='Paint your own Masterpiece'>
<DrawWithControls width={width - 2 * gap} height={height - 2 * gap} />
</PaperFolding>
<DragBoardHandle disableDrag={active}>
<PaperFolding onUnfold={() => setActive(true)} onInfold={() => setActive(false)} title='Paint your own Masterpiece'>
<DrawWithControls width={width - 2 * gap} height={height - 2 * gap} />
</PaperFolding>
</DragBoardHandle>
</DragBoardItem >;
}
4 changes: 2 additions & 2 deletions src/app/content/bricks/horse/Muybridge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const Muybridge = ({ pointer$ }: { pointer$: BehaviorSubject<{ x: number,
const { current: vec } = useRef(new THREE.Vector3());
useFrame((state) => {
const p = pointer$.getValue();
state.camera.position.lerp(vec.set(-1 + p.x * -1, 1 + p.y * 1, 7), 0.05);
state.camera.position.lerp(vec.set(-1 + p.x * -1, 1 + p.y * 1, 8), 0.05);
state.camera.lookAt(0, 0, 0);
});

Expand All @@ -22,7 +22,7 @@ export const Muybridge = ({ pointer$ }: { pointer$: BehaviorSubject<{ x: number,
<fog attach='fog' args={['black', 10, 12]} />
<PerspectiveCamera makeDefault fov={15} position={[0, 3, 100]} />
<Suspense fallback={null}>
<group position={[0, -1.2, 0]}>
<group position={[-0.5, -1.2, 0]}>
<Carla position={[-0.5, 0, 0]} rotation={[0, Math.PI - 0.4, 0]} scale={[0.2, 0.2, 0.2]} />
<Screen position={[1, 1.1, -2]} rotation={[0, -0.2, 0]} scale={[0.2, 0.2, 0.2]} />
<Ground />
Expand Down
2 changes: 1 addition & 1 deletion src/app/content/vita/Vita.styl
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
}

&.active .background-image {
filter: blur(100px); /*contrast(1.0) brightness(1.0) saturate(1.0)*/
filter: blur(100px); /* brightness(0) contrast(1.0) brightness(1.0) saturate(1.0)*/
}
}

Expand Down
1 change: 1 addition & 0 deletions src/app/ui/drag-board/DragBoard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { DragBoardIndicator } from './DragBoardIndicator';
import { useFlipThrough } from './useFlipThrough';
import { useDragSwipe } from './useDragSwipe';
import { DragSwipeIndicator } from './DragSwipeIndicator';
import { DragBoardHandleContext } from './DragBoardHandle';

export interface DragBoardProps {
children: React.ReactNode;
Expand Down
14 changes: 14 additions & 0 deletions src/app/ui/drag-board/DragBoardHandle.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.drag-board-handle {
box-sizing: border-box;
&:not(.drag-board-handle-drag-disabled) {
cursor: grab;

&.drag-board-handle-dragging {
cursor: grabbing;

&>* {
pointer-events: none;
}
}
}
}
40 changes: 40 additions & 0 deletions src/app/ui/drag-board/DragBoardHandle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import './DragBoardHandle.styl';

import React, { createContext, ReactNode } from 'react';
import { handleStart } from './handlePointerEvents';


// const MAX = 9999999;
// const R = MAX / -2;

export interface DragBoardHandleConsuming {
isDragging: boolean;
onPointerDown: (e: { clientX: number, clientY: number }) => void;
}

interface DragBoardHandleProps {
children?: ReactNode;
disableDrag?: boolean;
className?: string;
dragBoardItemRect?: DOMRect;
}

export const DragBoardHandleContext = createContext<DragBoardHandleConsuming | null>(null);

export const DragBoardHandle = (props: DragBoardHandleProps) => {
return (
<DragBoardHandleContext.Consumer>
{(value: DragBoardHandleConsuming | null) => {
if (!value) return null;
return <div
className={`${props.className ?? ''} drag-board-handle ${value.isDragging ? 'drag-board-handle-dragging' : ''} ${props.disableDrag ? 'drag-board-handle-drag-disabled' : ''}`}
onTouchStart={(e) => !props.disableDrag && value.onPointerDown(handleStart(e.touches[0]))}
onMouseDown={(e) => !props.disableDrag && value.onPointerDown(handleStart(e))}
>
{/* TODO {value.isDragging && <div style={{ position: 'fixed', background: 'rgba(255, 0, 0, 0.5)', zIndex: MAX, top: R, left: R, width: MAX, height: MAX }} />} */}
{props.children}
</div>
}}
</DragBoardHandleContext.Consumer >
);
};
12 changes: 0 additions & 12 deletions src/app/ui/drag-board/DragBoardItem.styl
Original file line number Diff line number Diff line change
@@ -1,16 +1,4 @@
.drag-board-item {
position: absolute;
transition: transform 0.1s ease-out;

&:not(.drag-board-item-drag-disabled) {
cursor: grab;

&.drag-board-item-dragging {
cursor: grabbing;

&>* {
pointer-events: none;
}
}
}
}
24 changes: 16 additions & 8 deletions src/app/ui/drag-board/DragBoardItem.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import './DragBoardItem.styl';

import React, { createContext, ReactNode } from "react";
import { handleStart } from './handlePointerEvents';
import { DragBoardHandleContext } from './DragBoardHandle';
import React, { createContext, ReactNode } from 'react';


export interface DragBoardItemConsuming extends DragBoardItemState {
isDragging: boolean;
onPointerDown: (id: string, e: { clientX: number, clientY: number, rect: DOMRect }) => void;
onPointerDown: (id: string, dragBoardItemRect: DOMRect | null, e: { clientX: number, clientY: number }) => void;
}

export interface DragBoardItemState {
Expand All @@ -26,6 +25,8 @@ interface DragBoardItemProps extends Partial<DragBoardItemState> {
export const DragBoardItemContext = createContext<DragBoardItemConsuming | null>(null);

export const DragBoardItem = (props: DragBoardItemProps) => {
const elementRef = React.useRef<HTMLDivElement>(null);

return (
<DragBoardItemContext.Consumer>
{(value: DragBoardItemConsuming | null) => {
Expand All @@ -37,17 +38,24 @@ export const DragBoardItem = (props: DragBoardItemProps) => {

return <div
key={value.id}
className={`${props.className ?? ''} drag-board-item ${value.isDragging ? 'drag-board-item-dragging' : ''} ${props.disableDrag ? 'drag-board-item-drag-disabled' : ''}`}
ref={elementRef}
className={`${props.className ?? ''} drag-board-item`}
style={{
left: `calc(50% + ${x}px)`,
top: `calc(50% + ${y}px)`,
transform: `translate(-50%, -50%) rotate(${rotation}deg)`,
zIndex: z + 1,
}}
onTouchStart={(e) => !props.disableDrag && value.onPointerDown(value.id, handleStart(e.touches[0], e))}
onMouseDown={(e) => !props.disableDrag && value.onPointerDown(value.id, handleStart(e, e))}
>
{props.children}
<DragBoardHandleContext.Provider value={{
isDragging: value.isDragging,
onPointerDown: (e: {
clientX: number;
clientY: number;
}) => value.onPointerDown(value.id, elementRef.current?.getBoundingClientRect() ?? null, e),
}}>
{props.children}
</DragBoardHandleContext.Provider>
</div>
}}
</DragBoardItemContext.Consumer >
Expand Down
2 changes: 1 addition & 1 deletion src/app/ui/drag-board/DragSwipeIndicator.styl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

.icon {
transition: fill 0.2s;
fill: rgba(255, 255, 255, 0.5);
fill: rgba(255, 255, 255, 0.8);
}
}
}
4 changes: 2 additions & 2 deletions src/app/ui/drag-board/handlePointerEvents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const handlePointerEvents = (


// called by the item itself
export const handleStart = (position: { clientX: number, clientY: number }, e: ReactMouseEvent | ReactTouchEvent) => {
export const handleStart = (position: { clientX: number, clientY: number }) => {
preventOverscrollBehaviour();
return { clientX: position.clientX, clientY: position.clientY, rect: e.currentTarget.getBoundingClientRect() };
return { clientX: position.clientX, clientY: position.clientY };
}
6 changes: 3 additions & 3 deletions src/app/ui/drag-board/useDragBoardState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@ export const useDragBoardState = (
});
};

const handleSelectItem = (id: string, e: { clientX: number, clientY: number, rect: DOMRect }) => {
const handleSelectItem = (id: string, dragBoardItemRect: DOMRect | null, e: { clientX: number, clientY: number }) => {
const itemState = itemStates.get(id);
if (itemState) {
setSelectedItem({
id,
offsetX: e.clientX - itemState.x,
offsetY: e.clientY - itemState.y,
width: e.rect.width,
height: e.rect.height,
width: dragBoardItemRect?.width ?? 0,
height: dragBoardItemRect?.height ?? 0,
startX: e.clientX,
startY: e.clientY,
isDragging: false,
Expand Down
27 changes: 15 additions & 12 deletions src/app/ui/mux/desktop/MuxProgramWindowBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { MuxOs } from '../MuxOs';
import { MuxProgram } from '../MuxProgram';
import React, { useState } from 'react';
import { MuxProgramIcon } from './MuxProgramIcon';
import { DragBoardHandle } from '../../drag-board/DragBoardHandle';

const ABOUT = '🛈';
const CLOSE = '✕';
Expand All @@ -17,18 +18,20 @@ export const MuxProgramWindowBar = ({ program }: MuxProgramWindowBarProps) => {
const toggleInfo = () => setShowInfo(!showInfo);

return (
<div className='mux-program-window-bar'>
<div className='window-title'>
<MuxProgramIcon path={program.iconPath} name={program.name} monoColor={program.iconMonoColor} />
{program.name}
</div>
<button className='info-button' onClick={toggleInfo}>
{ABOUT}
</button>
<button className='close-button' onClick={() => MuxOs.get().quitProgram(program.id)}>
{CLOSE}
</button>
<>
<DragBoardHandle className='mux-program-window-bar'>
<div className='window-title'>
<MuxProgramIcon path={program.iconPath} name={program.name} monoColor={program.iconMonoColor} />
{program.name}
</div>
<button className='info-button' onClick={toggleInfo}>
{ABOUT}
</button>
<button className='close-button' onClick={() => MuxOs.get().quitProgram(program.id)}>
{CLOSE}
</button>
</DragBoardHandle>
{showInfo && <div className='window-about'>{program.about}</div>}
</div>
</>
);
};

0 comments on commit 987354a

Please sign in to comment.