All Projects â†’ nikersify â†’ Pico

nikersify / Pico

Licence: mit
Take browser screenshots in Javascript 📸

Programming Languages

javascript
184084 projects - #8 most used programming language
typescript
32286 projects
HTML
75241 projects
CSS
56736 projects

Projects that are alternatives of or similar to Pico

fp-ts-fluture
fp-ts bindings for Fluture
Stars: ✭ 48 (-97.34%)
Mutual labels:  fp-ts, fluture
Snappy
PHP library allowing thumbnail, snapshot or PDF generation from a url or a html page. Wrapper for wkhtmltopdf/wkhtmltoimage
Stars: ✭ 3,986 (+120.59%)
Mutual labels:  html-to-image
app-screenshot-builder
Play Store and App Store application screenshot builder
Stars: ✭ 26 (-98.56%)
Mutual labels:  html2canvas
turkeyvisited
Mark the cities you have visited in Turkey and share the map!
Stars: ✭ 82 (-95.46%)
Mutual labels:  html2canvas
fp-ts-cheatsheet
FP-TS Cheat Sheet
Stars: ✭ 276 (-84.73%)
Mutual labels:  fp-ts
html2canvas-proxy-nodejs
Express middleware proxy for html2canvas
Stars: ✭ 101 (-94.41%)
Mutual labels:  html2canvas
mutoid
Reactive library for data fetching, caching, state management
Stars: ✭ 24 (-98.67%)
Mutual labels:  fp-ts
ts-do
Do like notation for typescript using fp-ts
Stars: ✭ 55 (-96.96%)
Mutual labels:  fp-ts
workshop-edsl-in-typescript
Code template for workshop "Building eDSLs in functional TypeScript"
Stars: ✭ 49 (-97.29%)
Mutual labels:  fp-ts
banner
🚩 A simple and clean banner generator - Banners on the go. https://liyasthomas.github.io/banner
Stars: ✭ 161 (-91.09%)
Mutual labels:  html2canvas
fp-ts-ramda
Ramda functions reimplemented in fp-ts
Stars: ✭ 129 (-92.86%)
Mutual labels:  fp-ts
purifree
Pointfree type-safe functional programming library for TypeScript - with do notation, HKTs, generic lifts and more
Stars: ✭ 64 (-96.46%)
Mutual labels:  fp-ts
typescript-react-starter
React & TypeScript Starter with webpack, ts-jest and runtime environment variables. It comes with fp-ts ecosystem and pre-configured prettier, eslint, vscode, husky hooks and Dockerfile to build a deployable image of your app
Stars: ✭ 17 (-99.06%)
Mutual labels:  fp-ts
retry-ts
Retry combinators for monadic actions that may fail
Stars: ✭ 151 (-91.64%)
Mutual labels:  fp-ts
EditShot
📸 A chrome extension to Edit a Page directly and then taking a screenshot!
Stars: ✭ 21 (-98.84%)
Mutual labels:  html2canvas
api2pdf.php
PHP client library for the Api2Pdf.com REST API - Convert HTML to PDF, URL to PDF, Office Docs to PDF, Merge PDFs, HTML to Image, URL to Image, HTML to Docx, HTML to Xlsx, PDF to HTML, Thumbnail preview of office files
Stars: ✭ 42 (-97.68%)
Mutual labels:  html-to-image
idg
Document image generator
Stars: ✭ 40 (-97.79%)
Mutual labels:  html-to-image
vscode-fp-ts-codegen
Expands haskell-syntax ADTs to typescript equivalent types definitions using gcanti/fp-ts-codegen
Stars: ✭ 16 (-99.11%)
Mutual labels:  fp-ts
html2canvas-csharp-proxy
C# Proxy html2canvas (aspx)
Stars: ✭ 16 (-99.11%)
Mutual labels:  html2canvas
Fluture
🦋 Fantasy Land compliant (monadic) alternative to Promises
Stars: ✭ 2,249 (+24.46%)
Mutual labels:  fluture

📸 Pico

Take browser screenshots in Javascript

npm GitHub issues Compressed size

(Original page on the left · PNG output on the right)


Development of this library is possible thanks to:

Gripeless
Gripeless is a free complaint solution for web apps
Let your users take screenshots of important issues, pipe them into your issue tracker
and let your users know when they're fixed, automatically.


https://usegripeless.com


Goal

Pico's goal is to produce high precision screenshots of any viewport entirely client side. This is different from simply capturing a webpage using Puppeteer or a similar tool in that the screenshot taking happens entirely client side.

The viewport screenshots include scrolled element scroll states, cross-origin images, input states, web fonts, canvas contents, current video frame contents, and much more information that you wouldn't be able to get using something like a headless browser.

