index.ts 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. // TIP: ctrl+cmd+t,生成函数注释
  2. import { getRangeRandom } from 'billd-utils';
  3. export function generateBase64(dom: CanvasImageSource) {
  4. const canvas = document.createElement('canvas');
  5. // @ts-ignore
  6. const { width, height } = dom.getBoundingClientRect();
  7. const rate = width / height;
  8. let ratio = 0.5;
  9. function geturl() {
  10. const coverWidth = width * ratio;
  11. const coverHeight = coverWidth / rate;
  12. canvas.width = coverWidth;
  13. canvas.height = coverHeight;
  14. canvas.getContext('2d')!.drawImage(dom, 0, 0, coverWidth, coverHeight);
  15. // webp比png的体积小非常多!因此coverWidth就可以不用压缩太夸张
  16. return canvas.toDataURL('image/webp');
  17. }
  18. let dataURL = geturl();
  19. while (dataURL.length > 1000 * 20) {
  20. ratio = ratio * 0.8;
  21. dataURL = geturl();
  22. }
  23. return dataURL;
  24. }
  25. /**
  26. * @description 获取随机字符串(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz)
  27. * @example: getRandomString(4) ===> abd3
  28. * @param {number} length
  29. * @return {*}
  30. */
  31. export const getRandomEnglishString = (length: number): string => {
  32. const str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
  33. let res = '';
  34. for (let i = 0; i < length; i += 1) {
  35. res += str.charAt(getRangeRandom(0, str.length - 1));
  36. }
  37. return res;
  38. };
  39. export const createVideo = ({ muted = true, autoplay = true }) => {
  40. const videoEl = document.createElement('video');
  41. videoEl.autoplay = autoplay;
  42. videoEl.muted = muted;
  43. videoEl.playsInline = true;
  44. videoEl.setAttribute('webkit-playsinline', 'true');
  45. videoEl.setAttribute('x5-video-player-type', 'h5');
  46. videoEl.setAttribute('x5-video-player-fullscreen', 'true');
  47. videoEl.setAttribute('x5-video-orientation', 'portraint');
  48. videoEl.oncontextmenu = (e) => {
  49. e.preventDefault();
  50. };
  51. // if (NODE_ENV === 'development') {
  52. videoEl.controls = true;
  53. // }
  54. return videoEl;
  55. };
  56. export function videoToCanvas(data: {
  57. videoEl: HTMLVideoElement;
  58. size?: { width: number; height: number };
  59. }) {
  60. const { videoEl } = data;
  61. if (!videoEl) {
  62. throw new Error('videoEl不能为空!');
  63. }
  64. const canvas = document.createElement('canvas');
  65. const ctx = canvas.getContext('2d')!;
  66. let timer;
  67. function drawCanvas() {
  68. if (data.size) {
  69. const { width, height } = data.size;
  70. canvas.width = width;
  71. canvas.height = height;
  72. ctx.drawImage(videoEl, 0, 0, width, height);
  73. // console.log('有size', width, height, performance.now());
  74. } else {
  75. // WARN safari没有captureStream方法
  76. const videoTrack = videoEl
  77. // @ts-ignore
  78. .captureStream()
  79. .getVideoTracks()[0];
  80. if (videoTrack) {
  81. const { width, height } = videoTrack.getSettings();
  82. canvas.width = width!;
  83. canvas.height = height!;
  84. ctx.drawImage(videoEl, 0, 0, width!, height!);
  85. // console.log('没有size', width, height, performance.now());
  86. }
  87. }
  88. timer = requestAnimationFrame(drawCanvas);
  89. }
  90. function stopDrawing() {
  91. cancelAnimationFrame(timer);
  92. }
  93. // document.body.appendChild(videoEl);
  94. drawCanvas();
  95. return { drawCanvas, stopDrawing, canvas, videoEl };
  96. }