Coder Social home page Coder Social logo

qq15725 / modern-screenshot Goto Github PK

View Code? Open in Web Editor NEW
412.0 4.0 29.0 2.11 MB

📸 Quickly generate image from DOM node using HTML5 canvas and SVG

Home Page: https://modern-screenshot.vercel.app

License: MIT License

TypeScript 97.21% HTML 0.98% CSS 1.81%
canvas dom image javascript screenshot svg typescript dom-to-image html2canvas html-to-image

modern-screenshot's Introduction

modern-screenshot

Minzip Version Downloads Issues License

Quickly generate image from DOM node using HTML5 canvas and SVG

Fork from html-to-image

English | 简体中文

📦 Install

npm i modern-screenshot

🦄 Usage

import { domToPng } from 'modern-screenshot'

domToPng(document.querySelector('#app')).then(dataUrl => {
  const link = document.createElement('a')
  link.download = 'screenshot.png'
  link.href = dataUrl
  link.click()
})
CDN
<script src="https://unpkg.com/modern-screenshot"></script>
<script>
  modernScreenshot.domToPng(document.querySelector('body')).then(dataUrl => {
    const link = document.createElement('a')
    link.download = 'screenshot.png'
    link.href = dataUrl
    link.click()
  })
</script>


Browser Console

⚠️ Partial embedding will fail due to CORS

const script = document.createElement('script')
script.src = "https://unpkg.com/modern-screenshot"
document.getElementsByTagName('head')[0].appendChild(script)

script.onload = () => {
  modernScreenshot
    .domToImage(document.querySelector('body'), {
      debug: true,
      progress: (current, total) => {
        console.log(`${ current }/${ total }`)
      }
    })
    .then(img => {
      const width = 600
      const height = img.height * (width / img.width)
      console.log('%c ', [
        `padding: 0 ${ width / 2 }px;`,
        `line-height: ${ height }px;`,
        `background-image: url('${ img.src }');`,
        `background-size: 100% 100%;`,
      ].join(''))
    })
}


Methods

method(node: Node, options?: Options)

DOM to dataURL

DOM to data

DOM to HTMLElement

Options

See the options.ts

Singleton context and web worker

Quick screenshots per second by reusing context and web worker

// use vite
import workerUrl from 'modern-screenshot/worker?url'
import { createContext, destroyContext, domToPng } from 'modern-screenshot'

async function screenshotsPerSecond() {
  const context = await createContext(document.querySelector('#app'), {
    workerUrl,
    workerNumber: 1,
  })
  for (let i = 0; i < 10; i++) {
    domToPng(context).then(dataUrl => {
      const link = document.createElement('a')
      link.download = `screenshot-${ i + 1 }.png`
      link.href = dataUrl
      link.click()
      if (i + 1 === 10) {
        destroyContext(context)
      }
    })
    await new Promise(resolve => setTimeout(resolve, 1000))
  }
}

screenshotsPerSecond()

See the context.ts

TODO

modern-screenshot's People

Contributors

aeharding avatar bugcreators avatar donaldxdonald avatar qq15725 avatar sabereen avatar strindhaug avatar welkinwong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

modern-screenshot's Issues

placeholderImage as a callback

I would like to replace images which was unable to load for the screenshot (mostly CORS errors). I would like to generate grey area where these images are. What I would need is a callback for placeholderImage where the first parameter is the original img element.

placeholderImage: (imgElement){
    return 'Get the size of the imgElement and generate a grey image with that size.';
}

Another idea: replace the img tag in the cloned document with a simple div with styling.

Support for `text-stroke`

Hello, thanks for a great tool.

I wonder if the css property text-stroke is meant to be supported? Everything else works great, but text-stroke does not appear. Tested on both Chromium and Firefox (Linux Box). I'm using modern-screenshot version 4.4.9.

I would be happy to make a PR if pointed in the right direction. Cheers!

截屏中带有视频的不好用

 data() {
        return {
          code: `<div style="text-align: center;">
  <h1>egami</h1>
  <h1>→</h1>
  <h1>image</h1>
  <video src='https://www.runoob.com/try/demo_source/movie.mp4' controls autoPlay></video>
</div>`,
          src: null,
        }
      },

image

[modern-screenshot] Failed image load data:image/svg+xml;charset=utf-8,...

Steps To Reproduce

首先非常感谢作者辛苦开发的这个截图库,非常好用,试用过好多个类似的库,最终基于体验和效果,使用了这个库。

我使用该库来将Bing Chat的聊天页面中的指定DOM结构转为图片,之前能够正常转换,但最近不知道什么原因(或许是Bing Chat页面改版?),实际生成的图片为空白图片(即图片全部为白色,没有任何实际内容),浏览器开发者工具控制台中的报错信息如下:

