最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

node文件資源管理器的圖片預覽從零實現(xiàn)

 更新時間:2023年12月21日 15:38:25   作者:寒露  
這篇文章主要為大家介紹了node文件資源管理器的圖片預覽從零實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

 使用技術(shù)

  • 使用 Next.js 的 Image 組件顯示圖片。自帶圖片壓縮生成快速預覽的 webp 格式圖片
  • 使用 antd 的 PreviewGroup 組件實現(xiàn)原圖瀏覽,自帶縮小、放大、上一張、下一張等功能

功能實現(xiàn)

文件樹

explorer/src/app/path/[[...path]]/card-display.tsx
explorer/src/app/path/[[...path]]/page.tsx
explorer/src/components/preview/ext-rxp.tsx
explorer/src/components/preview/index.tsx
explorer/src/components/preview/proview-group-context.tsx
explorer/src/components/use-replace-pathname.ts

文件路徑:explorer/src/components/preview/ext-rxp.tsx

一些判斷文件后綴名方法

export const ImgRxp = /\.(jpg|jpeg|gif|png|webp|ico)$/i
const RawRxp = /\.(cr2|arw)/i
const GifRxp = /\.(gif)$/i
const ZipRxp = /\.(zip|rar|7z|tar\.xz|tar)(\.+\d+)?$/i
const VideoRxp = /\.(mp4|mkv|mov|wmv|avi|avchd|flv|f4v|swf)(\.+\d+)?$/i
export const isRaw = (path: string) => RawRxp.test(path)
export const isImage = (path: string) => ImgRxp.test(path)
export const isGif = (path: string) => GifRxp.test(path)
export const isZip = (path: string) => ZipRxp.test(path)
export const isVideo = (path: string) => VideoRxp.test(path)

文件路徑:explorer/src/components/preview/index.tsx

預覽封裝組件,根據(jù)是否為文件夾、視頻、圖片、壓縮包顯示不同的 icon。

點擊圖片時,使用 antd 的 PreviewGroup 組件查看原圖。

import React from 'react'
import { FileOutlined, FileZipOutlined, FolderOutlined, VideoCameraOutlined } from '@ant-design/icons'
import Image from 'next/image'
import { isGif, isImage, isVideo, isZip } from '@/components/preview/ext-rxp'
import { usePreviewGroupDispatch } from '@/components/preview/proview-group-context'
import { ReaddirItemType } from '@/explorer-manager/src/type'
import { useReplacePathname } from '@/components/use-replace-pathname'
const Preview: React.FC<{ item: ReaddirItemType }> = ({ item }) => {
  const previewGroupDispatch = usePreviewGroupDispatch()
  const { name, is_directory } = item
  const { staticPath, joinSearchPath } = useReplacePathname()
  if (is_directory) {
    return <FolderOutlined />
  }
  if (isVideo(name)) {
    return <VideoCameraOutlined />
  }
  if (isImage(name)) {
    const image_path = staticPath(name)
    return (
      <Image
        onClick={() => previewGroupDispatch(name)}
        src={image_path}
        alt={name}
        fill
        sizes="375px"
        style={{
          objectFit: 'scale-down', //"contain" | "cover" | "fill" | "none" | "scale-down"
        }}
        unoptimized={isGif(image_path)}
        placeholder="empty"
      />
    )
  }
  if (isZip(name)) {
    return <FileZipOutlined />
  }
  return <FileOutlined />
}
export default Preview

文件路徑:explorer/src/components/preview/proview-group-context.tsx

antd PreviewGroup 組件封裝。

需要在頂層目錄插入 PreviewGroupProvider 上下文組件,導出 usePreviewGroup、usePreviewGroupDispatch 讀寫方法。

'use client'
import React from 'react'
import { Image as AntdImage } from 'antd'
import { findIndex } from 'lodash'
import { isImage } from '@/components/preview/ext-rxp'
import { useReplacePathname } from '@/components/use-replace-pathname'
import createCtx from '@/lib/create-ctx'
import { useReaddirContext } from '@/app/path/readdir-context'
export const PreviewGroupContent = createCtx<string>()
export const usePreviewGroup = PreviewGroupContent.useStore
export const usePreviewGroupDispatch = PreviewGroupContent.useDispatch
const AntdImagePreviewGroup: React.FC<React.PropsWithChildren> = ({ children }) => {
  const { staticPath } = useReplacePathname()
  const readdir_list = useReaddirContext()
  const image_list = readdir_list.filter((item) => isImage(item.name))
  const name = usePreviewGroup()
  const previewGroupDispatch = usePreviewGroupDispatch()
  return (
    <AntdImage.PreviewGroup
      preview={{
        visible: !!name,
        current: findIndex(image_list, { name }),
        onVisibleChange: () => {
          previewGroupDispatch('')
        },
        onChange: (current) => {
          previewGroupDispatch(image_list[current].name)
        },
      }}
      items={image_list.map(({ name }) => staticPath(name))}
    >
      {children}
    </AntdImage.PreviewGroup>
  )
}
const PreviewGroupProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  return (
    <PreviewGroupContent.ContextProvider value={''}>
      <AntdImagePreviewGroup>{children}</AntdImagePreviewGroup>
    </PreviewGroupContent.ContextProvider>
  )
}
export default PreviewGroupProvider

文件路徑:explorer/src/components/use-replace-pathname.ts

添加一個獲取不同路徑的hooks

  • replace\_pathname 將不需要的一級路徑 /path/ 過濾掉
  • joinSearchPath 拼接過濾掉 /path/ 的 pathname
  • joinPath 拼接未過濾的 pathname
  • staticPath 拼接得到獲取文件地址
