mirror of
https://github.com/XiaoDaiGua-Ray/ray-template.git
synced 2025-04-04 22:28:40 +08:00
145 lines
3.3 KiB
TypeScript
145 lines
3.3 KiB
TypeScript
/**
|
|
*
|
|
* @author Ray <https://github.com/XiaoDaiGua-Ray>
|
|
*
|
|
* @date 2023-12-14
|
|
*
|
|
* @workspace ray-template
|
|
*
|
|
* @remark 今天也是元气满满撸代码的一天
|
|
*/
|
|
|
|
import domToImage from 'dom-to-image'
|
|
import { unrefElement } from '@/utils'
|
|
|
|
import type { Options as ReDomToImageOptions } from 'dom-to-image'
|
|
import type { BasicTarget, TargetType } from '@/types/modules/vue'
|
|
|
|
export type ImageType = keyof typeof domToImageMethods
|
|
|
|
export type DomToImageResult = string | Blob | Uint8ClampedArray | undefined
|
|
|
|
export interface UseDomToImageOptions extends ReDomToImageOptions {
|
|
/**
|
|
*
|
|
*
|
|
* 指定图片类型,允许传递 imageType 参数,用于指定图片类型
|
|
*
|
|
* @default jpeg
|
|
*/
|
|
imageType?: ImageType
|
|
/**
|
|
*
|
|
*
|
|
* 在 dom 转换为图片之前执行
|
|
*
|
|
* @param element current dom
|
|
*/
|
|
beforeCreate?: <T extends TargetType = Element>(
|
|
element: T | null | undefined,
|
|
) => void
|
|
/**
|
|
*
|
|
* @param element current dom
|
|
* @param result dom to image result
|
|
*
|
|
* 在 dom 转换为图片之后执行
|
|
*/
|
|
created?: <T extends TargetType = Element>(
|
|
result: DomToImageResult,
|
|
element: T,
|
|
) => void
|
|
/**
|
|
*
|
|
* @param error dom to image error
|
|
*
|
|
* 在 dom 转换为图片失败时执行
|
|
*/
|
|
createdError?: (error?: Error) => void
|
|
/**
|
|
*
|
|
* @param element current dom
|
|
*
|
|
* 无论 dom 转换为图片成功或失败,都会执行
|
|
*/
|
|
finally?: () => void
|
|
}
|
|
|
|
const domToImageMethods = {
|
|
svg: domToImage.toSvg,
|
|
png: domToImage.toPng,
|
|
jpeg: domToImage.toJpeg,
|
|
blob: domToImage.toBlob,
|
|
pixelData: domToImage.toPixelData,
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param target ref dom
|
|
* @param options dom-to-image options
|
|
*
|
|
* 使用 dom-to-image 将 dom 转换为图片,基于 dom-to-image v2.6.0
|
|
* 拓展了 imageType 参数,用于指定图片类型
|
|
*
|
|
* create 方法支持在执行时传递 imageType 参数,用于指定图片类型。并且优先级大于 options.imageType
|
|
* 当然,你也可以不传递 imageType 参数,此时会使用 options.imageType
|
|
* 如果都未传递,则默认使用 jpeg
|
|
*
|
|
* @example
|
|
* const refDom = ref<HTMLElement>()
|
|
* const { create, stop } = useDomToImage(refDom, {
|
|
* beforeCreate: (element) => { ... },
|
|
* created: (element, result) => { ... },
|
|
* createdError: (element, error) => { ... },
|
|
* })
|
|
*/
|
|
export const useDomToImage = <T extends HTMLElement>(
|
|
target: BasicTarget<T>,
|
|
options?: UseDomToImageOptions,
|
|
) => {
|
|
const {
|
|
beforeCreate,
|
|
created,
|
|
createdError,
|
|
finally: _finally,
|
|
imageType: _imageType,
|
|
} = options ?? {}
|
|
|
|
const run = (
|
|
imageType?: UseDomToImageOptions['imageType'],
|
|
): Promise<DomToImageResult> => {
|
|
return new Promise((resolve, reject) => {
|
|
const element = unrefElement(target)
|
|
|
|
beforeCreate?.(element)
|
|
|
|
if (!element) {
|
|
createdError?.()
|
|
|
|
return reject('useDomToImage: element is undefined.')
|
|
}
|
|
|
|
domToImageMethods[imageType ?? _imageType ?? 'jpeg']?.(element, options)
|
|
.then((res) => {
|
|
created?.(res, element)
|
|
|
|
return resolve(res)
|
|
})
|
|
.catch((error: Error) => {
|
|
createdError?.(error)
|
|
|
|
return reject(error)
|
|
})
|
|
.finally(() => {
|
|
_finally?.()
|
|
})
|
|
})
|
|
}
|
|
|
|
return {
|
|
create: run,
|
|
}
|
|
}
|
|
|
|
export type UseDomToImageReturnType = ReturnType<typeof useDomToImage>
|