wheel rotation adjustment

This commit is contained in:
Chaebean Yang 2025-06-10 01:24:02 +09:00
parent 06cfd4dad8
commit 32fa693b5c

View File

@ -67,7 +67,7 @@
} }
if (memory?.images?.length) { if (memory?.images?.length) {
columnGroups = await extractColumnwiseColors(memory.images); columnGroups = await extractColumnwiseColors(memory.images, true);
currentImageIndex = 0; currentImageIndex = 0;
} }
} else { } else {
@ -83,7 +83,7 @@
if (memorySnap.exists()) { if (memorySnap.exists()) {
droppedTripId = tripId; droppedTripId = tripId;
droppedMemory = memorySnap.val(); droppedMemory = memorySnap.val();
droppedColumnGroups = await extractColumnwiseColors(droppedMemory.images); droppedColumnGroups = await extractColumnwiseColors(droppedMemory.images, false);
droppedImageIndex = 0; droppedImageIndex = 0;
} }
} }
@ -102,28 +102,6 @@
transformOrigin: 'center center' transformOrigin: 'center center'
}; };
$: if (memory?.images?.length && columnGroups.length) {
const angleOffset = -(360 / memory.images.length) * currentImageIndex;
const gradients = makeConcentricGradients(columnGroups, angleOffset);
const MASK_COUNT = 3;
for (let i = 0; i < MASK_COUNT; i++) {
gradients.push('radial-gradient(circle, var(--black) 100%)');
}
gradientLayers = gradients.map((bg, i) => {
const scale = 1 - i * 0.1;
return `background: ${bg};
width: ${scale * 100}%;
height: ${scale * 100}%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;`;
});
}
async function getImageData(url) { async function getImageData(url) {
const img = new Image(); const img = new Image();
img.crossOrigin = 'Anonymous'; img.crossOrigin = 'Anonymous';
@ -173,7 +151,7 @@
const r = data[idx], g = data[idx + 1], b = data[idx + 2]; const r = data[idx], g = data[idx + 1], b = data[idx + 2];
const [h, s, br] = rgbToHsb(r, g, b); const [h, s, br] = rgbToHsb(r, g, b);
if (br < 20 || s < 10) continue; if (br < 5 || s < 20) continue;
const rgb = `rgb(${r},${g},${b})`; const rgb = `rgb(${r},${g},${b})`;
columns[colIndex].push(rgb); columns[colIndex].push(rgb);
@ -187,7 +165,7 @@
}); });
} }
async function extractColumnwiseColors(imageUrls) { async function extractColumnwiseColors(imageUrls, reverseColumns = true) {
const columnColorGroups = [[], [], [], [], []]; const columnColorGroups = [[], [], [], [], []];
for (const url of imageUrls) { for (const url of imageUrls) {
@ -198,20 +176,47 @@
}); });
} }
return columnColorGroups.reverse(); return reverseColumns ? columnColorGroups.reverse() : columnColorGroups;
} }
function makeConcentricGradients(groups, rotationOffset = 0) { function makeConcentricGradients(groups, rotationOffset = 0, imageCount = 1, isDropped = false) {
const directionFactor = 1;
const additionalAdjustment = isDropped ? -360 / imageCount : 0;
return groups.map(colors => { return groups.map(colors => {
const step = 360 / colors.length; const step = 360 / colors.length;
const start = rotationOffset + 90 - 180 / memory.images.length; const rawStart = rotationOffset + directionFactor * (90 - 180 / imageCount);
return `conic-gradient(from ${start}deg, ${colors.map((c, i) => `${c} ${i * step}deg ${(i + 1) * step}deg`).join(', ')})`; const start = isDropped ? -rawStart + additionalAdjustment : rawStart;
return `conic-gradient(from ${start}deg, ${
colors.map((c, i) => `${c} ${i * step}deg ${(i + 1) * step}deg`).join(', ')
})`;
});
}
$: if (memory?.images?.length && columnGroups.length) {
const angleOffset = -(360 / memory.images.length) * currentImageIndex;
const gradients = makeConcentricGradients(columnGroups, angleOffset, memory.images.length, false);
const MASK_COUNT = 3;
for (let i = 0; i < MASK_COUNT; i++) {
gradients.push('radial-gradient(circle, var(--black) 100%)');
}
gradientLayers = gradients.map((bg, i) => {
const scale = 1 - i * 0.1;
return `background: ${bg};
width: ${scale * 100}%;
height: ${scale * 100}%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;`;
}); });
} }
$: if (droppedMemory?.images?.length && droppedColumnGroups.length) { $: if (droppedMemory?.images?.length && droppedColumnGroups.length) {
const angleOffset = -(360 / droppedMemory.images.length) * droppedImageIndex; const angleOffset = -(360 / droppedMemory.images.length) * droppedImageIndex;
const gradients = makeConcentricGradients(droppedColumnGroups, angleOffset); const gradients = makeConcentricGradients(droppedColumnGroups, angleOffset, droppedMemory.images.length, true);
const MASK_COUNT = 3; const MASK_COUNT = 3;
for (let i = 0; i < MASK_COUNT; i++) { for (let i = 0; i < MASK_COUNT; i++) {
@ -263,13 +268,17 @@
function handleDrop(event) { function handleDrop(event) {
event.preventDefault(); event.preventDefault();
if (droppedMemory) return;
const droppedTripId = event.dataTransfer.getData("tripId"); const droppedTripId = event.dataTransfer.getData("tripId");
const droppedMemoryId = event.dataTransfer.getData("memoryId"); const droppedMemoryId = event.dataTransfer.getData("memoryId");
loadDroppedTrip(droppedTripId, droppedMemoryId); loadDroppedTrip(droppedTripId, droppedMemoryId);
} }
function allowDrop(event) { function allowDrop(event) {
event.preventDefault(); if (!droppedMemory) {
event.preventDefault();
}
} }
</script> </script>
@ -316,8 +325,12 @@
{/if} {/if}
<div class="arrow-controls"> <div class="arrow-controls">
<button on:click={prevImage}>▲</button> <button on:click={prevImage}>
<button on:click={nextImage}>▼</button> <img src="/lucide_chevron-up.png" alt="Up" width="24" height="24" />
</button>
<button on:click={nextImage}>
<img src="/lucide_chevron-down.png" alt="Down" width="24" height="24" />
</button>
</div> </div>
</div> </div>
@ -335,8 +348,12 @@
<img class="dropped-img" src={droppedCurrentImage} alt="Dropped Image" /> <img class="dropped-img" src={droppedCurrentImage} alt="Dropped Image" />
{/if} {/if}
<div class="dropped-controls"> <div class="dropped-controls">
<button on:click={prevDroppedImage}>▲</button> <button on:click={prevDroppedImage}>
<button on:click={nextDroppedImage}>▼</button> <img src="/lucide_chevron-up.png" alt="Up" width="24" height="24" />
</button>
<button on:click={nextDroppedImage}>
<img src="/lucide_chevron-down.png" alt="Down" width="24" height="24" />
</button>
</div> </div>
{/if} {/if}
</div> </div>