2022 강력한 작품: 정교한 사진 미리 보기 구성 요소
이 구성 요소는 몇 년 전에 불완전한 버전을 발표했는데, 간헐적인 유지보수를 거친 후, 항상 문제가 있다고 느낀다.올해는 쉬지 않고 모든 개발이 그 위에서 이루어졌다.이제 드디어 이루어졌어!우선 효과를 살펴보자.
완벽한 그래디언트:
지정된 위치에서 확대:
스크롤 속도 늦추기
예
react-photo-view
react-photo-view
has an unparalleled preview interaction experience: starting from the opening of the image, the animation, details and interaction of each frame have been carefully designed and repeatedly debugged, which is comparable to the effect of native image preview.
pnpm i react-photo-view
개요:import { PhotoProvider, PhotoView } from 'react-photo-view';
import 'react-photo-view/dist/react-photo-view.css';
export default function MyComponent() {
return (
<PhotoProvider>
<PhotoView src="/1.jpg">
<img src="/1-thumbnail.jpg" alt="" />
</PhotoView>
</PhotoProvider>
);
}
왜 단독으로 개발해야 합니까?
물론 이를 실현하는 데 열중하는 것도 한 방면이지만 근본적인 원인은
React
의 강력한 생태계에서 사용하기 쉬운 이미지 미리보기 솔루션이 아예 없기 때문이다.당시에 나는 사용 원칙에 따라 인터넷에서 React
기반의 축소 미리보기 구성 요소 라이브러리를 찾았다.결과는 나를 좀 놀라게 했다.그림 크기 조정 미리 보기 라이브러리의 수량은 회전 목마 모듈 라이브러리와 비교할 수 없습니다.더 숨막힐 것은 대부분의 보잘것없는 구성 요소 라이브러리는 PhotoSwipe
소스 라이브러리의 2차 봉인을 기반으로 한다.또한 실제 생산에서 사용할 수 있는 미리 보기 어셈블리 라이브러리...없는 것 같다(또는 내가 찾을 수 없을 수도 있다). 이런 상황은 React
라이브러리에 반영될 뿐만 아니라 다른 프레임워크Vue
는 심지어 본 컴퓨터와 관련된 라이브러리에도 나타난다.물론
PhotoSwipe
는 사용할 수 없는 것이 아니지만 본 기기의 조작DOM
은 React
에서 적합하지 않고 용량도 gzip 12KB
보다 높아서 좀 비대하다. 그래서 나는 이런 대담한 생각을 가지고 있다.얼마나 좋아요?
이 제품은 매우 정교한 세부 사항과 기능을 갖추고 있다.
<video>
또는 HTML
요소 typescript
, 7KB Gzipped
, 서버측 렌더링 지원API
, 제로 스타트 비용JS
및 이상ES2017
을 출력하고 실현할 수 있다6KB Gzipped
.이런 책에 대량의 체험 디테일을 첨가하는 것은 결코 쉽지 않다.매우 간단한 사용자 정의 렌더링을 통해 더 많은 기능을 실현할 수 있다. 이것은 React
의 개념에 완전히 부합되고 불필요한 내장 기능을 피할 수 있다.유행 도서관 비교
다음 표는 대부분의 장면에 필요한 기능을 요약하고
react-photo-view
,PhotoSwipe
와 rc-image
(ant 디자인)의 비교를 나타낸다.반응 사진 보기
Photosweep
rc 이미지
줄다
19KB
47KB
40KB
축소 + 압축
7.3KB
12KB
14KB
기본 미리 보기
뒷받침
뒷받침
뒷받침
미리 보기 전환
뒷받침
뒷받침
지원되지 않음
휴대폰
뒷받침
뒷받침
지원되지 않음
완벽한 경도
뒷받침
뒷받침
지원되지 않음
미리 보기 자르기 애니메이션
뒷받침
지원(수동 지정 필요)
지원되지 않음
이미지 크기 조정
뒷받침
지원되지 않음(수동 지정 필요)
뒷받침
퇴로
뒷받침
지원되지 않음
뒷받침
마우스 휠 크기 조절
뒷받침
지원되지 않음
(부족한 위치)
춘권
뒷받침
뒷받침
지원되지 않음
애니메이션 매개변수 조정
뒷받침
뒷받침
지원되지 않음
사용이 간편한 API
뒷받침
지원되지 않음
뒷받침
타자 원고
뒷받침
지원되지 않음
뒷받침
키보드 탐색
뒷받침
뒷받침
뒷받침
사용자 정의 요소
뒷받침
XSS 위험
지원되지 않음
제약의를 받는다
뒷받침
뒷받침
뒷받침
순환 미리 보기
뒷받침
뒷받침
지원되지 않음
번갈아
뒷받침
지원되지 않음
뒷받침
도구막대 사용자화
뒷받침
뒷받침
지원되지 않음
전체 화면
사용자 지정 확장
뒷받침
지원되지 않음
우호적인 문서
문서보다 더 중요한 게 뭐가 있겠습니까? 그래서 저는 아주 예쁜 문서를 준비했습니다.
https://react-photo-view.vercel.app/
실현 과정
그림이 손가락으로 굴러가다
onTouchStart
에서 현재 촉발 위치 상태를 기록하여 onTouchMove
의 손가락을 따라 움직이게 하고 onTouchEnd
를 쉽게 실현할 수 있다.터치 위치 피드백으로 인해 화면 전환은 세부적인 것을 천천히 생각해야 한다. 이동한 후
onTouchStart
화면이 손가락을 따라 바로 이동하면 많은 오류 조작을 가져올 수 있다. 예를 들어 화면을 전환할 때 위아래로 미끄러지는 논리이다.이때 손가락이 움직이는 방향을 예측하기 위해20px
버퍼를 이동해야 한다.확대할 이미지 위치 지정하기
transform: scale(value)
를 사용하여 이미지를 배율 조정하지만 이미지의 중심이 확대되어 원하는 결과가 아닐 수 있습니다.처음에는 transform-origin
로 실현하려고 했는데, 이 생각은 매우 좋았다. 비록 처음에는 지정된 위치에서 확대할 수 있었지만.복원 위치가 원래 위치가 아니면 혼란이 일어난다.분명히 이런 방법은 통하지 않는다.나중에 생각해 보니 잠이 오지 않았다. 꿈에서 영감을 발견했다. 계산과 이해에 편리하도록 우리는 그림의 중심점
0
을 설정했다. 지정된 위치를 확대하고 축소하는 것은 그림의 중심 위치를 바꾸는 것을 의미한다.예를 들어, 이미지 폭200
, 중심점 위치100
및 맨 왼쪽 위치를 기준으로 두 배가 됩니다.현재 그림의 폭은 400
이고 중심점의 위치는 200
일 것이다.그러면 요약 공식은 다음과 같습니다.const centerClientX = innerWidth / 2;
// Coordinate offset conversion
const lastPositionX = centerClientX + lastX;
// zoom offset
const offsetScale = nextScale / scale;
// final offset position
const originX =
clientX - (clientX - lastPositionX) * offsetScale - centerClientX;
이런 계산 모델은 축소, 축소, 스크롤 + 축소, 테두리 계산 등 다양한 위치 응답을 나타낼 수 있다.손가락 사이
이것은 직각 삼각형의 피타고라스정리가 필요하다.
Math.sqrt((nextClientX - clientX) ** 2 + (nextClientY - clientY) ** 2);
아날로그 스크롤
이전 버전은
transition
로 구현되었습니다.손가락 슬라이딩의 시작과 끝 사이의 시간차를 통해 초기 속도를 계산하고 transition
시뮬레이션 거리로 눈을 굴리는 효과처럼 보일 것으로 추정한다😂. 그러나 이런 경험은 항상 훨씬 나쁘다.그 다음에 고등학교 물리 공식을 결합시켜 스크롤 효과를 모의했다.빠른 이동성:
공기 저항력:
CρS
는 모두 상수이기 때문에 그것들을 하나의 양으로 설정하면 된다.이 돈을 어떻게 얻었는지...해봤어요.😂 이는 v
의 제곱과 정비례할 뿐이다.또한 운동 방향과 반대로 하기 때문에
v
의 방향, 즉 Math.sign(-v)
을 취한다.function scrollMove(
initialSpeed: number,
callback: (spatial: number) => boolean,
) {
const acceleration = -0.002;
const resistance = 0.0002;
let v = initialSpeed;
let s = 0;
let lastTime: number | undefined = undefined;
let frameId = 0;
const calcMove = (now: number) => {
if (!lastTime) {
lastTime = now;
}
const dt = now - lastTime;
const direction = Math.sign(initialSpeed);
const a = direction * acceleration;
const f = Math.sign(-v) * v ** 2 * resistance;
const ds = v * dt + ((a + f) * dt ** 2) / 2;
v = v + (a + f) * dt;
s = s + ds;
// move to s
lastTime = now;
if (direction * v <= 0) {
cancelAnimationFrame(frameId);
return;
}
if (callback(s)) {
frameId = requestAnimationFrame(calcMove);
return;
}
cancelAnimationFrame(frameId);
};
frameId = requestAnimationFrame(calcMove);
}
축약작물
PhotoSwipe
축소판 이미지 트림은 지원되지만 이미지의 폭과 높이를 수동으로 지정해야 합니다data-cropped
.react-photo-view
미리 보기 그림getComputedStyle(element).objectFit
을 읽으면 현재 재단 파라미터를 얻을 수 있습니다.자동 재단 효과를 실현하다.호환성 처리
모든 이미지는 하나의 복합층이기 때문에 대량의 메모리를 소모할 수 있다.
IOS
는 상당히 큰 메모리 제한이 있는데 만약에 이미지가 확대할 때 항상 scale
를 사용한다면 Safari
의 이미지는 매우 모호해 보일 것이다.이제 이동이 완료될 때마다 이미지의 너비와 높이를 지정된 값으로 변경한 다음 scale
을 1로 재설정하면 원하는 효과를 얻을 수 있습니다.기타
PhotoSwipe
의 저자는 키예프에 거주하는 우크라이나인으로 키예프를 탈출해 현재 가족과 함께 우크라이나 서부에서 무사하며 전후에 원기를 회복하기를 바란다.후기
나는
react-photo-view
의 세부 사항에 많은 시간을 썼다. 만약 네가 좋아한다면 Star
를 눌러서 나를 도와줄 수 있다.https://github.com/MinJieLiu/react-photo-view
감사합니다!
Reference
이 문제에 관하여(2022 강력한 작품: 정교한 사진 미리 보기 구성 요소), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/minjieliu/2022-powerful-work-an-ultra-delicate-picture-preview-component-2ia3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)