diff --git a/README.md b/README.md index 96c06de..75489c0 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,11 @@ Implements ideas from the following papers: - [Measuring perceived color difference using YIQ NTSC transmission color space in mobile applications](https://www.spiedigitallibrary.org/conference-proceedings-of-spie/8011/80119D/Simple-perceptual-color-space-for-color-specification-and-real-time/10.1117/12.901997.full) (2010, Yuriy Kotsarenko, Fernando Ramos) - [Anti-aliased pixel and intensity slope detector](https://www.researchgate.net/publication/234126755_Anti-aliased_Pixel_and_Intensity_Slope_Detector) (2009, Vytautas Vyšniauskas) -## [Demo](https://observablehq.com/@mourner/pixelmatch-demo) +## Demo + +[observablehq](https://observablehq.com/@mourner/pixelmatch-demo) + +[Github page](https://mapbox.github.io/pixelmatch/demo) ## Example output @@ -105,7 +109,7 @@ Or use in the browser from a CDN: ```html + + diff --git a/demo/styles.css b/demo/styles.css new file mode 100644 index 0000000..bc6121a --- /dev/null +++ b/demo/styles.css @@ -0,0 +1,343 @@ +/* Base styles */ +* { + box-sizing: border-box; +} + +body { + font-family: Arial, sans-serif; + max-width: 1200px; + margin: 0 auto; + padding: 20px; + background-color: #f5f5f5; + line-height: 1.6; +} + +/* Container */ +.container { + background: white; + padding: 20px; + border-radius: 8px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); +} + +/* Header */ +header { + text-align: center; + margin-bottom: 30px; +} + +header h1 { + color: #333; + margin-bottom: 10px; +} + +.subtitle { + color: #666; + margin: 10px 0; +} + +.subtitle a { + color: #007bff; + text-decoration: none; +} + +.subtitle a:hover { + text-decoration: underline; +} + +/* Controls */ +.controls { + text-align: center; + margin: 20px 0; +} + +/* Buttons */ +.btn { + background-color: #007bff; + color: white; + border: none; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; + font-size: 16px; + margin: 10px; + transition: background-color 0.3s ease; +} + +.btn:hover { + background-color: #0056b3; +} + +.btn-primary { + background-color: #007bff; +} + +.btn-primary:hover { + background-color: #0056b3; +} + +.btn-danger { + background-color: #dc3545; +} + +.btn-danger:hover { + background-color: #c82333; +} + +.btn-secondary { + background-color: #6c757d; +} + +.btn-secondary:hover { + background-color: #5a6268; +} + +.btn-warning { + background-color: #ffc107; +} + +.btn-warning:hover { + background-color: #e0a800; +} + +/* Images container */ +.images-container { + display: flex; + justify-content: space-between; + margin: 20px 0; + gap: 15px; +} + +.image-display { + flex: 1; + text-align: center; + background: #f8f9fa; + padding: 15px; + border-radius: 8px; + border: 2px dashed #dee2e6; + transition: all 0.3s ease; + cursor: pointer; +} + +.image-display.drag-over { + background: #e3f2fd; + border-color: #2196f3; + transform: scale(1.02); + box-shadow: 0 4px 20px rgba(33, 150, 243, 0.3); +} + +.image-display.drag-over .placeholder-text { + color: #2196f3; +} + +.image-display img { + max-width: 100%; + max-height: 300px; + border-radius: 5px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); +} + +.image-container { + position: relative; + cursor: pointer; + display: inline-block; +} + +.image-overlay { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background: linear-gradient(transparent, rgba(0, 0, 0, 0.7)); + padding: 20px 10px 10px 10px; + border-radius: 0 0 5px 5px; + opacity: 0; + transition: opacity 0.3s ease; +} + +.image-container:hover .image-overlay { + opacity: 1; +} + +.image-display.no-image { + display: flex; + align-items: center; + justify-content: center; + min-height: 200px; + color: #6c757d; +} + +.placeholder-text { + color: #6c757d; + font-style: italic; + margin: 0; +} + +.help-text { + font-size: 12px; + margin-top: 10px; + color: #6c757d; +} + +/* File input */ +.file-input { + display: none; +} + +/* Result section */ +.result { + text-align: center; + padding: 20px; + background: white; + border-radius: 8px; + margin-top: 20px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + border: 1px solid #dee2e6; +} + +/* Options section */ +.options-section { + background: #f8f9fa; + border-radius: 8px; + margin: 20px 0; + border: 1px solid #dee2e6; + overflow: hidden; +} + +.options-header { + background: #e9ecef; + padding: 15px 20px; + cursor: pointer; + display: flex; + justify-content: space-between; + align-items: center; + transition: background-color 0.3s ease; +} + +.options-header:hover { + background: #dee2e6; +} + +.options-header h3 { + margin: 0; + color: #555; +} + +.toggle-icon { + font-size: 18px; + font-weight: bold; + color: #666; + transition: transform 0.3s ease; +} + +.options-content { + padding: 20px; + transition: max-height 0.3s ease, opacity 0.3s ease; + max-height: 1000px; + opacity: 1; +} + +.options-content.collapsed { + max-height: 0; + opacity: 0; + padding: 0 20px; +} + +.options-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); + gap: 20px; + margin: 20px 0; +} + +.option-group { + display: flex; + flex-direction: column; + gap: 8px; +} + +.option-group label { + font-weight: bold; + color: #333; + font-size: 14px; +} + +.option-group input[type='range'] { + width: 100%; +} + +.option-group input[type='color'] { + width: 60px; + height: 40px; + border: none; + border-radius: 5px; + cursor: pointer; +} + +.option-group input[type='checkbox'] { + width: 20px; + height: 20px; + cursor: pointer; +} + +.option-group small { + color: #6c757d; + font-size: 12px; + font-style: italic; +} + +.option-group span { + font-weight: bold; + color: #007bff; + font-size: 14px; +} + +.options-actions { + text-align: center; + margin-top: 20px; +} + +/* Diff image display */ +.diff-image-container { + text-align: center; +} + +.diff-image-container img { + max-width: 100%; + border-radius: 5px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); +} + +.download-btn { + margin-top: 10px; + background-color: #28a745; + padding: 8px 16px; + border: none; + border-radius: 4px; + color: white; + cursor: pointer; + transition: background-color 0.3s ease; +} + +.download-btn:hover { + background-color: #218838; +} + +/* Responsive design */ +@media (max-width: 768px) { + .images-container { + flex-direction: column; + } + + .options-grid { + grid-template-columns: 1fr; + } + + .container { + padding: 15px; + } + + body { + padding: 15px; + } +}