[modern-screenshot] Failed image load data:image/svg+xml;charset=utf-8,...

[modern-screenshot] Failed to drawImage DOMException: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The HTMLImageElement provided is in the 'broken' state.

image

Bing Chat的聊天页面中的需要转换为图片的指定DOM结构为:

image

<!-- Provide a log message if relevant -->

Your Environment

  • OS: Windows 10
  • modern-screenshot: 4.4.26
  • Browser: MicroSoft Edge 116.0.1938.29

自定义标签的一般应对方法。

image

上图的Label与Input,被封装在一个自定义Element里面,名字比如:xxx-textfield,Input中的输入,是在自定义标签的value中,从input中无法获取。 带来的问题是:转换时文本框里面的输入没有了。

image

粗略地看了一下你的代码,由于在utils.ts中没有针对自定义tag的判断,后来的取值与复制,也就无法处理这种绕弯弯的自定义Tag。

不知道您这儿有没有增加自定义Tag应对逻辑的一般流程?(比如:先在utils中增加判断,然后再改动哪个文件等),我自己看代码,怕有遗漏。

Question about cross-domain image rendering

Hello, thank you for making this, it works pretty well for my project compared to html2canvas & html-to-image.

Just a question out of curiosity, from my experience with html2canvas, as it primarily uses canvas for rendering, images from another domain need to go through a proxy to be drawn and exported from the canvas, but that doesn't seem to be the case with this lib, I'm able to render x-domain images normally without any proxy. What is the magic behind this one (how does it work)?

Blank images in firefox due to duplicate css bloating size of rendered result

I apologize for not being able to provide a repro via playground. I'm trying to take screenshots in the AWS Console of a relatively straight-foward svg within a div. It appears that modern-screenshot is embedding the full css multiple times into the resulting image making it too large for firefox to render. It is directly related to the number of lines in the svg, it will render fine with a few lines, but when there are more than 20 lines or so, the image it tries to render with css exceeds 30 MB and starts to fail.

The code I'm screenshotting looks like this:

