Skip to content

Commit

Permalink
feat: add image inspector
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Ngo authored and stevenle committed Jan 27, 2023
1 parent 309f81b commit 379ed26
Showing 1 changed file with 126 additions and 0 deletions.
126 changes: 126 additions & 0 deletions src/ui/image-inspector.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import {DomWatcher} from '../dom/dom-watcher';

export interface ImageInspectorConfig {
/**
* The name of the css class to attached to each generated spacer item.
*/
cssClassName: string;

/**
* The query selector of all elements you want to check for margins / paddings
* on the page.
*/
querySelector: string;
}

/**
* A class that will visibly highlight image dimensions on your page
*
*
* Setup:
* 1) Create your image-inspector css class.
*
* .image-inspector
* align-items: center
* background: rgba(#1a73e8, 0.15)
* box-shadow: none !important
* display: flex
* font-size: 12px
* height: var(--height)
* justify-content: center
* left: var(--left)
* margin: 0 !important
* pointer-events: none
* position: fixed !important
* top: var(--top)
* width: var(--width)
* z-index: 9
*
*
* 2) Instantiate ImageInspector. The query selector tells to inspect
* all divs on the page. Update it to scope the ImageInspector.
*
* new ImageInspector({
* cssClassName: 'image-inspector',
* querySelector: '.my-module > img'
* })
*
*/

export class ImageInspector {
private watcher: DomWatcher;
private config: ImageInspectorConfig;

constructor(config: ImageInspectorConfig) {
this.config = config;
this.watcher = new DomWatcher();

this.watcher.add({
element: window,
on: ['click', 'resize', 'scroll'],
callback: this.run.bind(this),
});
this.run();
}

private createInspector(el: HTMLImageElement, top: string, left: number) {
const dimensionsEl = document.createElement('div');
dimensionsEl.classList.add(this.config.cssClassName);

dimensionsEl.style.setProperty('--left', `${left}px`);
dimensionsEl.style.setProperty('--top', top);
dimensionsEl.style.setProperty('--width', `${dimensionsEl.offsetWidth}px`);

const headingEl = document.createElement('strong');
const renderedSizeEl = document.createElement('span');
const intrinsicSizeEl = document.createElement('span');

headingEl.innerText = `${el.alt || el.src}`;
renderedSizeEl.innerText = `Rendered size: ${el.offsetWidth} x ${el.offsetHeight}`;
intrinsicSizeEl.innerText = `Intrinsic size: ${el.naturalWidth} x ${el.naturalHeight}`;

dimensionsEl!.appendChild(headingEl);
dimensionsEl!.appendChild(renderedSizeEl);
dimensionsEl!.appendChild(intrinsicSizeEl);

el.parentElement!.appendChild(dimensionsEl);

const rect = dimensionsEl.getBoundingClientRect();
if (rect.width > 80) {
dimensionsEl.style.setProperty('--max-width', `${rect.width * 1.5}px`);
} else {
dimensionsEl.style.setProperty('--max-width', '80px');
}

dimensionsEl.style.setProperty('--height', rect.height + 'px');
}

public run() {
this.removeInspectors();
this.createInspectors();
}

private createInspectors() {
[].forEach.call(
document.querySelectorAll(this.config.querySelector),
(el: HTMLImageElement) => {
const rect = el.getBoundingClientRect();
this.createInspector(el, `${rect.top}px`, rect.left);
}
);
}

private removeInspectors() {
[].forEach.call(
document.querySelectorAll(`.${this.config.cssClassName}`),
(el: HTMLImageElement) => {
el.parentNode!.removeChild(el);
}
);
}

public dispose() {
this.removeInspectors();
this.watcher && this.watcher.dispose();
}
}

0 comments on commit 379ed26

Please sign in to comment.