From 649fb46777558954996dedfa3bb10b3391187465 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Sun, 23 Apr 2023 18:33:21 +0400 Subject: [PATCH] [Refactoring] RLottie: Make size required --- src/components/common/AnimatedSticker.tsx | 16 ++++------ src/components/common/ReactionEmoji.tsx | 6 ++-- src/components/common/StickerView.tsx | 6 ++-- .../middle/composer/StickerSetCover.tsx | 8 ++--- .../composer/hooks/useInputCustomEmojis.ts | 2 +- ...edCanvas.ts => useCoordsInSharedCanvas.ts} | 8 ++--- src/lib/rlottie/RLottie.ts | 30 ++++++------------- 7 files changed, 27 insertions(+), 49 deletions(-) rename src/hooks/{useBoundsInSharedCanvas.ts => useCoordsInSharedCanvas.ts} (86%) diff --git a/src/components/common/AnimatedSticker.tsx b/src/components/common/AnimatedSticker.tsx index 9911875d5..564f7b8c0 100644 --- a/src/components/common/AnimatedSticker.tsx +++ b/src/components/common/AnimatedSticker.tsx @@ -28,7 +28,7 @@ export type OwnProps = { playSegment?: [number, number]; speed?: number; noLoop?: boolean; - size?: number; + size: number; quality?: number; color?: [number, number, number]; isLowPriority?: boolean; @@ -126,14 +126,14 @@ const AnimatedSticker: FC = ({ tgsUrl, container, renderId || generateIdFor(ID_STORE, true), - viewId, { - noLoop, size, + noLoop, quality, isLowPriority, coords: sharedCanvasCoords, }, + viewId, color, onLoad, onEnded, @@ -152,18 +152,12 @@ const AnimatedSticker: FC = ({ ]); useEffect(() => { - if (animation || !tgsUrl || (sharedCanvas && !sharedCanvasCoords)) { - return; - } - if (RLottie) { init(); } else { - ensureLottie().then(() => { - requestMeasure(init); - }); + ensureLottie().then(init); } - }, [animation, init, sharedCanvas, sharedCanvasCoords, tgsUrl]); + }, [init]); const throttledInit = useThrottledCallback(init, [init], THROTTLE_MS); useSharedIntersectionObserver(sharedCanvas, throttledInit); diff --git a/src/components/common/ReactionEmoji.tsx b/src/components/common/ReactionEmoji.tsx index e7f27dde2..911dc8de3 100644 --- a/src/components/common/ReactionEmoji.tsx +++ b/src/components/common/ReactionEmoji.tsx @@ -10,7 +10,7 @@ import { EMOJI_SIZE_PICKER } from '../../config'; import buildClassName from '../../util/buildClassName'; import { getDocumentMediaHash, isSameReaction } from '../../global/helpers'; -import useBoundsInSharedCanvas from '../../hooks/useBoundsInSharedCanvas'; +import useCoordsInSharedCanvas from '../../hooks/useCoordsInSharedCanvas'; import useMediaTransition from '../../hooks/useMediaTransition'; import useMedia from '../../hooks/useMedia'; @@ -49,7 +49,7 @@ const ReactionEmoji: FC = ({ ), [availableReactions, reaction]); const thumbDataUri = availableReaction?.staticIcon?.thumbnail?.dataUri; const animationId = availableReaction?.selectAnimation?.id; - const bounds = useBoundsInSharedCanvas(ref, sharedCanvasHqRef); + const coords = useCoordsInSharedCanvas(ref, sharedCanvasHqRef); const mediaData = useMedia( availableReaction?.selectAnimation ? getDocumentMediaHash(availableReaction.selectAnimation) : undefined, !animationId, @@ -91,7 +91,7 @@ const ReactionEmoji: FC = ({ size={EMOJI_SIZE_PICKER} className={transitionClassNames} sharedCanvas={sharedCanvasHqRef!.current || undefined} - sharedCanvasCoords={bounds.coords} + sharedCanvasCoords={coords} /> )} diff --git a/src/components/common/StickerView.tsx b/src/components/common/StickerView.tsx index 17e51986e..524f0687f 100644 --- a/src/components/common/StickerView.tsx +++ b/src/components/common/StickerView.tsx @@ -17,7 +17,7 @@ import { useIsIntersecting } from '../../hooks/useIntersectionObserver'; import useThumbnail from '../../hooks/useThumbnail'; import useMediaTransition from '../../hooks/useMediaTransition'; import useFlag from '../../hooks/useFlag'; -import useBoundsInSharedCanvas from '../../hooks/useBoundsInSharedCanvas'; +import useCoordsInSharedCanvas from '../../hooks/useCoordsInSharedCanvas'; import useHeavyAnimationCheck, { isHeavyAnimating } from '../../hooks/useHeavyAnimationCheck'; import AnimatedSticker from './AnimatedSticker'; @@ -118,7 +118,7 @@ const StickerView: FC = ({ const fullMediaClassNames = useMediaTransition(isFullMediaReady); const noTransition = isLottie && preloadedPreviewData; - const bounds = useBoundsInSharedCanvas(containerRef, sharedCanvasRef); + const coords = useCoordsInSharedCanvas(containerRef, sharedCanvasRef); // Preload preview for Message Input and local message useMedia(previewMediaHash, !shouldLoad || !shouldPreloadPreview, undefined, cacheBuster); @@ -160,7 +160,7 @@ const StickerView: FC = ({ forceOnHeavyAnimation={forceOnHeavyAnimation} isLowPriority={isSmall && !selectIsAlwaysHighPriorityEmoji(getGlobal(), stickerSetInfo)} sharedCanvas={sharedCanvasRef?.current || undefined} - sharedCanvasCoords={bounds.coords} + sharedCanvasCoords={coords} onLoad={markPlayerReady} onLoop={onAnimatedStickerLoop} onEnded={onAnimatedStickerLoop} diff --git a/src/components/middle/composer/StickerSetCover.tsx b/src/components/middle/composer/StickerSetCover.tsx index 1a207acc5..bc298c97c 100644 --- a/src/components/middle/composer/StickerSetCover.tsx +++ b/src/components/middle/composer/StickerSetCover.tsx @@ -15,7 +15,7 @@ import { getStickerPreviewHash } from '../../../global/helpers'; import { useIsIntersecting } from '../../../hooks/useIntersectionObserver'; import useMedia from '../../../hooks/useMedia'; import useMediaTransition from '../../../hooks/useMediaTransition'; -import useBoundsInSharedCanvas from '../../../hooks/useBoundsInSharedCanvas'; +import useCoordsInSharedCanvas from '../../../hooks/useCoordsInSharedCanvas'; import AnimatedSticker from '../../common/AnimatedSticker'; import OptimizedVideo from '../../ui/OptimizedVideo'; @@ -54,7 +54,7 @@ const StickerSetCover: FC = ({ const isReady = mediaData || staticMediaData; const transitionClassNames = useMediaTransition(isReady); - const bounds = useBoundsInSharedCanvas(containerRef, sharedCanvasRef); + const coords = useCoordsInSharedCanvas(containerRef, sharedCanvasRef); useEffect(() => { if (isIntersecting && !stickerSet.stickers?.length) { @@ -74,11 +74,11 @@ const StickerSetCover: FC = ({ ) : (isVideo && !shouldFallbackToStatic) ? ( , sharedCanvasRef?: React.RefObject, ) { const [x, setX] = useState(); const [y, setY] = useState(); - const [size, setSize] = useState(); const recalculate = useCallback(() => { const container = containerRef.current; @@ -43,7 +42,6 @@ export default function useBoundsInSharedCanvas( // Factor coords are used to support rendering while being rescaled (e.g. message appearance animation) setX(round((targetBounds.left - canvasBounds.left) / canvasBounds.width, 4) || 0); setY(round((targetBounds.top - canvasBounds.top) / canvasBounds.height, 4) || 0); - setSize(Math.round(targetBounds.width)); }, [containerRef, sharedCanvasRef]); useEffect(recalculate, [recalculate]); @@ -52,7 +50,5 @@ export default function useBoundsInSharedCanvas( useResizeObserver(sharedCanvasRef, throttledRecalculate); useSharedIntersectionObserver(sharedCanvasRef, throttledRecalculate); - const coords = useMemo(() => (x !== undefined && y !== undefined ? { x, y } : undefined), [x, y]); - - return { coords, size }; + return useMemo(() => (x !== undefined && y !== undefined ? { x, y } : undefined), [x, y]); } diff --git a/src/lib/rlottie/RLottie.ts b/src/lib/rlottie/RLottie.ts index bb3234220..9c0fc0321 100644 --- a/src/lib/rlottie/RLottie.ts +++ b/src/lib/rlottie/RLottie.ts @@ -11,8 +11,8 @@ import cycleRestrict from '../../util/cycleRestrict'; import generateIdFor from '../../util/generateIdFor'; interface Params { + size: number; noLoop?: boolean; - size?: number; quality?: number; isLowPriority?: boolean; coords?: { x: number; y: number }; @@ -96,8 +96,8 @@ class RLottie { const [ , canvas, renderId, - viewId = generateIdFor(ID_STORE, true), - params, , + params, + viewId = generateIdFor(ID_STORE, true), , onLoad, ] = args; let instance = instancesByRenderId.get(renderId); @@ -117,8 +117,8 @@ class RLottie { private tgsUrl: string, private container: HTMLDivElement | HTMLCanvasElement, private renderId: string, + private params: Params, viewId: string = generateIdFor(ID_STORE, true), - private params: Params = {}, private customColor?: [number, number, number], private onLoad?: NoneToVoidFunction | undefined, private onEnded?: (isDestroyed?: boolean) => void, @@ -264,19 +264,7 @@ class RLottie { throw new Error('[RLottie] Container is not mounted'); } - let { size } = this.params; - - if (!size) { - size = ( - container.offsetWidth - || parseInt(container.style.width, 10) - || container.parentNode.offsetWidth - ); - - if (!size) { - throw new Error('[RLottie] Failed to detect width from container'); - } - } + const { size } = this.params; imgSize = Math.round(size * sizeFactor); @@ -309,7 +297,7 @@ class RLottie { const canvas = container; const ctx = canvas.getContext('2d')!; - imgSize = Math.round(this.params.size! * sizeFactor); + imgSize = Math.round(this.params.size * sizeFactor); if (!this.imgSize) { this.imgSize = imgSize; @@ -323,8 +311,8 @@ class RLottie { ctx, isSharedCanvas: true, coords: { - x: Math.round((coords?.x || 0) * canvasWidth), - y: Math.round((coords?.y || 0) * canvasHeight), + x: Math.round(coords!.x * canvasWidth), + y: Math.round(coords!.y * canvasHeight), }, onLoad, }); @@ -337,8 +325,8 @@ class RLottie { private calcSizeFactor() { const { - isLowPriority, size, + isLowPriority, // Reduced quality only looks acceptable on big enough images quality = isLowPriority && (!size || size > LOW_PRIORITY_QUALITY_SIZE_THRESHOLD) ? LOW_PRIORITY_QUALITY : HIGH_PRIORITY_QUALITY,