Giter VIP home page Giter VIP logo

frameright / image-display-control-web-component Goto Github PK

View Code? Open in Web Editor NEW
11.0 2.0 0.0 21.05 MB

๐Ÿš€ Next-gen responsive <img>

Home Page: https://webc.frameright.io

License: MIT License

HTML 36.95% TypeScript 57.86% JavaScript 4.53% Shell 0.24% CSS 0.42%
frameright image image-display-control image-manipulation image-publishing iptc-metadata metadata metadata-extraction metadata-parser responsive-design

image-display-control-web-component's Introduction

npm version Published on webcomponents.org

ย 

<img is="image-display-control">

Image Display Control Web Component

โžก๏ธ See this document rendered at docs.frameright.io/web-component

An easy way to do Image Display Control in your HTML page. Made with โค๏ธ by Frameright. Power to the pictures!

Less than 20kB in your final client-side bundle.

โ€ƒ โœจ Live demo

โ€ƒ ๐Ÿ’ป CodeSandbox

โ€ƒ ๐Ÿ’ก GitHub Discussions

NOTE: if you are using React, you may want to have a look at the Image Display Control React component instead.

Table of Contents

Overview

Without this web component

When an image is too big for its <img> HTML element, the best option browsers offer nowadays is to use the object-fit: cover; CSS property in order to scale and middle-crop it:

<img
  src="https://images.pexels.com/photos/3625715/pexels-photo-3625715.jpeg"
  width="200"
  height="200"
  style="object-fit: cover;"
/>

This is less than optimal, as there might be, in the example above, a better square-ish region in the image that could be displayed instead of the middle-crop.

Basic usage

This web component extends the <img> tag with the ability to accept a list of image regions, and to zoom in on the best one for the current element size:

<img
  is="image-display-control"
  src="https://images.pexels.com/photos/3625715/pexels-photo-3625715.jpeg"
  width="200"
  height="200"
  data-image-regions='[{
    "id": "oneanimal",
    "names": ["One animal"],
    "shape": "rectangle",
    "unit": "relative",
    "x": "0.217",
    "y": "0.708",
    "width": "0.239",
    "height": "0.1467"
  }, {
    "id": "threeanimals",
    "names": ["Three animals"],
    "shape": "rectangle",
    "unit": "relative",
    "x": "0.245",
    "y": "0.725",
    "width": "0.419",
    "height": "0.121"
  }]'
/>

The resulting HTML element is responsive and will automatically reassess the best region to zoom in on when it gets resized, e.g. when the user turns their phone from portrait to landscape.

โ€ƒ โœจ Live demo

โ€ƒ ๐Ÿ’ป CodeSandbox

โ€ƒ ๐Ÿ’ก GitHub Discussions

Why a custom img element?

In order to have existing CSS rules in a project able to target indifferently classic <img> elements and our web component, two options exist:

  1. Invent a custom <img is="image-display-control" src="..."> element implementing HTMLImageElement, or
  2. Invent a custom <image-display-control><img src="..."></image-display-control> element based on an HTML template with a <slot> element.

The problem with the second option is that it puts the <img> tag inside a new parent element <image-display-control> and CSS rules such as

img {
  /* fill the parent element */
  width: 100%;
  height: 100%;
}

won't have the intended results, because the parent element hasn't been instructed to fill its own parent. This would force developers to adapt their CSS rules to also target the new parent, which is not ideal.

This is why we went with the first option, which doesn't require any CSS changes in existing projects.

Image Display Control metadata

Nowadays an image file (e.g. JPEG, PNG) can contain this type of image regions in their metadata according to the IPTC standard. The back-end would typically be responsible for extracting them from the image file and placing them in the front-end's <img data-image-regions=" attribute. This is for example what this WordPress plugin does, with the help of a PHP library for extracting image metadata. This can also be achieved on a Node.js back-end with the help of this TypeScript library. In fact we have created this React component that does all this for you by serving the web component and running the TypeScript library either on your Node.js back-end or in the browser.

Photographers, or anyone else, can use the Frameright webapp to define and store image regions in the metadata of their pictures.

Installation

Provided that you are using a bundler (e.g. Webpack or Rollup), you can add the web component to your project with:

npm install @frameright/image-display-control-web-component

Less than 20kB in your final client-side bundle.

or get it from a CDN:

<script
  type="module"
  src="https://cdn.jsdelivr.net/npm/@frameright/[email protected]/dist/image-display-control.min.js"
></script>

โ€ƒ ๐Ÿ’พ Importing in your project

Usage

<html>
  <head></head>
  <body>
    <img
      is="image-display-control"
      src="https://images.pexels.com/photos/3625715/pexels-photo-3625715.jpeg"
      width="200"
      height="200"
      data-image-regions='[{
        "id": "oneanimal",
        "names": ["One animal"],
        "shape": "rectangle",
        "unit": "relative",
        "x": "0.217",
        "y": "0.708",
        "width": "0.239",
        "height": "0.1467"
      }, {
        "id": "threeanimals",
        "names": ["Three animals"],
        "shape": "rectangle",
        "unit": "relative",
        "x": "0.245",
        "y": "0.725",
        "width": "0.419",
        "height": "0.121"
      }]'
    />
    <!-- Built with Webpack or Rollup. Contains the web component: -->
    <script src="mybundle.js"></script>
  </body>