At the time of writing there are no existing solutions that are aimed of reproducing the entire viewport accurately like Pico.

How it works

Warning: nerdy

This program renders whatever is displayed in the given Window into an image, thanks to svg's <foreignObject>.

No server side code is required to produce the screenshot.

There is no native Javascript API to take the screenshot of what the user is currently seeing on their screen (and because of security issues there probably will never be one).

Since we don't have access to the raw data that's being shown to the user we have to reconstruct it manually. This program works thanks to svg's <foreignObject> which lets you insert any valid HTML content inside, which we can then pass as a data URL into a <canvas>' drawImage and read out the raw image data with canvas.toBlob or canvas.toDataURL.

The above alone would work great in a universe where subresources didn't exist - which as you know is not our universe. SVG's inserted into <img> tags (or in our case, <canvas>') cannot display any external resources, whether it's images, fonts or stylesheets.

To work around that fact Pico does the following things:

  • Downloads and inlines contents of all <img> tags as data URL's in their src attributes
  • Downloads external stylesheets and inlines them as <style> tags
  • Checks all stylesheets for nested resources
    • Downloads and checks nested stylesheets in @import rules
    • Downloads any resources referenced by the url() function, including but not exclusive to the following properties:
      • backgrounds
      • background-images
      • src in @font-face rule
      • cursor
      • content

In addition, Pico also:

  • Copies input states (text inputs, checkboxes, textareas) into value attributes so that they can be shown in SVG
  • Emulates current scroll positions on all scrolled elements (including the root <html> element) via either transform: translate (for root node) and absolute positioning of children of scrolled nodes
  • Transforms existing <canvas> elements into <img> tags with the contents of the <canvas>' inlined as data URL's in src
  • Performs various minor fixes for rem font size, working media queries, preserving size of everything, etc.

The returned DOM is inserted into an <iframe>, serialized into XML, converted into a data URL, put into an Image, which is then rendered onto a <canvas> whose contents are read out with canvas.toBlob and finally returned to the program's caller, together with all the errors when resources failed to load.

Pico is able to safely accumulate all async resource errors thanks to Fluture, which is a really great alternative to the native Promise and forces you to write type safe errors. You can read a fantastic introductory article to it by the library's author here.

API

Pico is built using Fluture and in addition to the Promise also provides a direct API to Fluture via functions suffixed with Fluture. If you don't care about functional programming just use the non-suffixed functions to work with Promise's instead.

All functions return an "ErrorStack", which is basically just the returned value paired with any errors that happened while computing it. Most errors will be CORS or 404 related issues when loading subresources.

Types

declare type ErrorStack<T> = {
    errors: DetailedError[];
    value: T;
};
export declare type DetailedError = {
    // Human readable string of why the error happened
    reason: string;

    // Proper error object
    error: Error;
};
export declare type Options = {
    // An array of selectors to nodes that should not be included in the output.
    ignore: string[];
};

Functions

declare const objectURL: ($window: Window, partialOptions?: Partial<Options>) => Promise<ErrorStack<string>>;
declare const objectURLFluture: ($window: Window, options: Options) => Fluture<DetailedError, ErrorStack<string>>;

Render the given Window to a PNG image and return it as an object URL. This is safer to use than dataURL due to memory constraints. Remember to call URL.revokeObjectURL when you're done with the image.


declare const dataURL: ($window: Window, partialOptions?: Partial<Options>) => Promise<ErrorStack<string>>;
declare const dataURLFluture: ($window: Window, options: Options) => Fluture<DetailedError, ErrorStack<string>>;

Render the given Window to a PNG image and return it as a data url. Note that in Chrome the limit for data url's is 2MB, prefer objectURL when possible.


declare const svgObjectURL: ($window: Window, partialOptions?: Partial<Options>) => Promise<ErrorStack<string>>;
declare const svgObjectURLFluture: ($window: Window, options: Options) => Fluture<DetailedError, ErrorStack<string>>;

Render the given Window to an SVG image and return it as an object URL. This function is mainly useful for inspecting the output of Pico using devtools, for real uses prefer the other functions.

Installation

$ npm install @gripeless/pico

The module is intended to be used exclusively in the browser via a code bundler like Rollup or Webpack. There is no single file bundle build provided at this time.

Contributing

See contributing.md.

Caveats

Pico is being developed against recent Firefox and Blink based browsers (Chrome, Opera, Brave, Edge). It does not work on Safari or old Edge versions due to lack of proper support for <foreignObject>.

Prior art

Pico's code was inspired in many ways by the following libraries:

Pico's selling point is representing the whole viewport as accurately as possible. If you want to render a single DOM node instead, consider using one of the above libraries.

To the authors of the above code, thank you for your awesome work.

License

MIT (c) 2020 Primitive Software

https://usegripeless.com

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].