React Native Academy · Pelajaran

Zum Cubit dan Putaran

Gabungkan PinchGestureHandler dan RotationGestureHandler dengan pengecaman gerak isyarat serentak untuk melaksanakan komponen imej yang boleh dizum dan diputar.

Pelajaran 4 daripada 413 langkah

Zum Cubit dan Putaran ialah pelajaran React Native Academy percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Sebanyak 3 pelajaran dalam laluan pembelajaran ini boleh dibaca sepenuhnya secara percuma — selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan praktikal dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran React Native Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus React Native Academy merangkumi sejumlah 4 pelajaran.

Mengapa Pinch dan Rotation Penting

Zum cubit dan putaran ialah interaksi utama pada peranti mudah alih, yang terdapat dalam pemapar foto, peta dan aplikasi dokumen. Pelaksanaan yang baik memerlukan pengenalpastian gesture berbilang sentuhan yang berjalan pada utas natif serta kemas kini transformasi masa nyata yang lancar melalui nilai dikongsi Reanimated.

React Native Gesture Handler menyediakan pengecam Gesture.Pinch() dan Gesture.Rotation(), yang apabila digabungkan dengan useAnimatedStyle dan useSharedValue Reanimated, menghasilkan interaksi yang sangat lancar sehingga sukar dibezakan daripada pelaksanaan natif.

Gesture.Pinch: Mengesan Skala

Gesture.Pinch() mengenal pasti gesture mencubit atau merenggang dengan dua jari. Nilai paling penting dalam objek peristiwa ialah event.scale, yang bermula pada 1.0 apabila gesture bermula dan berubah mengikut jarak antara jari. Nilai 2.0 bermaksud jarak antara jari adalah dua kali ganda berbanding permulaan.

Anda mesti menggabungkan skala bertambah gesture dengan skala asas yang disimpan untuk mengumpulkan zum merentas berbilang gesture cubit — jika tidak, setiap cubitan baharu akan ditetapkan semula kepada 1.0.

import { Gesture } from 'react-native-gesture-handler';
import { useSharedValue, withSpring } from 'react-native-reanimated';

const scale = useSharedValue(1);
const savedScale = useSharedValue(1);

const pinch = Gesture.Pinch()
  .onUpdate((e) => {
    scale.value = savedScale.value * e.scale;
  })
  .onEnd(() => {
    savedScale.value = scale.value;
  });

Mengehadkan Julat Zum

Tanpa had, pengguna boleh mengezum masuk ke skala yang sangat besar atau mengezum keluar sehingga imej hilang. Takrifkan aras zum minimum dan maksimum, kemudian hadkan nilai skala dalam panggil balik onUpdate menggunakan worklet utiliti.

Fungsi had berjalan pada utas UI sebagai worklet, lalu memastikan respons gesture kekal pantas. Pilih nilai had yang sesuai dengan kandungan anda — pemapar foto biasanya membenarkan zum 1x hingga 5x, manakala peta mungkin membenarkan julat yang jauh lebih luas.

const MIN_SCALE = 1;
const MAX_SCALE = 5;

function clamp(value, min, max) {
  'worklet';
  return Math.min(Math.max(value, min), max);
}

const pinch = Gesture.Pinch()
  .onUpdate((e) => {
    scale.value = clamp(savedScale.value * e.scale, MIN_SCALE, MAX_SCALE);
  })
  .onEnd(() => {
    savedScale.value = scale.value;
    // Snap back if over-zoomed out:
    if (scale.value < MIN_SCALE) {
      scale.value = withSpring(MIN_SCALE);
      savedScale.value = MIN_SCALE;
    }
  });

Gesture.Rotation: Menjejak Sudut

Gesture.Rotation() menjejak perubahan sudut bagi gesture memulas dengan dua jari. Nilai event.rotation adalah dalam radian — sudut putaran jari dari kedudukan permulaan gesture. Satu putaran penuh mengikut arah jam ialah kira-kira 6.28 radian (2π).

Seperti skala, anda mesti mengumpulkan putaran merentas berbilang gesture dengan menyimpan putaran semasa pada penghujung gesture dan menambahkan putaran gesture baharu pada ofset yang disimpan dalam gesture seterusnya.

const rotation = useSharedValue(0);
const savedRotation = useSharedValue(0);

const rotationGesture = Gesture.Rotation()
  .onUpdate((e) => {
    rotation.value = savedRotation.value + e.rotation;
  })
  .onEnd(() => {
    savedRotation.value = rotation.value;
  });

Menggunakan Skala dan Putaran dalam useAnimatedStyle

Tatasusunan transform dalam useAnimatedStyle menggunakan kedua-dua skala dan putaran. Susunan transformasi penting: gunakan skala dahulu, kemudian putaran (atau sebaliknya bergantung pada tingkah laku yang diingini). Tatasusunan transform React Native menerima nilai skala berangka dan nilai putaran dalam radian terus daripada nilai dikongsi.

