Animation attempt

This commit is contained in:
jaredvu 2023-11-28 15:44:01 -08:00
parent 2e51502abe
commit 7c48058cd3
No known key found for this signature in database
GPG Key ID: B9FE2F3F0A5D523C
2 changed files with 107 additions and 37 deletions

View File

@ -168,6 +168,7 @@ export const useDrawOrderbook = ({
size,
price,
mine,
animationType,
}: {
ctx: CanvasRenderingContext2D;
canvasWidth: number;
@ -175,9 +176,39 @@ export const useDrawOrderbook = ({
size?: Nullable<number>;
price?: Nullable<number>;
mine?: Nullable<number>;
animationType?: 'remove' | 'add';
}) => {
const y = getYFromIndex(idx, 'text');
const textColor = Colors[theme].text2;
const rectY = getYFromIndex(idx, 'rect');
let startTime: number;
let textColor: string = Colors[theme].text2;
const animateColor = (timestamp: number) => {
if (!startTime) startTime = timestamp;
const animationTime = timestamp - startTime;
// Linear transition for demonstration purposes
textColor = animationType
? {
add: Colors[theme].green,
remove: Colors[theme].red,
}[animationType]
: Colors[theme].text2;
if (animationTime < 500) {
// Continue the animation for 500ms (adjust as needed)
requestAnimationFrame(animateColor);
} else {
textColor = Colors[theme].text2;
}
if (animationType) {
// TODO: Clear rect and redraw text
// ctx.clearRect(0, rectY, canvasWidth, rectY + ROW_HEIGHT);
}
};
requestAnimationFrame(animateColor);
// Size text
if (size) {
@ -201,7 +232,7 @@ export const useDrawOrderbook = ({
// Mine text
if (mine) {
ctx.fillStyle = textColor;
ctx.fillStyle = Colors[theme].text2;
ctx.fillText(
MustBigNumber(mine).toFormat(stepSizeDecimals ?? TOKEN_DECIMALS, formatOptions),
getXByColumn({ canvasWidth, colIdx: 2 }) - ROW_PADDING_RIGHT,
@ -258,9 +289,7 @@ export const useDrawOrderbook = ({
return canvas.width / ratio;
}, [canvas, hoverCanvas]);
/**
* Handle Row Hover
*/
//Handle Row Hover
const lastHoveredRowRef = useRef<number>();
const lastHoveredRow = lastHoveredRowRef.current;
useEffect(() => {
@ -280,7 +309,12 @@ export const useDrawOrderbook = ({
}
}, [lastHoveredRow, hoveredRow]);
// Update histograms and row contents on data change
// Row Removal Animation state
const previousDataRef = useRef<{
[key: string]: number;
}>(Object.fromEntries(data.map((row: RowData) => [row.price, row.size])));
//Update histograms and row contents on data change
useEffect(() => {
const ctx = canvas?.getContext('2d');
@ -316,6 +350,9 @@ export const useDrawOrderbook = ({
histogramSide,
});
const isNew = !previousDataRef.current[price];
const wasRemoved = previousDataRef.current[price] && !data.find((row) => row.price === price);
// Size, Price, Mine
drawText({
ctx,
@ -324,8 +361,11 @@ export const useDrawOrderbook = ({
size,
price,
mine,
animationType: isNew ? 'add' : wasRemoved ? 'remove' : undefined,
});
});
previousDataRef.current = Object.fromEntries(data.map((row: RowData) => [row.price, row.size]));
}, [
canvasWidth,
data,

View File

@ -25,6 +25,7 @@ import { Tag } from '@/components/Tag';
import { ROW_HEIGHT, Row, type RowData } from './Orderbook/OrderbookRow';
import { SpreadRow } from './Orderbook/SpreadRow';
import { Output, OutputType } from '@/components/Output';
const ORDERBOOK_MAX_ROWS_PER_SIDE = 35;
@ -166,21 +167,32 @@ export const Orderbook = ({
side="ask"
onMouseLeave={() => setHoveredRow(undefined)}
>
<$HistogramCanvas ref={asksCanvasRef} width="100%" height={numRows * ROW_HEIGHT} />
<$HistogramCanvas ref={asksHoverRef} width="100%" height={numRows * ROW_HEIGHT} />
{asksSlice.map((row: RowData, idx) =>
row.price ? (
<$Row
key={idx}
title={`${row.price}`}
onClick={() => onRowAction(row.price)}
onMouseOver={(e) => setHoveredRow({ idx, side: 'ask' })}
/>
) : (
<$Row key={idx} onMouseOver={(e) => setHoveredRow(undefined)} />
)
)}
<$OrderbookCanvas ref={asksCanvasRef} width="100%" height={numRows * ROW_HEIGHT} />
<$HoverCanvas ref={asksHoverRef} width="100%" height={numRows * ROW_HEIGHT} />
<$HoverRows>
{asksSlice.map((row: RowData, idx) =>
row.price ? (
<$Row
key={idx}
title={`${row.price}`}
onClick={() => onRowAction(row.price)}
onMouseOver={(e) => setHoveredRow({ idx, side: 'ask' })}
>
<span></span>
<span></span>
<span>
<Output
type={OutputType.Fiat}
value={row.price}
fractionDigits={tickSizeDecimals}
/>
</span>
</$Row>
) : (
<$Row key={idx} onMouseOver={(e) => setHoveredRow(undefined)} />
)
)}
</$HoverRows>
</$OrderbookSideContainer>
<SpreadRow
@ -195,21 +207,32 @@ export const Orderbook = ({
side="bid"
onMouseLeave={() => setHoveredRow(undefined)}
>
<$HistogramCanvas ref={bidsCanvasRef} width="100%" height={numRows * ROW_HEIGHT} />
<$HistogramCanvas ref={bidsHoverRef} width="100%" height={numRows * ROW_HEIGHT} />
{bidsSlice.map((row: RowData, idx) =>
row.price ? (
<$Row
key={idx}
title={`${row.price}`}
onClick={() => onRowAction(row.price)}
onMouseOver={(e) => setHoveredRow({ idx, side: 'bid' })}
/>
) : (
<$Row key={idx} onMouseOver={(e) => setHoveredRow(undefined)} />
)
)}
<$OrderbookCanvas ref={bidsCanvasRef} width="100%" height={numRows * ROW_HEIGHT} />
<$HoverCanvas ref={bidsHoverRef} width="100%" height={numRows * ROW_HEIGHT} />
<$HoverRows>
{bidsSlice.map((row: RowData, idx) =>
row.price ? (
<$Row
key={idx}
title={`${row.price}`}
onClick={() => onRowAction(row.price)}
onMouseOver={(e) => setHoveredRow({ idx, side: 'bid' })}
>
<span></span>
<span></span>
<span>
<Output
type={OutputType.Fiat}
value={row.price}
fractionDigits={tickSizeDecimals}
/>
</span>
</$Row>
) : (
<$Row key={idx} onMouseOver={(e) => setHoveredRow(undefined)} />
)
)}
</$HoverRows>
</$OrderbookSideContainer>
</>
)}
@ -267,7 +290,7 @@ const $OrderbookSideContainer = styled.div<{ numRows: number; side: 'bid' | 'ask
position: relative;
`;
const $HistogramCanvas = styled(Canvas)`
const $OrderbookCanvas = styled(Canvas)`
width: 100%;
height: 100%;
@ -278,6 +301,13 @@ const $HistogramCanvas = styled(Canvas)`
font-feature-settings: var(--fontFeature-monoNumbers);
`;
const $HoverCanvas = styled($OrderbookCanvas)``;
const $HoverRows = styled.div`
position: absolute;
width: 100%;
`;
const $Row = styled(Row)<{ onClick?: () => void }>`
${({ onClick }) => (onClick ? 'cursor: pointer;' : 'cursor: default;')}
`;