initial
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
class VrtsComparisons extends window.HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.resolveElements();
|
||||
this.bindFunctions();
|
||||
this.bindEvents();
|
||||
this.init();
|
||||
}
|
||||
|
||||
resolveElements() {
|
||||
this.$content = document.querySelector( '[data-vrts-fullscreen]' );
|
||||
this.$fullscreen = this.querySelector( '[data-vrts-fullscreen-open]' );
|
||||
this.$control = this.querySelector(
|
||||
'[data-vrts-comparisons-slider-control]'
|
||||
);
|
||||
this.$diffIndicator = this.querySelector(
|
||||
'[data-vrts-comparisons-diff-inidicator]'
|
||||
);
|
||||
this.$comparison = this.querySelector(
|
||||
'[data-vrts-comparisons-slot="comparison"] img'
|
||||
);
|
||||
}
|
||||
|
||||
bindFunctions() {
|
||||
this.onFullscreenToggle = this.onFullscreenToggle.bind( this );
|
||||
this.onControlChange = this.onControlChange.bind( this );
|
||||
this.onFullScreenChange = this.onFullScreenChange.bind( this );
|
||||
this.onLoadComparison = this.onLoadComparison.bind( this );
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
this.$fullscreen.addEventListener( 'click', this.onFullscreenToggle );
|
||||
this.$control.addEventListener( 'input', this.onControlChange );
|
||||
document.addEventListener(
|
||||
'fullscreenchange',
|
||||
this.onFullScreenChange
|
||||
);
|
||||
}
|
||||
|
||||
init() {
|
||||
this.worker = new window.Worker(
|
||||
new URL( 'worker.js', import.meta.url )
|
||||
);
|
||||
this.worker.onmessage = this.onWorkerMessage.bind( this );
|
||||
if ( this.$comparison.complete ) {
|
||||
this.onLoadComparison();
|
||||
} else {
|
||||
this.$comparison.onload = this.onLoadComparison;
|
||||
}
|
||||
}
|
||||
|
||||
onLoadComparison() {
|
||||
const imageData = this.createOffscreenCanvarImageData(
|
||||
this.$comparison
|
||||
);
|
||||
this.worker.postMessage( {
|
||||
action: 'analyzeImage',
|
||||
imageData,
|
||||
} );
|
||||
}
|
||||
|
||||
createOffscreenCanvarImageData( image ) {
|
||||
const canvas = new window.OffscreenCanvas(
|
||||
image.naturalWidth,
|
||||
image.naturalHeight
|
||||
);
|
||||
const ctx = canvas.getContext( '2d' );
|
||||
ctx.drawImage( image, 0, 0 );
|
||||
return ctx.getImageData( 0, 0, canvas.width, canvas.height );
|
||||
}
|
||||
|
||||
requestFullscreen( element ) {
|
||||
if ( element.requestFullscreen ) {
|
||||
element.requestFullscreen();
|
||||
} else if ( element.webkitRequestFullscreen ) {
|
||||
element.webkitRequestFullscreen();
|
||||
} else if ( element.msRequestFullscreen ) {
|
||||
element.msRequestFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
exitFullscreen() {
|
||||
if ( document.exitFullscreen ) {
|
||||
document.exitFullscreen();
|
||||
} else if ( document.webkitExitFullscreen ) {
|
||||
document.webkitExitFullscreen();
|
||||
} else if ( document.msExitFullscreen ) {
|
||||
document.msExitFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
getFullscreenElement() {
|
||||
return (
|
||||
document.fullscreenElement ||
|
||||
document.webkitFullscreenElement ||
|
||||
document.msFullscreenElement
|
||||
);
|
||||
}
|
||||
|
||||
onFullscreenToggle( e ) {
|
||||
e.preventDefault();
|
||||
|
||||
if ( this.getFullscreenElement() === this.$content ) {
|
||||
this.exitFullscreen();
|
||||
} else {
|
||||
this.requestFullscreen( this.$content );
|
||||
}
|
||||
}
|
||||
|
||||
onFullScreenChange() {
|
||||
this.$content.setAttribute(
|
||||
'data-vrts-fullscreen',
|
||||
this.getFullscreenElement() === this.$content
|
||||
);
|
||||
}
|
||||
|
||||
onControlChange( e ) {
|
||||
this.style.setProperty(
|
||||
'--vrts-comparisons-slider-position',
|
||||
`${ e.target.value }%`
|
||||
);
|
||||
}
|
||||
|
||||
onWorkerMessage( e ) {
|
||||
if ( e.data?.action === 'analyzedImage' ) {
|
||||
this.highlightPixels( e.data.coloredPixels );
|
||||
}
|
||||
}
|
||||
|
||||
highlightPixels( pixels ) {
|
||||
const ctx = this.$diffIndicator.getContext( '2d' );
|
||||
this.$diffIndicator.width = this.$comparison.naturalWidth;
|
||||
this.$diffIndicator.height = this.$comparison.naturalHeight;
|
||||
ctx.clearRect(
|
||||
0,
|
||||
0,
|
||||
this.$comparison.naturalWidth,
|
||||
this.$comparison.naturalHeight
|
||||
);
|
||||
ctx.fillStyle = '#cc1818';
|
||||
pixels.forEach( ( y ) => {
|
||||
ctx.fillRect( 0, y - 2, ctx.canvas.width, 3 );
|
||||
} );
|
||||
}
|
||||
|
||||
connectedCallback() {}
|
||||
|
||||
disconnectedCallback() {
|
||||
this.$fullscreen?.removeEventListener(
|
||||
'click',
|
||||
this.onFullscreenToggle
|
||||
);
|
||||
this.$control?.removeEventListener( 'input', this.onControlChange );
|
||||
document.removeEventListener(
|
||||
'fullscreenchange',
|
||||
this.onFullScreenChange
|
||||
);
|
||||
this.worker?.terminate();
|
||||
this.worker = null;
|
||||
}
|
||||
}
|
||||
|
||||
window.customElements.define( 'vrts-comparisons', VrtsComparisons );
|
||||
Reference in New Issue
Block a user