import { usePathname } from 'next/navigation'
export const pathExp = /(^\/)?path/
export const encodePathItem = (path: string) => {
  return path
    .split('/')
    .map((text) => encodeURIComponent(text))
    .join('/')
}
export const useReplacePathname = () => {
  const pathname = decodeURIComponent(usePathname() || '')
  const replace_pathname = pathname.replace(pathExp, '')
  const joinSearchPath = (path: string) => encodePathItem(`${replace_pathname}/${path}`)
  const joinPath = (path: string) => encodePathItem(`${pathname}/${path}`)
  const staticPath = (path: string) => `/static${joinSearchPath(path)}`
  return {
    pathname: pathname,
    replace_pathname: replace_pathname,
    joinSearchPath: joinSearchPath,
    joinPath: joinPath,
    staticPath: staticPath,
  }
}

文件路徑:explorer/src/app/path/[[...path]]/card-display.tsx

將 Preview 組件插入 List Item 內(nèi)

...
import Preview from '@/components/preview'
const CardDisplay: React.FC = () => {
  const pathname = usePathname()
  const readdir = useReaddirContext()
  const column = useCardColumnContext()
  return (
    <List
...
                  <div style={{ position: 'absolute', width: '100%', height: '100%' }}>
                    <Preview item={item} />
                  </div>
...

文件路徑:explorer/src/app/path/[[...path]]/page.tsx

將 PreviewGroupProvider 組件插入最頂部

...
import PreviewGroupProvider from '@/components/preview/proview-group-context'
const Page: React.FC = () => {
  const display_type = useDisplayTypeContext()
  return <PreviewGroupProvider>{display_type === 'table' ? <TableDisplay /> : <CardDisplay />}</PreviewGroupProvider>
}
export default Page

效果

git-repo

yangWs29/share-explorer

以上就是node文件資源管理器的圖片預覽從零實現(xiàn)的詳細內(nèi)容,更多關(guān)于node文件圖片預覽的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 三行命令切換Node.js版本的流程步驟

    三行命令切換Node.js版本的流程步驟

    如何在Windows上更新Node.js版本呢?有沒有那種不需要重新安裝軟件再修改配置文件和環(huán)境變量的方法?你是否還在為可能要重新安裝Node然后配置文件修改環(huán)境變量困擾?面就來介紹一下nvm更換node版本的步驟,需要的朋友可以參考下
    2024-01-01
  • node.js中的fs.appendFile方法使用說明

    node.js中的fs.appendFile方法使用說明

    這篇文章主要介紹了node.js中的fs.appendFile方法使用說明,本文介紹了fs.appendFile方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • nodejs實現(xiàn)遍歷文件夾并統(tǒng)計文件大小

    nodejs實現(xiàn)遍歷文件夾并統(tǒng)計文件大小

    這篇文章主要介紹了nodejs實現(xiàn)遍歷文件夾并統(tǒng)計文件大小,下面使用nodejs的遍歷文件夾文件內(nèi)容,并且讀取所有的文件,并采取排序往大到小的順序進行輸出,需要的朋友可以參考下
    2015-05-05
  • node的EventEmitter模塊基本用法簡單實現(xiàn)示例

    node的EventEmitter模塊基本用法簡單實現(xiàn)示例

    這篇文章主要為大家介紹了node的EventEmitter模塊基本用法簡單實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-09-09
  • node.js解決客戶端請求數(shù)據(jù)里面中文亂碼的事件方法

    node.js解決客戶端請求數(shù)據(jù)里面中文亂碼的事件方法

    本文主要介紹了node.js解決客戶端請求數(shù)據(jù)里面中文亂碼的事件方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • node實現(xiàn)socket鏈接與GPRS進行通信的方法

    node實現(xiàn)socket鏈接與GPRS進行通信的方法

    這篇文章主要介紹了node實現(xiàn)socket鏈接與GPRS進行通信的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-05-05
  • NodeJS項目如何打包成可執(zhí)行文件

    NodeJS項目如何打包成可執(zhí)行文件

    這篇文章主要介紹了NodeJS項目如何打包成可執(zhí)行文件問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • nodejs npm install全局安裝和本地安裝的區(qū)別

    nodejs npm install全局安裝和本地安裝的區(qū)別

    這篇文章主要介紹了nodejs npm install 全局安裝和非全局安裝的區(qū)別,即帶參數(shù)-g和不帶參數(shù)-g安裝的區(qū)別,需要的朋友可以參考下
    2014-06-06
  • Windows下安裝NodeJS的詳細步驟

    Windows下安裝NodeJS的詳細步驟

    這篇文章主要介紹了Windows下安裝NodeJS,本文分步驟通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08
  • 詳解node單線程實現(xiàn)高并發(fā)原理與node異步I/O

    詳解node單線程實現(xiàn)高并發(fā)原理與node異步I/O

    本篇文章主要介紹了node單線程實現(xiàn)高并發(fā)原理與node異步I/O ,具有一定的參考價值,有興趣的可以了解一下
    2017-09-09

最新評論

彰化县| 凌云县| 邹城市| 咸宁市| 辛集市| 双峰县| 高安市| 肃南| 伊春市| 聊城市| 科技| 正镶白旗| 西平县| 新晃| 乌鲁木齐县| 旬阳县| 辉南县| 吴川市| 台中县| 潜山县| 雷波县| 阿鲁科尔沁旗| 马山县| 曲水县| 禄劝| 湖州市| 平谷区| 嘉兴市| 视频| 长岭县| 彰武县| 双牌县| 益阳市| 郴州市| 汝阳县| 石狮市| 双城市| 瑞安市| 无棣县| 抚松县| 永宁县|