Skip to content

Commit 76b72a4

Browse files
committed
add LucidNFT
1 parent 563da6c commit 76b72a4

4 files changed

Lines changed: 122 additions & 134 deletions

File tree

LucidNFT/index.html

Lines changed: 61 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ <h2>Method Overview</h2>
8181
<thead>
8282
<tr>
8383
<th>Domain</th>
84-
<th>Dataset Pairing</th>
84+
<th>Pairing</th>
8585
<th class="num">Baseline</th>
8686
<th class="num">LucidConsistency</th>
8787
</tr>
@@ -192,6 +192,10 @@ <h2>Results</h2>
192192
<img src="visualization/visualization_1.png" alt="Visual comparison of LucidNFT against Real-ISR baselines">
193193
<p class="image-caption">Visual comparison on RealLQ250. LucidNFT further improves semantic consistency and perceptual quality over the baseline LucidFlux, producing more faithful structures and richer texture details.</p>
194194
</div>
195+
<div class="hero-image">
196+
<img src="visualization/visualization_2.png" alt="Additional visual comparison of LucidNFT against Real-ISR baselines">
197+
<p class="image-caption">Additional visual comparison showing that LucidFlux(+LucidNFT) better preserves LR-consistent structures while recovering richer details across diverse real-world degradations.</p>
198+
</div>
195199
<div class="quantitative-results">
196200
<h3>Quantitative Results</h3>
197201
<div class="table-container">
@@ -628,74 +632,79 @@ <h3>Quantitative Results</h3>
628632

629633
<section id="gallery" class="info-section grid-gallery">
630634
<h2>Gallery</h2>
631-
<p class="image-caption">Click an LQ input to open an interactive slider comparison (LQ vs LucidFlux or LucidFlux(+LucidNFT)).</p>
635+
<p class="image-caption">Hover to enlarge the LR input, then compare LucidFlux vs LucidFlux(+LucidNFT) with an interactive slider.</p>
632636

633637
<div class="lq-gallery">
634-
<button class="lq-card" type="button" data-example="016" data-lq="gallery/016_lq.jpg" data-base="gallery/016_lucidflux.jpg" data-nft="gallery/016_lucidnft.jpg">
635-
<img src="gallery/016_lq.jpg" alt="Example 016 LQ input">
636-
<div class="lq-meta">
637-
<span class="lq-title">Example 016</span>
638-
<span class="lq-sub">LQ input</span>
639-
</div>
640-
</button>
641-
642-
<button class="lq-card" type="button" data-example="137" data-lq="gallery/137_lq.jpg" data-base="gallery/137_lucidflux.jpg" data-nft="gallery/137_lucidnft.jpg">
643-
<img src="gallery/137_lq.jpg" alt="Example 137 LQ input">
644-
<div class="lq-meta">
645-
<span class="lq-title">Example 137</span>
646-
<span class="lq-sub">LQ input</span>
638+
<div class="lq-card" tabindex="0" role="button" aria-label="Example 016 gallery item" data-example="016">
639+
<div class="lq-media">
640+
<img class="lq-thumb" src="gallery/016_lq.jpg" alt="Example 016 LR input">
641+
<div class="lq-hover-compare" aria-hidden="true">
642+
<div class="image-comparison inline-comparison">
643+
<img src="gallery/016_lucidflux.jpg" alt="LucidFlux output" class="before-image">
644+
<img src="gallery/016_lucidnft.jpg" alt="LucidFlux(+LucidNFT) output" class="after-image">
645+
<div class="comparison-slider" aria-label="Comparison slider">
646+
<div class="slider-handle">
647+
<div class="slider-arrow">◀ ▶</div>
648+
</div>
649+
</div>
650+
<div class="compare-tag before">LucidFlux</div>
651+
<div class="compare-tag after">LucidFlux(+LucidNFT)</div>
652+
</div>
653+
</div>
647654
</div>
648-
</button>
649-
650-
<button class="lq-card" type="button" data-example="223" data-lq="gallery/223_lq.png" data-base="gallery/223_lucidflux.jpg" data-nft="gallery/223_lucidnft.jpg">
651-
<img src="gallery/223_lq.png" alt="Example 223 LQ input">
652655
<div class="lq-meta">
653-
<span class="lq-title">Example 223</span>
654-
<span class="lq-sub">LQ input</span>
656+
<span class="lq-title">Example 016</span>
657+
<span class="lq-sub">LR</span>
655658
</div>
656-
</button>
657-
</div>
658-
</section>
659-
660-
<div id="gallery-modal" class="gallery-modal" aria-hidden="true" role="dialog">
661-
<div class="gallery-modal__backdrop" data-gallery-close></div>
662-
<div class="gallery-modal__panel" role="document" aria-label="Gallery comparison">
663-
<button class="gallery-modal__close" type="button" aria-label="Close" data-gallery-close>&times;</button>
664-
<div class="gallery-modal__header">
665-
<div class="gallery-modal__title" id="gallery-modal-title">Example</div>
666659
</div>
667660