<div class="logs__histogram"><div class="toolTip" style="pointer-events: none; left: 204.45px; display: none;"><div class="cwchart-histogram-tooltip-category">2023-08-28T14:53:00-07:00</div>
         <div class="cwchart-histogram-tooltip-value">4 matches</div></div><svg width="1102" height="90"><g class="my-brush" style="pointer-events: none;" transform="translate(40, 10)"><rect class="background" style="visibility: hidden; cursor: crosshair;" x="0" width="1002" height="60"></rect><rect class="extent" style="cursor: move; fill: rgb(120, 197, 197); opacity: 0.5;" x="178" width="11" height="60"></rect><g class="resize e" style="cursor: ew-resize;" transform="translate(189,0)"><rect x="-3" width="6" height="60" style="visibility: hidden;"></rect></g><g class="resize w" style="cursor: ew-resize;" transform="translate(178,0)"><rect x="-3" width="6" height="60" style="visibility: hidden;"></rect></g></g><g class="rects" transform="translate(40, 10)"><g class="x axis" transform="translate(0, 59)"><g class="tick" style="opacity: 1;" transform="translate(64,0)"><line y2="6" x2="0"></line><text dy=".71em" style="text-anchor: middle;" y="9" x="0">02:30</text></g><g class="tick" style="opacity: 1;" transform="translate(148,0)"><line y2="6" x2="0"></line><text dy=".71em" style="text-anchor: middle;" y="9" x="0">02:45</text></g><g class="tick" style="opacity: 1;" transform="translate(231,0)"><line y2="6" x2="0"></line><text dy=".71em" style="text-anchor: middle;" y="9" x="0">03 PM</text></g><g class="tick" style="opacity: 1;" transform="translate(315,0)"><line y2="6" x2="0"></line><text dy=".71em" style="text-anchor: middle;" y="9" x="0">03:15</text></g><g class="tick" style="opacity: 1;" transform="translate(398,0)"><line y2="6" x2="0"></line><text dy=".71em" style="text-anchor: middle;" y="9" x="0">03:30</text></g><g class="tick" style="opacity: 1;" transform="translate(482,0)"><line y2="6" x2="0"></line><text dy=".71em" style="text-anchor: middle;" y="9" x="0">03:45</text></g><g class="tick" style="opacity: 1;" transform="translate(565,0)"><line y2="6" x2="0"></line><text dy=".71em" style="text-anchor: middle;" y="9" x="0">04 PM</text></g><g class="tick" style="opacity: 1;" transform="translate(649,0)"><line y2="6" x2="0"></line><text dy=".71em" style="text-anchor: middle;" y="9" x="0">04:15</text></g><g class="tick" style="opacity: 1;" transform="translate(732,0)"><line y2="6" x2="0"></line><text dy=".71em" style="text-anchor: middle;" y="9" x="0">04:30</text></g><g class="tick" style="opacity: 1;" transform="translate(816,0)"><line y2="6" x2="0"></line><text dy=".71em" style="text-anchor: middle;" y="9" x="0">04:45</text></g><g class="tick" style="opacity: 1;" transform="translate(899,0)"><line y2="6" x2="0"></line><text dy=".71em" style="text-anchor: middle;" y="9" x="0">05 PM</text></g><g class="tick" style="opacity: 1;" transform="translate(983,0)"><line y2="6" x2="0"></line><text dy=".71em" style="text-anchor: middle;" y="9" x="0">05:15</text></g><path class="domain" d="M0,6V0H1002V6"></path></g><g class="y axis"><g class="tick" style="opacity: 1;" transform="translate(0,60)"><line x2="0" y2="0"></line><text dy=".32em" style="text-anchor: end;" x="-3" y="0">0</text></g><g class="tick" style="opacity: 1;" transform="translate(0,48)"><line x2="0" y2="0"></line><text dy=".32em" style="text-anchor: end;" x="-3" y="0">1</text></g><g class="tick" style="opacity: 1;" transform="translate(0,36)"><line x2="0" y2="0"></line><text dy=".32em" style="text-anchor: end;" x="-3" y="0">2</text></g><g class="tick" style="opacity: 1;" transform="translate(0,24)"><line x2="0" y2="0"></line><text dy=".32em" style="text-anchor: end;" x="-3" y="0">3</text></g><g class="tick" style="opacity: 1;" transform="translate(0,11.999999999999996)"><line x2="0" y2="0"></line><text dy=".32em" style="text-anchor: end;" x="-3" y="0">4</text></g><g class="tick" style="opacity: 1;" transform="translate(0,0)"><line x2="0" y2="0"></line><text dy=".32em" style="text-anchor: end;" x="-3" y="0">5</text></g><path class="domain" d="M0,0H0V60H0"></path></g><rect class="bar" x="0.13914734064713236" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="2.922094153589779" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="5.705040966532426" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="8.487987779475073" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="11.27093459241772" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="14.053881405360368" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="16.836828218303012" width="2.6437994722955143" y="48" height="12"></rect><rect class="bar" x="19.61977503124566" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="22.402721844188306" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="25.185668657130954" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="27.9686154700736" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="30.75156228301625" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="33.534509095958896" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="36.31745590890154" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="39.10040272184419" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="41.88334953478684" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="44.666296347729485" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="47.44924316067213" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="50.23218997361478" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="53.01513678655743" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="55.798083599500075" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="58.58103041244272" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="61.36397722538537" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="64.14692403832801" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="66.92987085127065" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="69.7128176642133" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="72.49576447715594" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="75.2787112900986" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="78.06165810304124" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="80.8446049159839" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="83.62755172892653" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="86.41049854186919" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="89.19344535481183" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="91.97639216775447" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="94.75933898069712" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="97.54228579363976" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="100.32523260658242" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="103.10817941952506" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="105.89112623246771" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="108.67407304541035" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="111.45701985835301" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="114.23996667129565" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="117.0229134842383" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="119.80586029718094" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="122.5888071101236" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="125.37175392306624" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="128.1547007360089" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="130.93764754895153" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="133.72059436189417" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="136.5035411748368" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="139.28648798777948" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="142.06943480072212" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="144.85238161366476" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="147.6353284266074" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="150.41827523955007" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="153.2012220524927" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="155.98416886543535" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="158.767115678378" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="161.55006249132066" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="164.3330093042633" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="167.11595611720594" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="169.89890293014858" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="172.68184974309125" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="175.4647965560339" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="178.24774336897653" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="181.03069018191917" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="183.8136369948618" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="186.59658380780448" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="189.37953062074712" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="192.16247743368976" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="194.9454242466324" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="197.72837105957507" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="200.5113178725177" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="203.29426468546035" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="206.077211498403" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="208.86015831134566" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="211.6431051242883" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="214.42605193723094" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="217.20899875017358" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="219.99194556311625" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="222.7748923760589" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="225.55783918900153" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="228.34078600194417" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="231.1237328148868" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="233.90667962782948" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="236.68962644077212" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="239.47257325371476" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="242.2555200666574" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="245.03846687960007" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="247.8214136925427" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="250.60436050548535" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="253.387307318428" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="256.17025413137065" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="258.95320094431327" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="261.73614775725594" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="264.5190945701986" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="267.3020413831412" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="270.0849881960839" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="272.8679350090265" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="275.65088182196916" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="278.43382863491183" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="281.21677544785445" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="283.9997222607971" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="286.7826690737398" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="289.5656158866824" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="292.34856269962506" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="295.1315095125677" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="297.91445632551034" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="300.697403138453" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="303.4803499513956" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="306.2632967643383" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="309.04624357728096" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="311.8291903902236" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="314.61213720316624" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="317.39508401610885" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="320.1780308290515" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="322.9609776419942" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="325.7439244549368" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="328.52687126787947" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="331.3098180808221" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="334.09276489376475" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="336.8757117067074" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="339.65865851965003" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="342.4416053325927" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="345.22455214553537" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="348.007498958478" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="350.79044577142065" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="353.57339258436326" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="356.35633939730593" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="359.1392862102486" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="361.9222330231912" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="364.7051798361339" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="367.4881266490765" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="370.27107346201916" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="373.05402027496183" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="375.83696708790444" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="378.6199139008471" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="381.4028607137898" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="384.1858075267324" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="386.96875433967506" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="389.75170115261767" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="392.53464796556034" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="395.317594778503" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="398.1005415914456" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="400.8834884043883" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="403.6664352173309" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="406.44938203027357" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="409.23232884321624" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="412.01527565615885" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="414.7982224691015" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="417.5811692820442" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="420.3641160949868" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="423.14706290792947" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="425.9300097208721" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="428.71295653381475" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="431.4959033467574" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="434.2788501597" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="437.0617969726427" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="439.84474378558537" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="442.627690598528" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="445.41063741147065" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="448.19358422441326" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="450.9765310373559" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="453.7594778502986" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="456.5424246632412" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="459.3253714761839" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="462.1083182891265" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="464.89126510206916" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="467.6742119150118" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="470.45715872795444" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="473.2401055408971" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="476.0230523538398" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="478.8059991667824" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="481.58894597972505" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="484.37189279266767" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="487.15483960561033" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="489.937786418553" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="492.7207332314956" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="495.5036800444383" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="498.2866268573809" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="501.06957367032356" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="503.85252048326623" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="506.63546729620884" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="509.4184141091515" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="512.2013609220942" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="514.9843077350369" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="517.7672545479794" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="520.5502013609221" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="523.3331481738647" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="526.1160949868074" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="528.8990417997501" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="531.6819886126926" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="534.4649354256353" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="537.247882238578" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="540.0308290515206" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="542.8137758644633" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="545.5967226774059" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="548.3796694903485" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="551.1626163032912" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="553.9455631162339" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="556.7285099291765" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="559.5114567421192" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="562.2944035550618" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="565.0773503680044" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="567.8602971809471" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="570.6432439938898" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="573.4261908068324" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="576.209137619775" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="578.9920844327177" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="581.7750312456603" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="584.557978058603" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="587.3409248715457" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="590.1238716844882" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="592.9068184974309" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="595.6897653103736" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="598.4727121233162" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="601.2556589362589" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="604.0386057492015" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="606.8215525621441" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="609.6044993750868" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="612.3874461880295" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="615.1703930009721" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="617.9533398139148" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="620.7362866268573" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="623.5192334398" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="626.3021802527427" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="629.0851270656854" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="631.868073878628" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="634.6510206915706" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="637.4339675045132" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="640.2169143174559" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="642.9998611303986" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="645.7828079433413" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="648.5657547562838" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="651.3487015692265" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="654.1316483821691" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="656.9145951951118" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="659.6975420080545" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="662.480488820997" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="665.2634356339397" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="668.0463824468824" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="670.829329259825" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="673.6122760727677" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="676.3952228857103" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="679.1781696986529" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="681.9611165115956" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="684.7440633245383" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="687.5270101374809" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="690.3099569504236" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="693.0929037633662" width="2.6437994722955143" y="0" height="60"></rect><rect class="bar" x="695.8758505763088" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="698.6587973892515" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="701.4417442021942" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="704.2246910151368" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="707.0076378280794" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="709.7905846410221" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="712.5735314539647" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="715.3564782669074" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="718.1394250798501" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="720.9223718927926" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="723.7053187057353" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="726.488265518678" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="729.2712123316206" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="732.0541591445633" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="734.8371059575059" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="737.6200527704485" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="740.4029995833912" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="743.1859463963339" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="745.9688932092765" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="748.7518400222192" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="751.5347868351618" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="754.3177336481044" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="757.1006804610471" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="759.8836272739898" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="762.6665740869324" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="765.449520899875" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="768.2324677128177" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="771.0154145257603" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="773.798361338703" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="776.5813081516457" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="779.3642549645882" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="782.1472017775309" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="784.9301485904736" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="787.7130954034162" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="790.4960422163589" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="793.2789890293014" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="796.0619358422441" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="798.8448826551868" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="801.6278294681294" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="804.4107762810721" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="807.1937230940147" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="809.9766699069573" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="812.7596167199" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="815.5425635328427" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="818.3255103457853" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="821.108457158728" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="823.8914039716706" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="826.6743507846132" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="829.4572975975559" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="832.2402444104986" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="835.0231912234412" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="837.8061380363838" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="840.5890848493265" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="843.3720316622691" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="846.1549784752118" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="848.9379252881545" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="851.720872101097" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="854.5038189140397" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="857.2867657269824" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="860.069712539925" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="862.8526593528677" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="865.6356061658103" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="868.4185529787529" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="871.2014997916956" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="873.9844466046383" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="876.7673934175809" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="879.5503402305236" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="882.3332870434662" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="885.1162338564088" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="887.8991806693515" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="890.6821274822942" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="893.4650742952368" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="896.2480211081794" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="899.030967921122" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="901.8139147340647" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="904.5968615470074" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="907.3798083599501" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="910.1627551728926" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="912.9457019858353" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="915.728648798778" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="918.5115956117206" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="921.2945424246633" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="924.0774892376058" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="926.8604360505485" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="929.6433828634912" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="932.4263296764339" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="935.2092764893765" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="937.9922233023191" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="940.7751701152617" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="943.5581169282044" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="946.3410637411471" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="949.1240105540898" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="951.9069573670324" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="954.689904179975" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="957.4728509929176" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="960.2557978058603" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="963.038744618803" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="965.8216914317456" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="968.6046382446882" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="971.3875850576309" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="974.1705318705735" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="976.9534786835162" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="979.7364254964589" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="982.5193723094014" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="985.3023191223441" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="988.0852659352868" width="2.6437994722955143" y="11.999999999999996" height="48"></rect><rect class="bar" x="990.8682127482294" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="993.6511595611721" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="996.4341063741147" width="2.6437994722955143" y="60" height="0"></rect><rect class="bar" x="999.2170531870573" width="2.6437994722955143" y="60" height="0"></rect></g></svg></div>

