Skip to content

Latest commit

ย 

History

History
119 lines (90 loc) ยท 5.09 KB

File metadata and controls

119 lines (90 loc) ยท 5.09 KB

React Native Gesture Image Viewer

English | ํ•œ๊ตญ์–ด

React Native Gesture Image Viewer logo

๊ฐœ์š”

React Native์—์„œ ์ด๋ฏธ์ง€ ๊ฐค๋Ÿฌ๋ฆฌ๋‚˜ ์ฝ˜ํ…์ธ  ๋ทฐ์–ด๋ฅผ ๊ตฌํ˜„ํ•  ๋•Œ, ๋ณต์žกํ•œ ์ œ์Šค์ฒ˜ ์ฒ˜๋ฆฌ์™€ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๊ตฌํ˜„์œผ๋กœ ์–ด๋ ค์›€์„ ๊ฒช์œผ์‹  ์ ์ด ์žˆ์œผ์‹ ๊ฐ€์š”?

๊ธฐ์กด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์€ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์ด ์–ด๋ ต๊ฑฐ๋‚˜ ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. react-native-gesture-image-viewer๋Š” React Native Reanimated์™€ Gesture Handler๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ๊ณ ์„ฑ๋Šฅ ๋ฒ”์šฉ ์ œ์Šค์ฒ˜ ๋ทฐ์–ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, ์ด๋ฏธ์ง€๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋น„๋””์˜ค, ์ปค์Šคํ…€ ์ปดํฌ๋„ŒํŠธ ๋“ฑ ๋ชจ๋“  ์ฝ˜ํ…์ธ ์— ์™„์ „ํ•œ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•๊ณผ ์ง๊ด€์ ์ธ ์ œ์Šค์ฒ˜ ์ง€์›์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

Gesture and zoom demo

์ฃผ์š” ํŠน์ง•

  • ๐ŸคŒ ์™„์ „ํ•œ ์ œ์Šค์ฒ˜ ์ง€์› - ํ•€์น˜ ์คŒ, ๋”๋ธ” ํƒญ ์คŒ, ์Šค์™€์ดํ”„ ๋„ค๋น„๊ฒŒ์ด์…˜, ์คŒ ์ƒํƒœ์—์„œ์˜ ํŒฌ, ์„ธ๋กœ ๋“œ๋ž˜๊ทธ๋กœ ๋‹ซ๊ธฐ ์ง€์›
  • ๐ŸŽ๏ธ ๊ณ ์„ฑ๋Šฅ ์• ๋‹ˆ๋ฉ”์ด์…˜ - React Native Reanimated ๊ธฐ๋ฐ˜์˜ 60fps ์ด์ƒ์˜ ๋ถ€๋“œ๋Ÿฝ๊ณ  ๋ฐ˜์‘์„ฑ ๋†’์€ ์• ๋‹ˆ๋ฉ”์ด์…˜
  • ๐ŸŽจ ์™„์ „ํ•œ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• - ์ปดํฌ๋„ŒํŠธ, ์Šคํƒ€์ผ, ์ œ์Šค์ฒ˜ ๋™์ž‘๊นŒ์ง€ ์™„๋ฒฝํ•˜๊ฒŒ ์ œ์–ด ๊ฐ€๋Šฅ
  • ๐ŸŽ›๏ธ ์™ธ๋ถ€ ์ œ์–ด API - ๋ฒ„ํŠผ ๋“ฑ ๋‹ค๋ฅธ UI ์ปดํฌ๋„ŒํŠธ์—์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์œผ๋กœ ์ œ์–ด ๊ฐ€๋Šฅ
  • ๐Ÿงฉ ๋‹ค์ค‘ ์ธ์Šคํ„ด์Šค ๊ด€๋ฆฌ - ๊ณ ์œ  ID ๊ธฐ๋ฐ˜์œผ๋กœ ์—ฌ๋Ÿฌ ๋ทฐ์–ด๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ๊ด€๋ฆฌ
  • ๐Ÿงฌ ์œ ์—ฐํ•œ ํ†ตํ•ฉ - Modal, React Native Modal, ScrollView, FlatList, FlashList, Expo Image, FastImage ๋“ฑ ์›ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ์‚ฌ์šฉ
  • ๐Ÿง  ์™„๋ฒฝํ•œ TypeScript ์ง€์› - ํƒ€์ž… ์ถ”๋ก ๊ณผ ์•ˆ์ •์„ฑ์„ ๊ฐ–์ถ˜ ๋›ฐ์–ด๋‚œ ๊ฐœ๋ฐœ ๊ฒฝํ—˜ ์ œ๊ณต
  • ๐ŸŒ ํฌ๋กœ์Šค ํ”Œ๋žซํผ ์ง€์› - iOS, Android, Web์—์„œ ๋™์ž‘ํ•˜๋ฉฐ Expo Go ๋ฐ New Architecture ์ง€์›
  • ๐Ÿช„ ๊ฐ„ํŽธํ•œ API - ๋ณต์žกํ•œ ์„ค์ • ์—†์ด๋„ ์ง๊ด€์ ์ด๊ณ  ์‰ฝ๊ฒŒ ๊ตฌํ˜„ ๊ฐ€๋Šฅ

