成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

2022強(qiáng)力之作:一款超精致的圖片預(yù)覽組件

開發(fā) 前端
react-photo-view 擁有無與倫比的預(yù)覽交互體驗(yàn):從打開圖像開始,每一幀的動(dòng)畫、細(xì)節(jié)和交互都經(jīng)過了精心設(shè)計(jì)與反復(fù)調(diào)試,媲美原生圖片預(yù)覽的效果。

我剛接觸前端這個(gè)行業(yè)的時(shí)候就有一個(gè)想法,那就是寫一個(gè)超炫酷的圖片預(yù)覽畫廊。還記得當(dāng)時(shí)用美圖看看看,那輕快的速度和交互很是令人著迷。

該組件在幾年前已經(jīng)發(fā)布不完全版,后面斷斷續(xù)續(xù)的維護(hù),總感覺差了點(diǎn)什么。今年春節(jié)沒休息,全搭在上面進(jìn)行開發(fā),現(xiàn)在總算是完美實(shí)現(xiàn)!先看看效果:

縮略圖完美漸變:

指定位置放大:

減速滾動(dòng):

什么是 react-photo-view

react-photo-view 擁有無與倫比的預(yù)覽交互體驗(yàn):從打開圖像開始,每一幀的動(dòng)畫、細(xì)節(jié)和交互都經(jīng)過了精心設(shè)計(jì)與反復(fù)調(diào)試,媲美原生圖片預(yù)覽的效果。

pnpm i react-photo-view

概覽:

import { PhotoProvider, PhotoView } from'react-photo-view';
import'react-photo-view/dist/react-photo-view.css';

exportdefaultfunction MyComponent() {
return (
<PhotoProvider>
<PhotoView src="/1.jpg">
<img src="/1-thumbnail.jpg" alt="" />
</PhotoView>
</PhotoProvider>
);
}

為什么要單獨(dú)開發(fā)它?

當(dāng)然想實(shí)現(xiàn)它的執(zhí)念也算一個(gè)方面,但根本原因是在 React 強(qiáng)大的生態(tài)中根本找不到一個(gè)好用的圖片預(yù)覽方案。當(dāng)時(shí)奉行拿來主義,在網(wǎng)上找了一圈基于 React 放大預(yù)覽組件庫,結(jié)果令我有點(diǎn)意外,圖片放大預(yù)覽的庫的數(shù)量明顯比不上輪播組件庫。更令人窒息的是這些少得可憐的組件庫中,其中一大半都是基于 PhotoSwipe 這個(gè)開源庫進(jìn)行的二次封裝。除此之外,能用于實(shí)際生產(chǎn)的預(yù)覽組件庫……好像沒有(也可能是我找不到),這種情況不僅體現(xiàn)在 React 庫上,其他框架 Vue 乃至是原生的相關(guān)庫都是如此。

當(dāng)然 PhotoSwipe 也不是不能用,但原生操作 DOM 的寫法在 React 中格格不入,其體積也是在 gzip 12KB 之上了,顯得有點(diǎn)臃腫了,便有了這個(gè)大膽的想法。

它有多優(yōu)秀?

它擁有非常完善的細(xì)節(jié)與特性:

  • 支持觸摸手勢,拖動(dòng)/平移/物理效果滑動(dòng),雙指指定位置放大/縮小
  • 全方面動(dòng)畫銜接,打開/關(guān)閉/回彈/觸邊,順其自然的交互效果
  • 圖像自適應(yīng),以一個(gè)合適的最初呈現(xiàn)大小,并根據(jù)調(diào)整自適應(yīng)
  • 支持自定義如 或任意 HTML 元素的預(yù)覽
  • 鍵盤導(dǎo)航,完美適配桌面端
  • 支持自定義節(jié)點(diǎn)擴(kuò)展,輕松實(shí)現(xiàn)全屏預(yù)覽、旋轉(zhuǎn)控制、圖片介紹以及更多功能
  • 基于 typescript,7KB Gzipped,支持服務(wù)端渲染
  • 簡單易用的 API,上手零成本

還導(dǎo)出了支持 ES2017 以上的 JS,可以做到 6KB Gzipped。在如此的體積上加上非常多的體驗(yàn)細(xì)節(jié)實(shí)屬不容易,更多的功能可以通過非常容易的自定義渲染來實(shí)現(xiàn),這與 React 理念完美契合,從而可以避免內(nèi)置一些非剛需的功能。

流行庫對(duì)比

以下表格統(tǒng)計(jì)了大部分場景所需功能,展示 react-photo-view 、 PhotoSwipe 和 rc-image(ant-design) 對(duì)比:

友好的文檔

還有什么比文檔更重要了,為此,我還準(zhǔn)備了一個(gè)超漂亮的文檔(目前只有中文,以后有時(shí)間在翻譯吧~)

https://react-photo-view.vercel.app/ 文末查看原文可預(yù)覽

實(shí)現(xiàn)歷程

圖片跟隨手指滾動(dòng)

在 onTouchStart 時(shí)記錄當(dāng)前觸發(fā)位置狀態(tài),在 onTouchMove 時(shí)讓其跟隨手指移動(dòng),onTouchEnd 解除跟隨就可以簡單實(shí)現(xiàn)。

觸邊位置反饋使圖片切換都是需要慢慢琢磨細(xì)節(jié):在 onTouchStart 之后移動(dòng)如果立即讓圖片跟隨手指移動(dòng)的話會(huì)帶來許多誤操作,比如本想讓他切換圖片卻走了上下滑動(dòng)的邏輯。這時(shí)候就需要一個(gè) 20px 的移動(dòng)緩沖來預(yù)判手指移動(dòng)方向。

指定圖片位置進(jìn)行放大

