Rumah hujung hadapan web tutorial js Mencipta Cangkuk Reaksi untuk Memusing Imej di Mana-mana Sudut

Mencipta Cangkuk Reaksi untuk Memusing Imej di Mana-mana Sudut

Sep 05, 2024 pm 07:00 PM

Creating a React Hook for Rotating Images at Any Angle

Dalam pembangunan web, anda mungkin perlu memutarkan imej, yang mudah dilakukan dalam CSS. Kod mudah seperti transformasi ini: rotate(90deg);. Tetapi bagaimana jika kita mahu melakukannya dalam JS?

TLDR

Melukis imej ke kanvas dalam persekitaran penyemak imbas dan memutarkannya. Tetapi sebelum itu, kita perlu melakukan beberapa matematik untuk mengekalkan nisbah bidang imej asal.

Teras

Dengan mengandaikan bahawa kita telah memuatkan imej, pengiraan imej yang diputar boleh dilakukan seperti berikut:

const { PI, sin, cos, abs } = Math;
const angle = (degree * PI) / 180;
const sinAngle = sin(angle);
const cosAngle = cos(angle);

const rotatedWidth = abs(imageWidth * cosAngle) + abs(imageHeight * sinAngle);

const rotatedHeight = abs(imageWidth * sinAngle) + abs(imageHeight * cosAngle);

Dan seterusnya, kami menggunakan beberapa API kanvas untuk melakukan putaran sebenar:

const canvas = document.createElement('canvas');

const { width: canvasWidth, height: canvasHeight } = canvas;
const canvasCtx2D = canvas.getContext('2d');

canvasCtx2D.clearRect(0, 0, canvasWidth, canvasHeight);
canvasCtx2D.translate(canvasWidth / 2, canvasHeight / 2);
canvasCtx2D.rotate(angle);

canvasCtx2D.drawImage(
  image,
  -imageWidth / 2,
  -imageHeight / 2,
  imageWidth,
  imageHeight,
);

return canvas.toDataURL('image/png');

Selesaikan

Dengan adanya kod teras, kami boleh membuat beberapa pengoptimuman dan menulis cangkuk React khusus untuk menggunakannya:

import { useEffect, useRef, useState } from 'react';

type RotatedImage = {
  src: string;
  width: number;
  height: number;
} | null;

let canvas: HTMLCanvasElement | null = null;
let canvasCtx2D: CanvasRenderingContext2D | null = null;

const getRotatedImage = (
  image: HTMLImageElement | null,
  rotation: number,
): RotatedImage => {
  canvas ??= document.createElement('canvas');
  canvasCtx2D ??= canvas.getContext('2d');

  if (!image || !canvasCtx2D) return null;

  const { width: imageWidth, height: imageHeight, currentSrc } = image;
  const degree = rotation % 360;
  if (!degree) {
    return {
      src: currentSrc,
      width: imageWidth,
      height: imageHeight,
    };
  }

  const { PI, sin, cos, abs } = Math;
  const angle = (degree * PI) / 180;
  const sinAngle = sin(angle);
  const cosAngle = cos(angle);

  canvas.width = abs(imageWidth * cosAngle) + abs(imageHeight * sinAngle);
  canvas.height = abs(imageWidth * sinAngle) + abs(imageHeight * cosAngle);

  // The width and height of the canvas will be automatically rounded.
  const { width: canvasWidth, height: canvasHeight } = canvas;

  canvasCtx2D.clearRect(0, 0, canvasWidth, canvasHeight);
  canvasCtx2D.translate(canvasWidth / 2, canvasHeight / 2);
  canvasCtx2D.rotate(angle);

  canvasCtx2D.drawImage(
    image,
    -imageWidth / 2,
    -imageHeight / 2,
    imageWidth,
    imageHeight,
  );

  const src = canvas.toDataURL('image/png');
  canvas.width = 0;
  canvas.height = 0;

  return {
    src,
    width: canvasWidth,
    height: canvasHeight,
  };
};

