Start with an HTML2Canvas hooks

import React from 'react'
import html2Canvas from 'html2canvas'

type UseHtml2Canvas = (opt: {
  dom_id: string
  html_2_canvas_option: Html2Canvas.Html2CanvasOptions
}) => [string.(a)= > 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((a)= > {
    html2Canvas(document.getElementById(dom_id), html_2_canvas_option).then((canvas) = > {
      changeSaveImg(canvas.toDataURL('image/jpeg'))})}, [])return [save_img, create_save_img]
}
Copy the code

Here’s another example of a call

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>
  )
}

Copy the code

Pay attention to the point

  1. Date: July 18, 2020,html2canvasuse1.0.0 - rc. 5Version,iosThere will be no display on the device.thenThe function will not be called back and will not report an error. Please downgrade mandatory use1.0.0 - rc. 4Version. (Note the “^1.0.0-rc.4” in package.json^I want to get rid of symbols.)
  2. alldomWithin theThe pictureCan’tCross domainOtherwise, it will cause strange problems such as a blank screen. Even withuseCORSallowTaintYou can’t fix it. The browser console just printsCORSRelated errors were reported.
  3. The sharpness of the generated image depends on the quality of the original imagewidth,height,windowWidth,windowHeight,scaleImpact. Adjust these parameters based on the actual situation.
  4. If the generatedbase64If the picture is too large, the picture cannot be displayed. Please reduce the size accordingly3Several parameter values in.
  5. Cannot convert images toBlobAlthough the device can normally display the picture, it cannot save it by long pressing. The saved picture may be a blank image.
  6. In the specifieddomTo generate the imageoffsetTopwithoffsetLeftImpact. For example,offsetTop20When generated on top of the picture20pxThe distance (not 20px) will be setbackgroundColor(default white) Color fill. At this point, you can usexwithyParameters are corrected.
  7. If the cross-domain situation persists, or the image never appears, consider converting the image resource tobase64. For example, the two-dimensional code picture link has not appeared on some devices, you can consider the interface directly return the two-dimensional code content, by the front end according to the returned content to create a two-dimensional code.
  8. Try switching when you still have some weird problemshtml2canvasVersion.

Attach a hooks to create a QR code

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((a)= > {
    QRCode.toDataURL(QR_content, {margin: 0}, (err, url) = > {
      changeQR(url)
    })
  }, [QR_content])

  return [qr]
}
Copy the code