使用 transform: scale(value) 可以實(shí)現(xiàn)對(duì)圖片的縮放,但是都是對(duì)圖片中心進(jìn)行放大,縮放的結(jié)果可能不是想要的。起初打算用 transform-origin 來實(shí)現(xiàn),想法是美好的,雖然第一次在指定的位置能夠進(jìn)行放大。倘若縮小的位置不是原來的位置就會(huì)產(chǎn)生混亂跳動(dòng),很顯然這個(gè)方式不行。

后來思來想去睡不著,在睡夢中發(fā)現(xiàn)了靈感:便于計(jì)算理解,我們?cè)O(shè)圖片中心點(diǎn)為 0, 任何指定位置的放大縮小,即改變圖片中心的位置。比如圖片寬度 200,中心點(diǎn)位置為 100,基于最左側(cè)位置放大一倍。現(xiàn)在圖片寬度 400,那么中心點(diǎn)的位置應(yīng)為 200。那么總結(jié)公式如下:

const centerClientX = innerWidth / 2;
// 坐標(biāo)偏移轉(zhuǎn)換
const lastPositionX = centerClientX + lastX;
// 縮放偏移
const offsetScale = nextScale / scale;
// 最終偏移位置
const originX = clientX - (clientX - lastPositionX) * offsetScale - centerClientX;

這種模式計(jì)算能承擔(dān)各種位置響應(yīng),比如雙指縮放、雙指滾動(dòng)+縮放、邊緣計(jì)算等等。

雙指之間的距離

這里需要初中時(shí)直角三角勾股定理:

Math.sqrt((nextClientX - clientX) ** 2 + (nextClientY - clientY) ** 2);

模擬滾動(dòng)操作

之前的版本使用 transition 實(shí)現(xiàn),通過手指滑動(dòng)開始結(jié)束的時(shí)間差,計(jì)算出初始速度,估摸著用 transition 模擬出一個(gè)距離讓眼睛看起來有滾動(dòng)效果 ??。但這種方式體驗(yàn)始終差很多。后面結(jié)合高中物理公式模擬出滾動(dòng)效果:

加速運(yùn)動(dòng):

空氣阻力:

CρS 都是常數(shù),干脆都搞成一個(gè)量好了。至于怎么出這個(gè)量大小……試出來的 ?? 這樣就只與 v 平方成正比了。

另外因?yàn)楹瓦\(yùn)動(dòng)方向相反,取個(gè) 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 支持縮略圖裁切,不過需要手動(dòng)指定圖片寬高和 data-cropped,相當(dāng)麻煩。react-photo-view 通過讀取縮略圖 getComputedStyle(element).objectFit 來獲取當(dāng)前裁切參數(shù)。實(shí)現(xiàn)自動(dòng)裁切效果。

兼容性處理

因?yàn)槊繌垐D片都是一個(gè)合成層,這會(huì)消耗相當(dāng)多的內(nèi)存。IOS 上對(duì)于內(nèi)存有相當(dāng)大的限制,如果圖片在放大的情況一直使用 scale,那么在 Safari 上會(huì)顯得非常模糊。現(xiàn)在通過每次在運(yùn)動(dòng)完成后,都改變圖片的寬高為指定的值,然后重設(shè) scale 為 1,這種方式應(yīng)該本身需要達(dá)到的效果吧。

責(zé)任編輯:姜華 來源: 前端星辰
相關(guān)推薦

2020-06-01 16:45:44

Linux終端Terminus

2024-02-23 08:13:25

Excalidraw白板工具開源

2023-01-29 07:49:57

2011-09-08 17:31:29

Steply社交圖片

2022-07-04 08:48:36

KubernetesDatreeLinux

2021-04-02 10:14:02

詐騙軟件Fleeceware軟應(yīng)用

2020-12-03 09:33:58

前端開發(fā)工具

2016-09-19 13:44:54

vue翻頁組件Web

2021-08-25 11:10:41

GitHub命令Linux

2017-07-11 08:57:07

功能超融合架構(gòu)

2021-09-14 08:38:57

組件開源前端

2012-06-15 10:33:06

JavaScript

2021-11-16 14:55:50

命令行Linux開源

2014-12-31 15:26:57

iOS8iMessageswift

2023-02-24 16:08:09

ArkUI組件應(yīng)用文件管理器

2024-02-26 12:02:37

Python數(shù)據(jù)可視化D3blocks

2014-12-16 10:11:22

2024-08-16 08:31:05

2021-07-23 16:50:19

httpJava框架

2021-09-28 20:19:54

APKAndroid流程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 午夜看电影在线观看 | 国产不卡一区 | 日本黄色一级视频 | 精品成人佐山爱一区二区 | 欧美日韩成人一区二区 | 99精品国自产在线 | 精品一区在线 | 亚洲一区二区三区四区在线观看 | 成人妇女免费播放久久久 | 中文字幕av中文字幕 | 99免费视频| 国产精品久久久久久久久久久久 | h视频在线观看免费 | 国产视频久久 | 亚洲国产精品久久 | 九九亚洲| 一二三四在线视频观看社区 | 精品日韩一区 | 亚洲精品一区二区二区 | 久久久精品久久 | 日本三级网站在线观看 | 国产一在线观看 | 欧美精品一区三区 | 精品久久不卡 | 日日夜夜天天久久 | 天天天天操 | av网站免费 | 亚洲一区二区三区四区五区午夜 | 欧美一级高清片 | 一区欧美 | 天天干天天爽 | 在线资源视频 | 国产wwwcom | 久久男人 | 成人毛片网 | 亚洲精品www.| 国产综合久久久久久鬼色 | 欧美a在线 | 国产精品揄拍一区二区 | 成人免费观看男女羞羞视频 | 东方伊人免费在线观看 |