const useRotateImage = (imageSrc: string, rotation?: number): RotatedImage => {
  const imageEle = useRef<HTMLImageElement | null>(null);
  const [rotatedImage, setRotatedImage] = useState<RotatedImage>(null);

  useEffect(() => {
    if (typeof rotation === 'number') {
      let currImage = imageEle.current;

      if (currImage?.currentSrc !== imageSrc) {
        currImage = new Image();
        imageEle.current = currImage;

        currImage.src = imageSrc;
      }

      currImage.decode().then(
        () => setRotatedImage(getRotatedImage(currImage, rotation)),
        () => setRotatedImage(null),
      );
    }
  }, [imageSrc, rotation]);

  return rotatedImage;
};

export default useRotateImage;

Di sini saya menggunakan semula elemen kanvas yang sama untuk mengurangkan penciptaan berulang. Kedua, perlu diingatkan bahawa saya menetapkan lebar dan ketinggiannya kepada 0 selepas setiap putaran untuk mengurangkan penggunaan memori. By the way, saya juga melakukan operasi membersihkan kanvas. Ini kerana dalam spesifikasi HTML apabila anda mengubah suai lebar dan ketinggian kanvas (sama ada ia sama seperti sebelumnya) akan mengosongkan kanvas, yang sama seperti canvasCtx2D.clearRect(0, 0, canvasWidth, canvasHeight), yang disokong oleh penyemak imbas moden.

Dalam useRotateImage, saya menyimpan rujukan kepada elemen imej dan menetapkan keadaan imej diputar selepas image.decode(), yang diselesaikan selepas data imej sedia.

Di bawah ialah kes penggunaan dalam talian:


Jika anda mendapati ini membantu, sila pertimbangkan melanggan surat berita saya untuk lebih banyak artikel dan alatan berguna tentang pembangunan web. Terima kasih kerana membaca!

Atas ialah kandungan terperinci Mencipta Cangkuk Reaksi untuk Memusing Imej di Mana-mana Sudut. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas

Tutorial PHP
1598
276
Jenis Bersyarat Lanjutan dalam TypeScript Jenis Bersyarat Lanjutan dalam TypeScript Aug 04, 2025 am 06:32 AM

Jenis Keadaan Lanjutan TypeScript Melaksanakan penghakiman logik antara jenis melalui Textendsu? X: Y Sintaks. Keupayaan terasnya ditunjukkan dalam jenis keadaan yang diedarkan, kesimpulan jenis kesimpulan dan pembinaan alat jenis kompleks. 1. Jenis bersyarat diedarkan dalam parameter jenis kosong dan secara automatik boleh memecah jenis bersama, seperti toarray untuk mendapatkan rentetan [] | number []. 2. Menggunakan Pengagihan untuk Membina Alat Penapisan dan Pengekstrakan: Tidak termasuk Kecualikan Jenis Melalui Textendsu? Tidak pernah: T, Ekstrak Ekstrak Persamaan melalui Textendsu? 3

Mikro Frontends Architecture: Panduan Pelaksanaan Praktikal Mikro Frontends Architecture: Panduan Pelaksanaan Praktikal Aug 02, 2025 am 08:01 AM

Microfrontendssolvescalingchallengesinlargeteamsbyenablingindependentdevelopmentanddeployment.1) chooseanInintegrationstration: useModulefederationInwebPack5formruntimeLoadingandtrueindectivence, Build-timeIntegrationForseMlesetups, Oriframes/Web

Apakah perbezaan antara var, biarkan, dan const dalam javascript? Apakah perbezaan antara var, biarkan, dan const dalam javascript? Aug 02, 2025 pm 01:30 PM

varisfunction-scoped, canbereassigned, omredwithundefined, andattachedtotheglobalwindowobject; 2.Letandconstareblock-scoped, withletallowingreassignmentandconstnotallowingit, everconstobjectscanhaveMutabeTerSties;

Apakah pilihan Chaining (?) Dalam JS? Apakah pilihan Chaining (?) Dalam JS? Aug 01, 2025 am 06:18 AM

Optionalchaining (?) InjavaScriptSafelyAccessSnestedPropertiesByReturningundefinedifanypartofthechainisnullorundefined, mencegahRuntimeerrors.1.itallowssafeaccesstodeperlynestedobjectproperties?

