Add x and y props to image

This commit is contained in:
Zoe Roux 2024-01-25 09:39:37 +01:00
parent 5efcfb8b61
commit ec90862262
3 changed files with 59 additions and 26 deletions

View File

@ -18,6 +18,8 @@
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
*/
import { ComponentProps } from "react";
import { View } from "react-native";
import FImage from "react-native-fast-image";
export const FastImage = ({
@ -25,6 +27,10 @@ export const FastImage = ({
alt,
width,
height,
x,
y,
rows,
columns,
style,
...props
}: {
@ -32,18 +38,31 @@ export const FastImage = ({
alt: string;
width: number | string;
height: number | string;
x: number;
y: number;
rows: number;
columns: number;
style?: object;
}) => {
return (
<FImage
source={{
uri: src,
priority: FImage.priority.low,
}}
accessibilityLabel={alt}
resizeMode={FImage.resizeMode.cover}
style={style}
{...props}
/>
<View style={{ width, height, overflow: "hidden", flexGrow: 0, flexShrink: 0 }}>
<FImage
source={{
uri: src,
priority: FImage.priority.low,
}}
accessibilityLabel={alt}
resizeMode={FImage.resizeMode.cover}
style={[
{
width: width * columns,
height: height * rows,
transform: `translate(${-x}px, ${-y}px)`,
},
style,
]}
{...props}
/>
</View>
);
};

View File

@ -24,11 +24,17 @@ export const FastImage = ({
src,
alt,
style,
x,
y,
...props
}: {
src: string;
alt: string;
style?: object;
width: number | string;
height: number | string;
x: number;
y: number;
}) => {
return (
<NextImage
@ -37,7 +43,7 @@ export const FastImage = ({
alt={alt!}
// Don't use next's server to reprocess images, they are already optimized by kyoo.
unoptimized={true}
style={style}
style={{ objectFit: "none", objectPosition: `${-x}px ${-y}px`, ...style }}
{...props}
/>
);

View File

@ -23,11 +23,12 @@ import { FastImage, P, imageBorderRadius, tooltip, ts } from "@kyoo/primitives";
import { Platform, View } from "react-native";
import { percent, useYoshiki, px, vh } from "yoshiki/native";
import { ErrorView } from "../../fetch";
import { useMemo } from "react";
import { ComponentProps, useEffect, useMemo } from "react";
import { CssObject } from "yoshiki/src/web/generator";
import { useAtomValue } from "jotai";
import { durationAtom, progressAtom } from "../state";
import { durationAtom, playAtom, progressAtom } from "../state";
import { toTimerString } from "./left-buttons";
import { useSetAtom } from "jotai";
type Thumb = { to: number; url: string; x: number; y: number; width: number; height: number };
@ -67,7 +68,19 @@ export const useScrubber = (url: string) => {
return ret;
}, [data]);
return { info, error } as const;
const last = info?.[info.length - 1];
return {
info,
error,
stats: last
? {
rows: last.y / last.height + 1,
columns: Math.max(...info.map((x) => x.x)) / last.width + 1,
width: last.width,
height: last.height,
}
: null,
} as const;
};
useScrubber.query = (url: string): QueryIdentifier<string> => ({
@ -80,14 +93,14 @@ useScrubber.query = (url: string): QueryIdentifier<string> => ({
export const BottomScrubber = ({ url }: { url: string }) => {
const { css } = useYoshiki();
const { info, error } = useScrubber(url);
const { info, error, stats } = useScrubber(url);
const progress = useAtomValue(progressAtom);
const duration = useAtomValue(durationAtom);
const duration = useAtomValue(durationAtom) ?? 1;
if (error) return <ErrorView error={error} />;
const width = info?.[0]?.width ?? 0;
const width = stats?.width ?? 1;
return (
<View {...css({ overflow: "hidden" })}>
<View
@ -109,15 +122,10 @@ export const BottomScrubber = ({ url }: { url: string }) => {
alt=""
width={thumb.width}
height={thumb.height}
style={
Platform.OS === "web"
? ({
objectFit: "none",
objectPosition: `${-thumb.x}px ${-thumb.y}px`,
flexShrink: 0,
} as CssObject)
: undefined
}
x={thumb.x}
y={thumb.y}
columns={stats?.columns}
rows={stats?.rows}
/>
))}
</View>