util.ts 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. /** Set canvas size taking `devicePixelRatio` into account */
  7. export function setCanvasSize(canvas: HTMLCanvasElement, width: number, height: number) {
  8. canvas.width = Math.round(window.devicePixelRatio * width)
  9. canvas.height = Math.round(window.devicePixelRatio * height)
  10. Object.assign(canvas.style, { width: `${width}px`, height: `${height}px` })
  11. }
  12. /** Resize canvas to container element taking `devicePixelRatio` into account */
  13. export function resizeCanvas (canvas: HTMLCanvasElement, container: Element) {
  14. let width = window.innerWidth
  15. let height = window.innerHeight
  16. if (container !== document.body) {
  17. let bounds = container.getBoundingClientRect()
  18. width = bounds.right - bounds.left
  19. height = bounds.bottom - bounds.top
  20. }
  21. setCanvasSize(canvas, width, height)
  22. }
  23. function _canvasToBlob(canvas: HTMLCanvasElement, callback: BlobCallback, type?: string, quality?: any) {
  24. const bin = atob(canvas.toDataURL(type, quality).split(',')[1])
  25. const len = bin.length
  26. const len32 = len >> 2
  27. const a8 = new Uint8Array(len)
  28. const a32 = new Uint32Array(a8.buffer, 0, len32)
  29. let j = 0
  30. for (let i = 0; i < len32; ++i) {
  31. a32[i] = bin.charCodeAt(j++) |
  32. bin.charCodeAt(j++) << 8 |
  33. bin.charCodeAt(j++) << 16 |
  34. bin.charCodeAt(j++) << 24
  35. }
  36. let tailLength = len & 3;
  37. while (tailLength--) a8[j] = bin.charCodeAt(j++)
  38. callback(new Blob([a8], { type: type || 'image/png' }));
  39. }
  40. export async function canvasToBlob(canvas: HTMLCanvasElement, type?: string, quality?: any): Promise<Blob> {
  41. return new Promise((resolve, reject) => {
  42. const callback = (blob: Blob | null) => {
  43. if (blob) resolve(blob)
  44. else reject('no blob returned')
  45. }
  46. if (!HTMLCanvasElement.prototype.toBlob) {
  47. _canvasToBlob(canvas, callback, type, quality)
  48. } else {
  49. canvas.toBlob(callback, type, quality)
  50. }
  51. })
  52. }