Transformasi rotate memerlukan rentetan dengan akhiran 'rad', manakala scale menerima nombor secara terus. Gunakan penggabungan rentetan (bukan literal templat dengan backtick) untuk membina rentetan putaran dalam worklet.

const animatedStyle = useAnimatedStyle(() => ({
  transform: [
    { scale: scale.value },
    { rotate: rotation.value + 'rad' }, // concatenate string, no backticks
  ],
}));

return (
  <GestureDetector gesture={composedGesture}>
    <Animated.Image
      source={{ uri: imageUrl }}
      style={[styles.image, animatedStyle]}
    />
  </GestureDetector>
);

Menggabungkan Pinch dan Rotation Secara Serentak

Pemapar foto memerlukan pinch dan rotation berfungsi pada masa yang sama. Balut kedua-dua gesture dalam Gesture.Simultaneous dan hantar gesture yang digabungkan itu kepada satu GestureDetector. Ini membolehkan pengguna mengezum dan memutar dengan gesture dua jari dalam satu pergerakan yang lancar.

Menambahkan pan secara serentak menghasilkan pengalaman pemapar foto yang lengkap: mengezum, memutar dan mengubah kedudukan imej dengan dua jari pada masa yang sama.

const composedGesture = Gesture.Simultaneous(
  pinch,
  rotationGesture,
  pan
);

return (
  <GestureDetector gesture={composedGesture}>
    <Animated.Image
      source={{ uri: imageUrl }}
      style={[styles.image, animatedStyle]}
      resizeMode='contain'
    />
  </GestureDetector>
);

Ketuk Dua Kali untuk Menetapkan Semula Zum

Ciri standard pemapar foto ialah mengetuk dua kali untuk bertukar antara saiz semula jadi dengan paparan yang dizum masuk, kemudian mengetuk dua kali lagi untuk menetapkan semula. Gunakan Gesture.Tap().numberOfTaps(2) untuk pengecam ketukan dua kali, dan dalam pengendalinya, animasikan skala serta putaran kembali kepada nilai awal menggunakan spring.

Gunakan Gesture.Exclusive dengan gesture ketukan dua kali diberikan keutamaan berbanding ketukan sekali untuk menghalang ketukan sekali daripada dicetuskan semasa urutan ketukan dua kali.

const doubleTap = Gesture.Tap()
  .numberOfTaps(2)
  .onEnd(() => {
    if (scale.value > 1) {
      // Reset to natural size:
      scale.value = withSpring(1);
      savedScale.value = 1;
      rotation.value = withSpring(0);
      savedRotation.value = 0;
      offsetX.value = withSpring(0);
      offsetY.value = withSpring(0);
    } else {
      // Zoom to 2x:
      scale.value = withSpring(2);
      savedScale.value = 2;
    }
  });

Titik Pangsi untuk Zum Pinch

Secara lalai, transformasi skala menskalakan imej dari titik tengahnya. Untuk rasa yang lebih semula jadi, imej sepatutnya dizum mengelilingi titik fokus — titik tengah antara kedua-dua jari. Peristiwa gesture menyediakan event.focalX dan event.focalY untuk tujuan ini.

Pelaksanaan zum berasaskan titik fokus memerlukan pelarasan ofset translasi bersama-sama skala supaya titik di bawah jari kekal tetap semasa zum. Matematik ini melibatkan pengiraan perubahan ofset yang disebabkan oleh perubahan skala pada titik fokus tertentu.

const pinch = Gesture.Pinch()
  .onUpdate((e) => {
    const newScale = clamp(savedScale.value * e.scale, MIN_SCALE, MAX_SCALE);
    const scaleDelta = newScale / scale.value;
    // Adjust offset to keep focal point fixed:
    offsetX.value = e.focalX - scaleDelta * (e.focalX - offsetX.value);
    offsetY.value = e.focalY - scaleDelta * (e.focalY - offsetY.value);
    scale.value = newScale;
  });

Kekangan Sempadan Selepas Pan dan Zum

Selepas mengezum masuk, pengguna boleh melakukan pan untuk melihat bahagian imej yang berbeza. Namun, anda perlu mengehadkan pan supaya imej tidak boleh diseret sehingga kanvas kosong di luar tepinya kelihatan. Kira ofset pan maksimum berdasarkan skala semasa dan dimensi imej, kemudian hadkan ofset dalam onUpdate pan.

Inilah kemasan yang membezakan pemapar foto profesional daripada prototaip kasar. Logik kekangan ini hanya memerlukan beberapa baris matematik yang berjalan sebagai worklet pada utas UI.

