Skip to content

Commit

Permalink
feat(useimage): add useImage hook
Browse files Browse the repository at this point in the history
  • Loading branch information
innocces committed Jul 26, 2021
1 parent 858fa52 commit 53b5dfd
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/app/src/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ export default {
'pages/useVibrate/index',
'pages/useMotion/index',
'pages/useBrightness/index',
// media
'pages/useImage/index',
],
window: {
backgroundTextStyle: 'light',
Expand Down
3 changes: 3 additions & 0 deletions packages/app/src/pages/useImage/index.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
navigationBarTitleText: 'useImage',
};
30 changes: 30 additions & 0 deletions packages/app/src/pages/useImage/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { useCallback } from 'react';
import { AtButton } from 'taro-ui';
import DocPage from '@components/DocPage';

import { useImage } from 'taro-hooks';

export default () => {
const [fileInfo, { choose, preview, save }] = useImage({});

return (
<>
<DocPage title="useImage 图片" panelTitle="useImage">
<AtButton onClick={() => choose()}>选择图片</AtButton>
<AtButton
disabled={!fileInfo.tempFilePaths}
className="gap"
onClick={() => preview({ urls: fileInfo.tempFilePaths })}
>
预览照片
</AtButton>
<AtButton
disabled={!fileInfo.tempFilePaths}
onClick={() => save(fileInfo.tempFilePaths[0])}
>
保存图片
</AtButton>
</DocPage>
</>
);
};
4 changes: 4 additions & 0 deletions packages/hooks/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ import useVibrate from './useVibrate';
import useMotion from './useMotion';
import useBrightness from './useBrightness';

// media
import useImage from './useImage';

export {
useEnv,
useLaunchOptions,
Expand Down Expand Up @@ -63,4 +66,5 @@ export {
useVibrate,
useMotion,
useBrightness,
useImage,
};
47 changes: 47 additions & 0 deletions packages/hooks/src/useImage/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
title: useImage
nav:
title: Hooks
path: /hooks
order: 2
group:
title: 媒体
path: /media
---

# useImage

图片操作, 如预览、获取、压缩等.

## 何时使用

当需要对图片进行操作时

## API

```jsx | pure
const [show, hide] = useLoading(initialOption);
```

## 参数说明

| 参数 | 说明 | 类型 | 默认值 |
| ------------- | ------------------------------------------ | -------------------- | ------ |
| initialOption | 初始提示框配置(若指定后面可与新的配置合并) | `General.IAnyObject` | - |

## 返回值说明

| 返回值 | 说明 | 类型 |
| ------ | -------------- | ------------------------------------------------ |
| show | 显示加载提示框 | `(options?: General.IAnyObject) => Promise<any>` |
| hide | 隐藏提示框 | `() => Promise<any>` |

## 代码演示

<code src="@pages/useImage" />

## Hook 支持度

| 微信小程序 | H5 | ReactNative |
| :--------: | :-: | :---------: |
| ✔️ | ✔️ | ✔️ |
136 changes: 136 additions & 0 deletions packages/hooks/src/useImage/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import {
saveImageToPhotosAlbum,
previewImage,
getImageInfo,
compressImage,
chooseImage,
chooseMessageFile,
General,
ENV_TYPE,
} from '@tarojs/taro';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useEnv } from '..';
import { saveImageForH5 } from './utils';

export type ChooseImageOption = Partial<
Pick<chooseImage.Option, 'count' | 'sizeType' | 'sourceType'>
>;

export type PreviewImageOption = Pick<previewImage.Option, 'current' | 'urls'>;

export type ChooseImageAction = (
option: ChooseImageOption,
) => Promise<chooseImage.SuccessCallbackResult>;

export type PreviewImageAction = (
option: PreviewImageOption,
) => Promise<General.CallbackResult>;

export type saveImageToPhotosAlbumAction = (
filePath: string,
) => Promise<General.CallbackResult>;

export type IFileInfo = Partial<
Pick<chooseImage.SuccessCallbackResult, 'tempFilePaths' | 'tempFiles'>
>;

export type IOptions = ChooseImageOption;

export interface IAction {
choose: ChooseImageAction;
preview: PreviewImageAction;
save: saveImageToPhotosAlbumAction;
}

function useImage(options: IOptions): [IFileInfo, IAction] {
const [fileInfo, setFileInfo] = useState<IFileInfo>({});
const env = useEnv();

const chooseImageAsync = useCallback<ChooseImageAction>((option) => {
const { count, sizeType, sourceType } = options;
const finalOptions = Object.assign(
{},
Object.fromEntries(
[
['count', count],
['sizeType', sizeType],
['sourceType', sourceType],
].filter((v) => v[1]) || [],
),
option || {},
);
return new Promise((resolve, reject) => {
try {
chooseImage({
...finalOptions,
success: (res) => {
console.log(res);
const { errMsg, ...fileInfo } = res;
setFileInfo(fileInfo);
resolve(res);
},
fail: reject,
}).catch(reject);
} catch (e) {
reject(e);
}
});
}, []);

const previewImageAsync = useCallback<PreviewImageAction>((option) => {
return new Promise((resolve, reject) => {
try {
previewImage({
...option,
success: resolve,
fail: reject,
}).catch(reject);
} catch (e) {
reject(e);
}
});
}, []);

const saveImageToPhotosAlbumAsync = useCallback<saveImageToPhotosAlbumAction>(
(filePath) => {
return new Promise(async (resolve, reject) => {
if (!filePath) {
reject('you must provide filePath');
} else {
try {
if (env === ENV_TYPE.WEB) {
const result = await saveImageForH5(filePath);
if (result) {
resolve({
errMsg: 'save success',
});
} else {
reject('save fail');
}
} else {
saveImageToPhotosAlbum({
filePath,
success: resolve,
fail: reject,
}).catch(reject);
}
} catch (e) {
reject(e);
}
}
});
},
[env],
);

return [
fileInfo,
{
choose: chooseImageAsync,
preview: previewImageAsync,
save: saveImageToPhotosAlbumAsync,
},
];
}

export default useImage;
25 changes: 25 additions & 0 deletions packages/hooks/src/useImage/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export const saveImageForH5 = async (filePath: string) => {
if (filePath) {
let result = true;
try {
const responese = await fetch(filePath);
console.log(responese);
const blob = await responese.blob();
const blobInstance = new Blob([blob], {
type: 'application/octet-stream',
});
const href = window.URL.createObjectURL(blobInstance);
const downloadElement = document.createElement('a');
downloadElement.href = href;
downloadElement.download = filePath.split('/').reverse()[0];
document.body.appendChild(downloadElement);
downloadElement.click();
document.body.removeChild(downloadElement);
window.URL.revokeObjectURL(href);
} catch (e) {
result = false;
}
return result;
}
return false;
};

0 comments on commit 53b5dfd

Please sign in to comment.