668-
<div class="gallery-comparison-block">
669-
<div class="gallery-comparison-title">LQ vs LucidFlux</div>
670-
<div class="image-comparison gallery-comparison" id="gallery-comparison-base">
671-
<img src="" alt="Before (LQ input)" class="before-image" id="gallery-before-base">
672-
<img src="" alt="After (LucidFlux output)" class="after-image" id="gallery-after-base">
673-
<div class="comparison-slider" id="gallery-slider-base" aria-label="Comparison slider (LucidFlux)">
674-
<div class="slider-handle">
675-
<div class="slider-arrow">◀ ▶</div>
661+
<div class="lq-card" tabindex="0" role="button" aria-label="Example 137 gallery item" data-example="137">
662+
<div class="lq-media">
663+
<img class="lq-thumb" src="gallery/137_lq.jpg" alt="Example 137 LR input">
664+
<div class="lq-hover-compare" aria-hidden="true">
665+
<div class="image-comparison inline-comparison">
666+
<img src="gallery/137_lucidflux.jpg" alt="LucidFlux output" class="before-image">
667+
<img src="gallery/137_lucidnft.jpg" alt="LucidFlux(+LucidNFT) output" class="after-image">
668+
<div class="comparison-slider" aria-label="Comparison slider">
669+
<div class="slider-handle">
670+
<div class="slider-arrow">◀ ▶</div>
671+
</div>
672+
</div>
673+
<div class="compare-tag before">LucidFlux</div>
674+
<div class="compare-tag after">LucidFlux(+LucidNFT)</div>
676675
</div>
677676
</div>
678-
<div class="compare-tag before">LQ</div>
679-
<div class="compare-tag after">LucidFlux</div>
677+
</div>
678+
<div class="lq-meta">
679+
<span class="lq-title">Example 137</span>
680+
<span class="lq-sub">LR</span>
680681
</div>
681682
</div>
682683

683-
<div class="gallery-comparison-block">
684-
<div class="gallery-comparison-title">LQ vs LucidFlux(+LucidNFT)</div>
685-
<div class="image-comparison gallery-comparison" id="gallery-comparison-nft">
686-
<img src="" alt="Before (LQ input)" class="before-image" id="gallery-before-nft">
687-
<img src="" alt="After (LucidFlux+LucidNFT output)" class="after-image" id="gallery-after-nft">
688-
<div class="comparison-slider" id="gallery-slider-nft" aria-label="Comparison slider (LucidFlux+LucidNFT)">
689-
<div class="slider-handle">
690-
<div class="slider-arrow">◀ ▶</div>
684+
<div class="lq-card" tabindex="0" role="button" aria-label="Example 223 gallery item" data-example="223">
685+
<div class="lq-media">
686+
<img class="lq-thumb" src="gallery/223_lq.png" alt="Example 223 LR input">
687+
<div class="lq-hover-compare" aria-hidden="true">
688+
<div class="image-comparison inline-comparison">
689+
<img src="gallery/223_lucidflux.jpg" alt="LucidFlux output" class="before-image">
690+
<img src="gallery/223_lucidnft.jpg" alt="LucidFlux(+LucidNFT) output" class="after-image">
691+
<div class="comparison-slider" aria-label="Comparison slider">
692+
<div class="slider-handle">
693+
<div class="slider-arrow">◀ ▶</div>
694+
</div>
695+
</div>
696+
<div class="compare-tag before">LucidFlux</div>
697+
<div class="compare-tag after">LucidFlux(+LucidNFT)</div>
691698
</div>
692699
</div>
693-
<div class="compare-tag before">LQ</div>
694-
<div class="compare-tag after">LucidFlux(+LucidNFT)</div>
700+
</div>
701+
<div class="lq-meta">
702+
<span class="lq-title">Example 223</span>
703+
<span class="lq-sub">LR</span>
695704
</div>
696705
</div>
697706
</div>
698-
</div>
707+
</section>
699708