๋น ๋ฅธ ์‹œ์ž‘

๐Ÿ“š ๋ฌธ์„œ

์ „์ฒด ๋ฌธ์„œ๋Š” https://react-native-gesture-image-viewer.pages.dev์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ œ ๋ฐ ๋ฐ๋ชจ

๐Ÿค– AI

  • llms.txt: ๋ฌธ์„œ์˜ ๋ชจ๋“  ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ์ œ๋ชฉ, ๋งํฌ ๋ฐ ๊ฐ„๋‹จํ•œ ์„ค๋ช…์ด ํฌํ•จ๋œ ๊ตฌ์กฐํ™”๋œ ์ƒ‰์ธ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.
  • llms-full.txt: ๋ชจ๋“  ๋ฌธ์„œ ํŽ˜์ด์ง€์˜ ์ „์ฒด ๋‚ด์šฉ์„ ํ•˜๋‚˜์˜ ํŒŒ์ผ๋กœ ํ•ฉ์นœ ์ „์ฒด ๋‚ด์šฉ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.

๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•

react-native-gesture-image-viewer๋Š” ์™„์ „ํ•œ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•์„ ์œ„ํ•ด ์ œ์Šค์ฒ˜ ๋™์ž‘์—๋งŒ ์ง‘์ค‘ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.

import { useCallback, useState } from 'react';
import { ScrollView, Image, Modal, View, Text, Button, Pressable } from 'react-native';
import {
  GestureViewer,
  GestureTrigger,
  useGestureViewerController,
  useGestureViewerEvent,
  useGestureViewerState,
} from 'react-native-gesture-image-viewer';

function App() {
  const images = [...];
  const [visible, setVisible] = useState(false);
  const [selectedIndex, setSelectedIndex] = useState(0);

  const { goToIndex, goToPrevious, goToNext } = useGestureViewerController();

  const { currentIndex, totalCount } = useGestureViewerState();

  const openModal = (index: number) => {
    setSelectedIndex(index);
    setVisible(true);
  };

  const renderImage = useCallback((imageUrl: string) => {
    return <Image source={{ uri: imageUrl }} style={{ width: '100%', height: '100%' }} resizeMode="contain" />;
  }, []);

  useGestureViewerEvent('zoomChange', (data) => {
    console.log(`Zoom changed from ${data.previousScale} to ${data.scale}`);
  });

  return (
    <View>
      {images.map((uri, index) => (
        <GestureTrigger key={uri} onPress={() => openModal(index)}>
          <Pressable>
            <Image source={{ uri }} />
          </Pressable>
        </GestureTrigger>
      ))}
      <Modal transparent visible={visible}>
        <GestureViewer
          data={images}
          initialIndex={selectedIndex}
          renderItem={renderImage}
          ListComponent={ScrollView}
          onDismiss={() => setVisible(false)}
        />
        <View>
          <Button title="Prev" onPress={goToPrevious} />
          <Button title="Jump to index 2" onPress={() => goToIndex(2)} />
          <Button title="Next" onPress={goToNext} />
          <Text>{`${currentIndex + 1} / ${totalCount}`}</Text>
        </View>
      </Modal>
    </View>
  );
}

๊ธฐ์—ฌํ•˜๊ธฐ

ํ”„๋กœ์ ํŠธ ๊ธฐ์—ฌ ๋ฐฉ๋ฒ•๊ณผ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ •์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ธฐ์—ฌ ๊ฐ€์ด๋“œ๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”.

๋ผ์ด์„ ์Šค

MIT