</html>

Demo

โ€ƒ โœˆ๏ธ Advanced usage

โ€ƒ โœจ Local demo

โ€ƒ ๐Ÿ”ง Contributing

โ€ƒ ๐Ÿ“ Changelog

โ€ƒ ๐Ÿ’ก GitHub Discussions

โ€ƒ โœจ Live demo

Dependency tree / credits

Browser support

From scratch the web component should work on:

  • Chrome 64+ (2018 or newer)
  • Firefox 69+ (2019 or newer)
  • Safari 15.4+ (2022 or newer)

More support can be achieved with a few tweaks:

โ€ƒ ๐Ÿ” Browser support

image-display-control-web-component's People

Contributors

dependabot[bot] avatar lourot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

image-display-control-web-component's Issues

`npm audit fix`

At the moment, NPM detects a high severity vulnerability in one of our dependency. However npm audit fix doesn't help:

$ npm audit fix

up to date, audited 774 packages in 3s

133 packages are looking for funding
  run `npm fund` for details

# npm audit report

marked  <=4.0.9
Severity: high
Marked ReDoS due to email addresses being evaluated in quadratic time - https://github.com/advisories/GHSA-xf5p-87ch-gxw2
Inefficient Regular Expression Complexity in marked - https://github.com/advisories/GHSA-5v2h-r2cx-5xgj
Inefficient Regular Expression Complexity in marked - https://github.com/advisories/GHSA-rrrm-qjm4-v8hf
fix available via `npm audit fix`
node_modules/marked

1 high severity vulnerability

To address all issues, run:
  npm audit fix

Fix circular imports

$ npm run build
[...]
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ File name                    โ”‚ Size     โ”‚
โ”‚ ---------------------------- โ”‚ -------- โ”‚
โ”‚ image-display-control.min.js โ”‚ 17.88 kB โ”‚
โ”‚ ---------------------------- โ”‚ -------- โ”‚
โ”‚ Totals                       โ”‚ 17.88 kB โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
(!) Circular dependencies
dist/src/PositionInRelativeCoord.js -> dist/src/PositionInPixels.js -> dist/src/PositionInRelativeCoord.js
dist/src/SizeInPixels.js -> dist/src/SizeInRelativeCoord.js -> dist/src/SizeInPixels.js
created ./dist/image-display-control.min.js in 546ms

Validate with many image regions

Is there a limit to the size of the value string of an HTML attribute? In other words, can we pass as many regions as we want?

Force selecting any image region

Right now, the component may decide that the best region to zoom in on right now is no region at all, i.e. the original image. This happens if the current component ratio is closed to the original image's ratio.

By default, the component should always prefer selecting one of the regions, no matter what. This behavior could be tweaked with a new HTML attribute, see #2

Option for automatically parsing metadata

In order to populate data-image-regions=, if parsing image metadata on the front-end is good enough, one has to write a bit of boilerplate at the moment, as shown in the CodeSandbox:

        const imgElement = document.getElementById("skater");
        const image = await fetch(imgElement.src);
        const arrayBuffer = await image.arrayBuffer();
        const buffer = Buffer.Buffer.from(arrayBuffer);
        const parser = new ImageDisplayControl.Parser(buffer);
        const regions = parser.getIdcMetadata("rectangle", "crop");
        imgElement.dataset.imageRegions = JSON.stringify(regions);

It would be nice to be able to pass a flag to the web-component telling it to do this for us, if ImageDisplayControl.Parser exists, i.e. if https://github.com/Frameright/image-display-control-metadata-parser has been loaded.

Possible optimization / strech goal

We could then store the parsed metadata in the localstorage in order not to have to parse it again. We need to find a cheap way though to determine when what we have cached is stale.

Enhanced behavior on old browsers

In order to better deal with older browsers, these two mechanisms could be implemented.

1. Legacy+data attribute pairs, e.g. src= + data-src=

<img src="fallback-pic-on-old-browser.jpg" data-src="pic-with-regions.jpg">. If web components are supported by the browser, our component's constructor kicks in and copies the content of data-src= to src=. If the component later gets manually disabled, it will restore the original src= value. We can imagine the same behavior for other attributes, like srcset= and sizes=.

2. CSS class marking well-functioning components

If web components are supported by the browser, out component's constructor kicks in and adds the image-display-control-supported CSS class. The user could then use such a stylesheet in their project:

img[is="image-display-control"] {
  border: 1px solid green;
}

img[is="image-display-control"]:not(.image-display-control-supported) {
  display: none;
}

Create a `<div>` web component

So far we have implemented an <img is="image-display-control" src="..."> web component.

Implement a <div is="image-display-control-div" style="background-image: url(...);"> web component.

Refactor `ImageDisplayControl.ts`

The main file ImageDisplayControl.ts has grown a lot recently and should be refactored. Some of the logic (calculations, region overlays, ...) should be moved away into different files with different concerns.

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.