const IMAGE_WIDTH = 300;
const CONTAINER_WIDTH = 375;

const pan = Gesture.Pan()
  .onUpdate((e) => {
    const maxOffsetX = Math.max(0, (scale.value * IMAGE_WIDTH - CONTAINER_WIDTH) / 2);
    offsetX.value = clamp(
      savedOffsetX.value + e.translationX,
      -maxOffsetX,
      maxOffsetX
    );
  });

Menganimasikan Kembali Selepas Zum Berlebihan

Apabila pengguna mengangkat jari selepas melakukan zum berlebihan (di bawah minimum atau melebihi maksimum), gunakan spring untuk mengembalikan skala kepada had, bukannya membiarkan imej pada saiz yang luar biasa. Lakukan ini dalam panggil balik onEnd bagi gesture pinch.

Begitu juga, selepas pengguna mengezum keluar kembali kepada 1x, tetapkan semula ofset pan kepada sifar supaya imej kembali ke tengah. Gabungan pemeriksaan sempadan dalam onEnd ini menjadikan komponen terasa kemas dan boleh dijangka.

const pinch = Gesture.Pinch()
  .onEnd(() => {
    if (scale.value < MIN_SCALE) {
      scale.value = withSpring(MIN_SCALE);
      savedScale.value = MIN_SCALE;
      // Reset pan to center:
      offsetX.value = withSpring(0);
      offsetY.value = withSpring(0);
    } else if (scale.value > MAX_SCALE) {
      scale.value = withSpring(MAX_SCALE);
      savedScale.value = MAX_SCALE;
    } else {
      savedScale.value = scale.value;
    }
  });

Menggabungkan Semuanya

Pemapar foto lengkap yang boleh dizum, diputar dan dianjak menggabungkan: nilai dikongsi untuk skala, putaran dan ofset; useAnimatedStyle yang menggunakan semua transformasi; Gesture.Simultaneous yang menggabungkan pinch, rotation, pan dan ketukan dua kali; serta pembatasan sempadan dalam onUpdate dan pembetulan spring dalam onEnd.

Ini ialah salah satu interaksi paling mengagumkan yang boleh anda bina dalam React Native, dan semuanya berjalan pada utas UI tanpa melibatkan utas JavaScript semasa gesture — menjadikannya sukar dibezakan daripada pelaksanaan natif.

const composed = Gesture.Simultaneous(
  Gesture.Exclusive(
    doubleTap,
    singleTap
  ),
  pan,
  pinch,
  rotationGesture
);

const style = useAnimatedStyle(() => ({
  transform: [
    { translateX: offsetX.value },
    { translateY: offsetY.value },
    { scale: scale.value },
    { rotate: rotation.value + 'rad' },
  ],
}));

Semakan Pantas

Uji pemahaman anda tentang konsep Pembangunan Mudah Alih React Native daripada pelajaran ini.

Ulang Kaji Pelajaran

Dalam pelajaran ini, anda telah mempelajari bahawa: Gesture.Pinch() menyediakan event.scale untuk menjejak zum dua jari berbanding permulaan gesture, Gesture.Rotation() menyediakan event.rotation dalam radian untuk menjejak putaran dua jari, dan Gesture.Simultaneous menggabungkan pinch, rotation serta pan supaya ketiga-tiganya berfungsi serentak bagi menghasilkan pengalaman pemapar foto yang lengkap. Seterusnya, kita akan mengkonfigurasi skema URL tersuai untuk pautan mendalam ke skrin aplikasi tertentu.

Percuma untuk bermula

Pelajari JavaScript dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
30
Pelajaran
120

Soalan Lazim

Adakah pelajaran “Zum Cubit dan Putaran” percuma?

Ya — sebanyak 3 pelajaran dalam laluan pembelajaran React Native Academy, termasuk “Zum Cubit dan Putaran”, boleh dibaca sepenuhnya secara percuma di web ini. Selepas itu, CoddyKit PRO membuka akses kepada semua pelajaran, serta latihan interaktif dengan penyunting kod terbina dalam dan tutor kecerdasan buatan yang tersedia 24/7. Kursus React Native Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Zum Cubit dan Putaran”?

Gabungkan PinchGestureHandler dan RotationGestureHandler dengan pengecaman gerak isyarat serentak untuk melaksanakan komponen imej yang boleh dizum dan diputar. Anda berlatih React Native Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan React Native Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran React Native Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.

Berapa lamakah pelajaran “Zum Cubit dan Putaran” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran React Native Academy ini?

Ya. Setiap pelajaran React Native Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Memasang Reanimated dan Nilai Dikongsi
  2. Worklet dan Menjalankan Kod pada Utas UI
  3. Gerak Isyarat Seret dan Leret dengan Gesture Handler
  4. Zum Cubit dan Putaran
← Kembali ke React Native Academy