700709
<section id="contact-us" class="contact-us info-section">
701710
<h2>Contact</h2>

LucidNFT/script.js

Lines changed: 16 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -58,26 +58,11 @@ document.addEventListener('DOMContentLoaded', function() {
5858
initImageNavigation();
5959
// initAutoGallery 已禁用
6060

61-
function initGalleryModal() {
62-
const modal = document.getElementById('gallery-modal');
63-
const title = document.getElementById('gallery-modal-title');
64-
const baseComparison = document.getElementById('gallery-comparison-base');
65-
const baseSlider = document.getElementById('gallery-slider-base');
66-
const baseBefore = document.getElementById('gallery-before-base');
67-
const baseAfter = document.getElementById('gallery-after-base');
61+
function initInlineComparisonSliders() {
62+
const comparisons = Array.from(document.querySelectorAll('.image-comparison'));
63+
if (comparisons.length === 0) return;
6864

69-
const nftComparison = document.getElementById('gallery-comparison-nft');
70-
const nftSlider = document.getElementById('gallery-slider-nft');
71-
const nftBefore = document.getElementById('gallery-before-nft');
72-
const nftAfter = document.getElementById('gallery-after-nft');
73-
74-
if (!modal || !baseComparison || !baseSlider || !baseBefore || !baseAfter || !nftComparison || !nftSlider || !nftBefore || !nftAfter) return;
75-
76-
let currentExample = null;
77-
const dragState = {
78-
isDragging: false,
79-
active: null,
80-
};
65+
const dragState = { isDragging: false, active: null };
8166

8267
function updateSlider(comparisonEl, sliderEl, afterEl, x) {
8368
const rect = comparisonEl.getBoundingClientRect();
@@ -86,70 +71,32 @@ document.addEventListener('DOMContentLoaded', function() {
8671
afterEl.style.clipPath = `polygon(${percentage}% 0%, 100% 0%, 100% 100%, ${percentage}% 100%)`;
8772
}
8873

89-
function initComparison(comparisonEl, sliderEl, afterEl) {
74+
comparisons.forEach(comparisonEl => {
75+
const sliderEl = comparisonEl.querySelector('.comparison-slider');
76+
const afterEl = comparisonEl.querySelector('.after-image');
77+
if (!sliderEl || !afterEl) return;
78+
79+
// Drag start
9080
sliderEl.addEventListener('mousedown', (e) => {
9181
dragState.isDragging = true;
9282
dragState.active = { comparisonEl, sliderEl, afterEl };
9383
e.preventDefault();
84+
e.stopPropagation();
9485
});
95-
9686
sliderEl.addEventListener('touchstart', (e) => {
9787
dragState.isDragging = true;
9888
dragState.active = { comparisonEl, sliderEl, afterEl };
9989
e.preventDefault();
90+
e.stopPropagation();
10091
}, { passive: false });
10192

93+
// Click-to-jump
10294
comparisonEl.addEventListener('click', (e) => {
10395
if (e.target === sliderEl || e.target.closest('.slider-handle')) return;
10496
updateSlider(comparisonEl, sliderEl, afterEl, e.clientX);
10597
});
106-
}
107-
108-
function openModal(exampleBtn) {
109-
currentExample = exampleBtn;
110-
const id = exampleBtn.dataset.example || '';
111-
title.textContent = `Example ${id}`;
112-
113-
baseBefore.src = exampleBtn.dataset.lq;
114-
baseBefore.alt = `Example ${id} LQ input`;
115-
baseAfter.src = exampleBtn.dataset.base;
116-
117-
nftBefore.src = exampleBtn.dataset.lq;
118-
nftBefore.alt = `Example ${id} LQ input`;
119-
nftAfter.src = exampleBtn.dataset.nft;
120-
121-
modal.classList.add('is-open');
122-
modal.setAttribute('aria-hidden', 'false');
123-
document.body.style.overflow = 'hidden';
124-
125-
// Center sliders after layout.
126-
requestAnimationFrame(() => {
127-
const baseRect = baseComparison.getBoundingClientRect();
128-
updateSlider(baseComparison, baseSlider, baseAfter, baseRect.left + baseRect.width * 0.5);
129-
const nftRect = nftComparison.getBoundingClientRect();
130-
updateSlider(nftComparison, nftSlider, nftAfter, nftRect.left + nftRect.width * 0.5);
131-
});
132-
}
133-
134-
function closeModal() {
135-
modal.classList.remove('is-open');
136-
modal.setAttribute('aria-hidden', 'true');
137-
document.body.style.overflow = '';
138-
dragState.isDragging = false;
139-
dragState.active = null;
140-
}
141-
142-
document.querySelectorAll('.lq-card').forEach(btn => {
143-
btn.addEventListener('click', () => openModal(btn));
144-
});
145-
146-
modal.querySelectorAll('[data-gallery-close]').forEach(el => {
147-
el.addEventListener('click', closeModal);
14898
});
14999

150-
initComparison(baseComparison, baseSlider, baseAfter);
151-
initComparison(nftComparison, nftSlider, nftAfter);
152-
153100
document.addEventListener('mousemove', (e) => {
154101
if (!dragState.isDragging || !dragState.active) return;
155102
updateSlider(dragState.active.comparisonEl, dragState.active.sliderEl, dragState.active.afterEl, e.clientX);
@@ -159,20 +106,9 @@ document.addEventListener('DOMContentLoaded', function() {
159106
updateSlider(dragState.active.comparisonEl, dragState.active.sliderEl, dragState.active.afterEl, e.touches[0].clientX);
160107
}, { passive: true });
161108

162-
document.addEventListener('mouseup', () => {
163-
dragState.isDragging = false;
164-
dragState.active = null;
165-
});
166-
document.addEventListener('touchend', () => {
167-
dragState.isDragging = false;
168-
dragState.active = null;
169-
});
170-
171-
document.addEventListener('keydown', (e) => {
172-
if (!modal.classList.contains('is-open')) return;
173-
if (e.key === 'Escape') closeModal();
174-
});
109+
document.addEventListener('mouseup', () => { dragState.isDragging = false; dragState.active = null; });
110+
document.addEventListener('touchend', () => { dragState.isDragging = false; dragState.active = null; });
175111
}
176112

177-
initGalleryModal();
113+
initInlineComparisonSliders();
178114
});

LucidNFT/styles.css

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,35 @@ body {
251251
position: relative;
252252
}
253253

254-
.lq-card:hover img,
255-
.lq-card:focus-visible img {
254+
.lq-media {
255+
position: relative;
256+
border-radius: 12px;
257+
overflow: hidden;
258+
}
259+
260+
.lq-thumb {
261+
display: block;
262+
}
263+
264+
.lq-hover-compare {
265+
position: absolute;
266+
inset: 0;
267+
opacity: 0;
268+
transform: translateY(6px);
269+
transition: opacity 0.22s ease 0.12s, transform 0.22s ease 0.12s;
270+
pointer-events: none;
271+
z-index: 6;
272+
}
273+
274+
.lq-card:hover .lq-hover-compare,
275+
.lq-card:focus-visible .lq-hover-compare {
276+
opacity: 1;
277+
transform: translateY(0);
278+
pointer-events: auto;
279+
}
280+
281+
.lq-card:hover .lq-thumb,
282+
.lq-card:focus-visible .lq-thumb {
256283
transform: translateY(-3px) scale(1.18);
257284
box-shadow: 0 10px 22px rgba(0, 0, 0, 0.15);
258285
z-index: 5;
@@ -481,6 +508,17 @@ body {
481508
right: 12px;
482509
}
483510

511+
.inline-comparison {
512+
height: 100%;
513+
}
514+
515+
.inline-comparison .before-image,
516+
.inline-comparison .after-image {
517+
height: 100%;
518+
width: 100%;
519+
object-fit: contain;
520+
}
521+
484522
.table-wrapper {
485523
width: 100%;
486524
overflow-x: auto;
@@ -529,6 +567,11 @@ body {
529567
background-color: #f8fbff;
530568
color: #0f3f66;
531569
font-weight: 700;
570+
text-align: center;
571+
}
572+
573+
.table-wrapper th.left,
574+
.table-wrapper td.left {
532575
text-align: left;
533576
}
534577

1.5 MB
Loading

0 commit comments

Comments
 (0)