') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - EssentialBlocks/image-comparison · GitHub
Skip to content

Repository files navigation

Image Comparison

Let your visitors compare images and make your website interactive — a standalone Gutenberg block plugin by WPDeveloper, part of the Essential Blocks family.

WordPressPHPLicense

About

Image Comparison adds a before/after slider to the WordPress block editor. Drop in two images, then control the slider handle, orientation, hover behaviour, labels, colors and spacing from the block sidebar. Handy for WooCommerce stores, portfolios, and any before/after showcase.

The front-end slider is powered by react-compare-image.

Features

  • Completely customizable — images, size, colors, labels, and typography
  • Vertical & horizontal comparison modes
  • Slider on hover or drag-to-compare
  • Super light-weight — no extra resources, optimized for fast loading and instant live editing
  • Native block editor experience — full inspector controls with responsive settings

Requirements

MinimumTested up to
WordPress6.07.1
PHP7.48.5

Installation

From the block editor

  1. Open the WordPress Block (Gutenberg) editor
  2. Search for Image Comparison
  3. Install in one click

Manual

  1. Upload image-comparison to /wp-content/plugins/
  2. Activate the plugin through the Plugins menu in WordPress
  3. Follow the documentation

Development

This repository uses two git submodules. Clone with them, or the build and the plugin will both be incomplete:

git clone --recurse-submodules git@github.com:EssentialBlocks/image-comparison.git
# already cloned?
git submodule update --init --recursive
SubmodulePathPurpose
controlscontrols/Shared Essential Blocks inspector controls
style-handlerlib/style-handler/Front-end CSS generation

Install dependencies and build:

npm install # install dependencies
npm run start # development build with watch
npm run build # production build
npm run lint:js # lint JavaScript
npm run lint:css # lint styles
npm run format:js # format source

Built with @wordpress/scripts. webpack.config.js builds two entries — dist/index.js (editor) and dist/frontend/index.js (front end) — plus dist/style.css.

CleanWebpackPlugin is filtered out of the config on purpose: dist/controls.js and dist/controls.css are vendored artifacts produced by the central Essential Blocks pipeline, not by this repository's build. Deleting dist/ removes them with no way to regenerate them here.

Source lives in src/, shared controls in controls/, and the PHP entry point is image-comparison.php.

Packaging a release

Zips are produced with wp dist-archive, which honours .distignore:

wp package install wp-cli/dist-archive-command # once
wp dist-archive . ../image-comparison.zip

Branches

BranchPurpose
masterStable, released code. Default branch.
latestStaging for the next release.
devActive development. Open pull requests against this branch.

Contributing

Issues and pull requests are welcome at EssentialBlocks/image-comparison. Please branch off dev and target dev with your pull request.

Contributors

Support

License

GPL-3.0-or-later — see the licence text.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

5 watching

Forks

Releases

Packages

Contributors

Languages