Menjana teka -teki coklat berganda yang diselesaikan: Panduan untuk struktur data dan algoritma Menjana teka -teki coklat berganda yang diselesaikan: Panduan untuk struktur data dan algoritma Aug 05, 2025 am 08:30 AM

Artikel ini meneroka secara mendalam bagaimana untuk menghasilkan teka-teki yang dapat diselesaikan secara automatik untuk permainan teka-teki double-choco. Kami akan memperkenalkan struktur data yang cekap - objek sel berdasarkan grid 2D yang mengandungi maklumat sempadan, warna, dan keadaan. Atas dasar ini, kami akan menghuraikan algoritma pengiktirafan blok rekursif (serupa dengan carian kedalaman pertama) dan bagaimana untuk mengintegrasikannya ke dalam proses penjanaan teka-teki berulang untuk memastikan teka-teki yang dihasilkan memenuhi peraturan permainan dan dapat diselesaikan. Artikel ini akan menyediakan kod sampel dan membincangkan pertimbangan utama dan strategi pengoptimuman dalam proses penjanaan.

Bagaimanakah anda boleh mengeluarkan kelas CSS dari elemen DOM menggunakan JavaScript? Bagaimanakah anda boleh mengeluarkan kelas CSS dari elemen DOM menggunakan JavaScript? Aug 05, 2025 pm 12:51 PM

Kaedah yang paling biasa dan disyorkan untuk membuang kelas CSS dari elemen DOM menggunakan JavaScript adalah melalui kaedah mengeluarkan () harta klasik. 1. Gunakan elemen.classlist.remove ('className') untuk memadamkan satu kelas tunggal atau berganda dengan selamat, dan tiada kesilapan akan dilaporkan walaupun kelas tidak wujud; 2. Kaedah alternatif adalah untuk mengendalikan harta kelas secara langsung dan mengeluarkan kelas dengan penggantian rentetan, tetapi mudah untuk menyebabkan masalah disebabkan oleh pemprosesan yang tidak tepat atau pemprosesan ruang yang tidak betul, jadi tidak disyorkan; 3. 4.Classlist

Apakah sintaks kelas dalam JavaScript dan bagaimana ia berkaitan dengan prototaip? Apakah sintaks kelas dalam JavaScript dan bagaimana ia berkaitan dengan prototaip? Aug 03, 2025 pm 04:11 PM

Sintaks kelas JavaScript adalah gula sintaks yang diwarisi oleh prototaip. 1. Kelas yang ditakrifkan oleh kelas pada dasarnya adalah fungsi dan kaedah ditambah kepada prototaip; 2. Contohnya mencari kaedah melalui rantaian prototaip; 3. Kaedah statik tergolong dalam kelas itu sendiri; 4. Memperluas mewarisi melalui rantaian prototaip, dan lapisan asas masih menggunakan mekanisme prototaip. Kelas tidak mengubah intipati warisan prototaip JavaScript.

Membina sistem reka bentuk dengan buku cerita dan bertindak balas Membina sistem reka bentuk dengan buku cerita dan bertindak balas Jul 30, 2025 am 05:05 AM

Pertama, gunakan NPXStoryBookInit untuk memasang dan mengkonfigurasi buku cerita dalam projek React, jalankan npmrunstorybook untuk memulakan pelayan pembangunan tempatan; 2. Mengatur struktur fail komponen mengikut fungsi atau jenis, dan buat fail .story.js yang sepadan untuk menentukan keadaan yang berbeza dalam setiap direktori komponen; 3. Gunakan sistem args dan kawalan buku cerita untuk mencapai pelarasan atribut dinamik untuk memudahkan ujian pelbagai keadaan interaktif; 4. Gunakan fail MDX untuk menulis dokumen teks yang kaya yang mengandungi spesifikasi reka bentuk, arahan kebolehaksesan, dan lain -lain, dan menyokong memuatkan MDX melalui konfigurasi; 5. Tentukan token reka bentuk melalui tema.js dan gunakan pratonton.js

See all articles