And visually it looks like this:

image

I've attached the gzipped img that modern-screenshot creates that firefox chokes on because it is too big. modern-screenshot.txt.gz
I've also attached the main stylesheet from the AWS console that appears multiple times in the rendered image.
styles.css.gz

There are probably a couple of ways to fix this:

  1. Embed the css once instead of per line
  2. Only embed the css that is actually used
  3. Add a filter that allows the developer to specify which css classes are embedded

Let me know if I can provide more info or help!

Steps To Reproduce

  1. Using Cloudwatch Insights in AWS i.e. https://us-west-2.console.aws.amazon.com/cloudwatch/home?region=us-west-2#logsV2:logs-insights

  2. Select a log file that has at least 50 lines at different timestamps and run a query like. limit 100 to display a histogram of the logs.

  3. Take a screenshot using domToPng on the div with class logs__histogram

Error Message & Stack Trace

Log message

[modern-screenshot] Failed image load
data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%221082%22%20height%3D%2294.75%22%20viewBox%3D%220%200%201082%2094.75%22%3E%3Cstyle%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxhtml%22%3E%0A.______background-clip--text%20%7B%0A%20%20background-clip%3A%20text%3B%0A%20%20-webkit-background-clip%3A%20text%3B%0A%7D%0A%40font-face%20%7B%20font-family%3A%20%22Amazon%20Ember%22%3B%20src%3A%20url(%22data%3Aapplication%2Fx-font-woff%3Bbase64%2Cd09GRgABAAAAAEbsABAAAAAAiagAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABbAAAABwAAAAcbjn2yEdERUYAAAGIAAAAMwAAADgFFwODR1BPUwAAAbwAAAw5AAAmVDGI9a5HU1VCAAAN%2BAAABNIAAAsi%2B2GWR09TLzIAABLMAAAAXQAAAGCIbG6MY21hcAAAEywAAAIRAAADDi4Vrc1nYXNwAAAVQAAAAAgAAAAIAAAAEGdseWYAABVIAAAl4AAAPiTZSEt1aGVhZAAAOygAAAA0AAAANgj8ZOJoaGVhAAA7XAAAACEAAAAkCA0ExmhtdHgAADuAAAACyAAABRyyMDbRbG9jYQAAPkgAAAJpAAACnivTHIRtYXhwAABAtAAAAB0AAAAgAV4Ao25hbWUAAEDUAAABvwAABKxfvqgQcG9zdAAAQpQAAAROAAAIR7QPcfl3ZWJmAABG5AAAAAYAAAAGXvJWqgAAAAEAAAAAzD2i…

error { target: img, isTrusted: true, srcElement: img, eventPhase: 0, bubbles: false, cancelable: false, returnValue: true, defaultPrevented: false, composed: false, timeStamp: 47642, … }

bubbles: false

cancelBubble: false

cancelable: false

composed: false

currentTarget: null

defaultPrevented: false

eventPhase: 0

explicitOriginalTarget:

isTrusted: true

originalTarget:

returnValue: true

srcElement:

target:

timeStamp: 47642

type: "error"

<get isTrusted()>: function isTrusted()

: EventPrototype { composedPath: composedPath(), stopPropagation: stopPropagation(), stopImmediatePropagation: stopImmediatePropagation(), … }

Your Environment

  • modern-screenshot: [e.g. 4.4.30]
  • Browser: [e.g. Firefox for mac 116.0.3]

Ios 设备 调用 domToDataUrl 图片无法加载

设备: iPhoneXR
系统: 16.0
环境: safari,钉钉H5

具体呈现: 调用一次方法只呈现出一张图片
image
image
现解决方法: 如果画面有两张图片, 就要在 ios 端 额外 await 两次

文心一言的图片无法导出的问题

文心一言在:https://yiyan.baidu.com/
排队不用很久,今天普遍是一个多小时就到了

导出的插件是:https://github.com/gantrol/Bing-Chat-Saver/releases/tag/v0.2.dark

网页原图:

image

效果图:

my-image-name (15)

HTML格式为(链接的是隐去的):

<div class="section-container html-wrap"><div class="custom-html"><p><img src="http://txt2img.cdn.bcebos.com/upload/<id>?x-bce-process=style/wm_ai"><br>好的,根据你的需求,我为你创作了一幅画作。<br>我的作画技能还在不断进化中,暂时还不支持对画作的修改和解释。<br>如果需要继续让我为你作画,请完整描述你的需求,如:“帮我画一枝晶莹剔透的牡丹花”。</p>
</div></div>

Default font on Firefox

Before all, thanks for this lib, I am searching for a related thing for a long time!

Problem

I am having issues with font on Firefox, when I save the image using domToPng, the browser default font is used instead my custom font.

preview
image

result
yutyiytuituyrty

Environment

Browser: Firefox 113.0.2
Framework: [email protected]
modern-screenshot: 4.4.25
Related Libs: [email protected], [email protected], [email protected]
Repo: https://github.com/mateusfg7/rifa
Related source:

Additional information

I also tested on Chrome and works fine. The problem only occurs on production environment, when I run the app on development environment all works fine.

Is there a way to use a non-rendered React component?

I would like to take a list of data and render it in the background to generate images.

I have an array of data like this:

const data = [
  {
    height: 500,
    weight: 500,
    color: "#ff0000",
    text: "Hello World",
  },
  ...
];

I would like to loop through each item in the array and pass the data into a React element like:

for (const d of data) {
  const dataUrl = await domToBlob(<Component {...d} />);
  // upload to server
}

Is this possible?

Inline SVG with use tag that reference external file doesn't work and potentially crashes

Steps To Reproduce

When trying to generate an image from html containing an SVG with a use tag that references an external file, it doesn't work. And if the url contains a query-string for cache busting or other characters that is invalid in a querySelector it will cause a javascript crash.

Example:
Playground for https://codesandbox.io

Error Message & Stack Trace

Uncaught (in promise) DOMException: Document.querySelector: 'svg external-symbol.svg?cacheBust=123#icon' is not a valid selector
    At https://unpkg.com/modern-screenshot:7
    S https://unpkg.com/modern-screenshot:1
    S https://unpkg.com/modern-screenshot:1
    At https://unpkg.com/modern-screenshot:7

...etc

Your Environment

  • modern-screenshot: [e.g. 4.4.9]
  • Browser: [e.g. chrome 111.0.5563.64]

不支持emoji和font-awsome

rt
一开始以为是字体跨域问题,后来仔细盘了一遍发现是一些特殊字体不能绘制。
不知道有没有办法解决QwQ

How do I manage cors with images?

When creating a PNG from the dom where a cross-origin image is in-use, am I able to bypass CORS so that the image renders?

For example in html2canvas I can set useCors (html2canvas(screenshotTarget, {useCORS: true})) - is there an equivalent in this library?

No Firefox support 🦊

Hello, bro, thanks for make this lib!

After some tests on a rich page, I noticed that it doesn't work on Firefox browser even with a simple case. Unfortunately, there is no console error or warning to help identify the problem.

Minimal scenario to reproduce:
https://codepen.io/qq15725/pen/PoBbOWm

Fonts are not applied in Safari.

I am currently using this library to develop a requirement to store a specific component. Thanks for developing it.

It is working fine in chrome.
However, in safari, the font is not being applied and is coming up with the default font.

In Chrome
download (35)

In Safari
download-4

my code :

 await domToCanvas(imageDiv, {
      scale: 2,
      backgroundColor: 'white',
      drawImageInterval: 1000,
    });

    const canvas = await domToCanvas(imageDiv, {
      scale: 2,
      backgroundColor: 'white',
      drawImageInterval: 1000,
    });

<div className="absolute bottom-[-1000px]"> <div id="capture-area" className="relative z-[-2] w-[340px] h-[370px] " ref={imageShareRef} > <div className="relative top-[10px]"> <Diary.CardImage imageSrc={feed['운동 인증샷']} sportsKind={feed['운동 종목']} workout={feed.운동량} emotion={feed.감정량} goal={feed['작성자 되고싶은나'] ?? ''} goalPercent={feed.goalGauge} pictureTime={formattingTime} /> </div> </div> </div>

Your Environment

  • modern-screenshot: [e.g. 4.4.9]
  • Browser: Chrome (111.0.5563.146)
    Safari 16.2(18614.3.7.1.5)

Uncaught (in promise) TypeError: u.style.fontFamily is undefined

Not sure what's happening, here's the code I'm using:

    jQuery('#download').click(function() {
    	jQuery('#socialcanvas').removeClass('canvas-zoom-out');
        modernScreenshot.domToJpeg(document.getElementById('socialcanvas'), { quality: 1, width:canvWidth, height:canvHeight })
        .then(dataUrl => {
        var link = document.createElement('a');
        link.download = shapetrimmed + ' - ' + fileTitle + '.jpeg';
        link.href = dataUrl;
        link.click();
        jQuery('#socialcanvas').addClass('canvas-zoom-out');
        });
    });

I get this:
[modern-screenshot] Error while reading CSS rules from https://fonts.googleapis.com/css?family=Roboto%3A100%2C100it…c%2C800%2C800italic%2C900%2C900italic&display=auto&ver=6.1.1 DOMException: CSSStyleSheet.cssRules getter: Not allowed to access cross-origin stylesheet modern-screenshot:1:3035

And this:

Uncaught (in promise) TypeError: u.style.fontFamily is undefined
    It https://unpkg.com/modern-screenshot:7
    It https://unpkg.com/modern-screenshot:7
    q https://unpkg.com/modern-screenshot:1
    promise callback*L https://unpkg.com/modern-screenshot:1
    g https://unpkg.com/modern-screenshot:1
    g https://unpkg.com/modern-screenshot:1
    It https://unpkg.com/modern-screenshot:6
    Ae https://unpkg.com/modern-screenshot:9
    q https://unpkg.com/modern-screenshot:1
    promise callback*L https://unpkg.com/modern-screenshot:1
    q https://unpkg.com/modern-screenshot:1
    promise callback*L https://unpkg.com/modern-screenshot:1
    g https://unpkg.com/modern-screenshot:1
    g https://unpkg.com/modern-screenshot:1
    Ae https://unpkg.com/modern-screenshot:9
    z https://unpkg.com/modern-screenshot:9
    q https://unpkg.com/modern-screenshot:1
    promise callback*L https://unpkg.com/modern-screenshot:1
    g https://unpkg.com/modern-screenshot:1
    g https://unpkg.com/modern-screenshot:1
    z https://unpkg.com/modern-screenshot:9
    _ https://unpkg.com/modern-screenshot:9
    q https://unpkg.com/modern-screenshot:1
    promise callback*L https://unpkg.com/modern-screenshot:1
    g https://unpkg.com/modern-screenshot:1
    g https://unpkg.com/modern-screenshot:1
    _ https://unpkg.com/modern-screenshot:9
    Bt https://unpkg.com/modern-screenshot:9
    q https://unpkg.com/modern-screenshot:1
    promise callback*L https://unpkg.com/modern-screenshot:1
    g https://unpkg.com/modern-screenshot:1
    g https://unpkg.com/modern-screenshot:1
    Bt https://unpkg.com/modern-screenshot:9
    <anonymous> https://DOMAIN/sandbox/wp-content/themes/nel-sandbox/js/socialtool.js?ver=6.1.1:372
    jQuery 10
    <anonymous> https://DOMAIN/sandbox/wp-content/themes/nel-sandbox/js/socialtool.js?ver=6.1.1:370
    jQuery 13
modern-screenshot:7:711

css 的 text-shadow 生成图片后没有阴影效果

示例如下:

h1{
  display: flex;
  justify-content: center;
  font-size: 30px;
  font-weight: bolder;
  color: #f00;
  -webkit-text-stroke: 1px white;
  text-shadow: 2px 4px 4px rgba(0, 0, 0, 0.3); /* 设置向下的阴影效果 */
  border-radius: 8px;
  padding: 0 2px;
  white-space: nowrap;
}

There are gray boxes inside the picture

Steps To Reproduce

I'm creating and downloading the image, but the image I'm downloading is getting gray boxes.

Error Message & Stack Trace

No errors

Your Environment

  • React.js app
  • modern-screenshot: 4.4.23
  • Browser: Chrome

LTeay94TIs

iled to drawImage DOMException: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The HTMLImageElement provided is in the 'broken' state.

我把这个嵌入了另外一个App(jquery的),总是无论时下载图片,还是将图片添加到Dom中,都报相同的错误。

Failed to drawImage DOMException: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The HTMLImageElement provided is in the 'broken' state.

编译后的代码,在这个位置:

function ut(e, t) {
        return p(this, null, function*() {
            const {log: n, timeout: r, drawImageCount: a, drawImageInterval: i} = t;
            n.time("image to canvas");
            const o = yield _(e, {
                timeout: r
            })
              , {canvas: s, context2d: c} = ft(e.ownerDocument, t)
              , l = ()=>{
                try {
                    c == null || c.drawImage(o, 0, 0, s.width, s.height)
               

源码错误出在image-to-canvas.ts中的第20行:

context2d?.drawImage(loaded, 0, 0, canvas.width, canvas.height)

我的环境:MacOS M1 Ventera 13.3.1
Browser: Chrome, Firefox latest version.错误相同。
我的代码:

window.modernScreenshot.domToPng(runtimeElement).then(dataUrl => {
		    const link = document.createElement('a')
		    link.download = 'screenshot.png'
		    link.href = dataUrl
		    link.click()
		  })
		  .catch(function (error) {
			  console.error("modern screenshot:",error);
		  });

或者:

window.modernScreenshot.domToPng(document.body).then(function (dataUrl){
			 var img = new Image();
			 img.src = dataUrl;
			 document.body.appendChild(img);
		 }).catch(function (error){
			 console.error("dom to png error:",error);
		 })

Vue3安装后提示TypeError: domToPng is not a function

image
执行代码完全按照教程:
import { domToPng } from 'modern-screenshot'

domToPng(document.querySelector('#app')).then(dataUrl => {
const link = document.createElement('a')
link.download = 'screenshot.png'
link.href = dataUrl
link.click()
})
但是运行的时候会爆这个错误

Google web fonts not working in Firefox. Getting DOMException: CSSStyleSheet.cssRules error.

Steps To Reproduce

  1. Open a page with modern-screenshot in Firefox.
  2. Use a Google web font in the container.
  3. Generate image of the container (Containing the Google web font).

The following error shows up

Error while reading CSS rules from [https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@…;800&family=Slabo+27px:wght@300;400;500;700;800&display=swap](https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@300;400;500;700;800&family=Inter:wght@300;400;500;700;800&family=Lato:wght@300;400;500;700;800&family=Montserrat:wght@300;400;500;700;800&family=Open+Sans:wght@300;400;500;700;800&family=Poppins:wght@300;400;500;700;800&family=Prompt:wght@300;400;500;700;800&family=Public+Sans:wght@300;400;500;700;800&family=Raleway:wght@300;400;500;700;800&family=Roboto:wght@300;400;500;700;800&family=Slabo+27px:wght@300;400;500;700;800&display=swap) DOMException: CSSStyleSheet.cssRules getter: Not allowed to access cross-origin stylesheet
Error Message & Stack Trace

error

Your Environment

  • modern-screenshot: 4.4.9
  • Browser: Firefox 111.0.1

How Screenshot of hidden div using modern-screenshort

How to take screenshots of a hidden div? Similar to using html2canvas code below.

[html2canvas(mydiv,](url) {
    onclone: function (clonedDoc) {
        clonedDoc.getElementById('mydiv').style.display = 'block';
    }
}).then((canvas)=>{
//your onrendered function code here
})

Inline SVGs in CSS are not working

I have an inline SVG set as a background image using CSS, but modern screenshot can't seem to 'see' it. This is a screenshot:
Screenshot 2023-03-19 at 12-17-30 Social – Nel Sandbox

And this is the generated image:
Square - This is the image

Getting blank white image when taking screenshot in Firefox.

  1. Install modern-screenshot version - 4.4.25.
  2. Using domToPng, run project on Firefox.
  3. After clicking on Screenshot getting white blank image.

After Clicking on take screenshot getting white blank image on Firefox, for Chrome it it working fine.
Image is getting created properly.

  • modern-screenshot: 4.4.25.
  • Browser: Firefox : 113.0.2

Grey boxes surrounding all nodes in image

Steps To Reproduce

When rendering a screenshot, all dom nodes are surrounded by gray boxes. It seems to also be outlining margins and padding separately from the nodes.

This isn't online anywhere.

Error Message & Stack Trace

No errors

Your Environment

This is in a Rails/Stimulus app. Nothing fancy.

screenshot

  • Browser: Firefox

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.