先准备一个 html2canvas
的 hooks
import React from 'react'
import html2Canvas from 'html2canvas'
type UseHtml2Canvas = (opt: {
dom_id: string
html_2_canvas_option: Html2Canvas.Html2CanvasOptions
}) => [string, () => void]
export const useHtml2Canvas: UseHtml2Canvas = ({
dom_id,
html_2_canvas_option = {
useCORS: true,
scale: devicePixelRatio,
width: window.innerWidth,
height: window.innerHeight,
windowWidth: window.innerWidth,
windowHeight: window.innerHeight,
},
}) => {
const [save_img, changeSaveImg] = React.useState(undefined)
const create_save_img = React.useCallback(() => {
html2Canvas(document.getElementById(dom_id), html_2_canvas_option).then((canvas) => {
changeSaveImg(canvas.toDataURL('image/jpeg'))
})
}, [])
return [save_img, create_save_img]
}
再来一个调用示例
import React from 'react'
import {useHtml2Canvas} from '@com/use-html-2-canvas'
const list = Array.from({length: 20}).map((v, k) => k)
const randomColor = () => {
const random = () => Math.round(Math.random() * 255)
return `rgb(${random()}, ${random()}, ${random()})`
}
export default () => {
const [img_src, createSaveImg] = useHtml2Canvas({
dom_id: 'test-save-img',
html_2_canvas_option: {
useCORS: true,
scale: devicePixelRatio,
width: window.innerWidth,
height: window.innerHeight,
windowWidth: window.innerWidth,
windowHeight: window.innerHeight,
},
})
React.useEffect(() => {
createSaveImg()
}, [])
return (
<div>
{img_src && <img src={img_src} alt="" style={{width: '100vw', height: '20vh'}} />}
<ul style={{width: '100vw', height: '100vh'}} id="test-save-img">
{list.map((text, key) => (
<li key={key} style={{height: `${100 / list.length}vh`, backgroundColor: `${randomColor()}`}}>
{text}
</li>
))}
</ul>
</div>
)
}
注意点
- 时间:2020年07月18日,
html2canvas
使用1.0.0-rc.5
版本,ios
设备上会没有任何显示。then
函数不会被回调也不会报错。请降级强制使用1.0.0-rc.4
版本。(注意package.json 内的 "^1.0.0-rc.4"^
符号要去掉) - 所有
dom
内的图片
不能跨域
,否则会导致白屏等奇怪问题。即使加上useCORS
与allowTaint
也无法解决,浏览器控制台直接会打印CORS
相关报错。 - 生成的图片清晰度受原始图片的质量与
width
、height
、windowWidth
、windowHeight
、scale
影响,请根据实际情况来调节这几个参数。 - 如果生成的
base64
图片过大,会导致图片无法显示,请相应减小3
中的几个参数值。 - 不可将图片转换为
Blob
的形式,设备虽然可以正常显示图片,但是无法进行长按保存,保存下来的图片可能为一个空白的图像。 - 在指定
dom
来生成图片时,会受offsetTop
与offsetLeft
影响。例如offsetTop
为20
时,生成的图片顶部20px
(不一定为 20px)的距离会被所设置的backgroundColor
(默认白色)颜色填充。这时,可使用x
与y
参数进行校正。 - 如果一直出现跨域的情况,或者图片一直不出现的情况,可考虑将图片资源转换成
base64
。例如就遇到二维码图片链接某些设备上一直不出现,则可以考虑接口直接返回二维码内容,由前端根据返回的内容来创建二维码。 - 当还出现一些奇奇怪怪的问题时,可尝试切换
html2canvas
版本。
附上一个创建二维码的 hooks
import React from 'react'
import QRCode from 'qrcode'
type UseCreateQR = (QR_content: string) => [string]
export const useCreateQR: UseCreateQR = (QR_content) => {
const [qr, changeQR] = React.useState('')
React.useEffect(() => {
QRCode.toDataURL(QR_content, {margin: 0}, (err, url) => {
changeQR(url)
})
}, [QR_content])
return [qr]
}