mirror of
https://github.com/zen-browser/astro-site-test.git
synced 2025-07-07 21:39:58 +02:00
feat(how-much): added more way to interact with the images
This commit is contained in:
parent
d083320e0e
commit
d52d737d6d
3 changed files with 89 additions and 13 deletions
|
@ -30,7 +30,7 @@ import { Image } from "astro:assets";
|
||||||
@tailwind base;
|
@tailwind base;
|
||||||
@layer base {
|
@layer base {
|
||||||
section {
|
section {
|
||||||
@apply section flex flex-col items-center gap-md;
|
@apply section flex flex-col items-center gap-md py-20;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
|
|
|
@ -26,6 +26,7 @@ const modes: ModesOptions[] = ["compact", "collapsed", "standard", "split"];
|
||||||
name="view"
|
name="view"
|
||||||
value={mode}
|
value={mode}
|
||||||
checked={mode === "compact"}
|
checked={mode === "compact"}
|
||||||
|
class="sr-only"
|
||||||
/>
|
/>
|
||||||
<span>{mode.charAt(0).toUpperCase() + mode.slice(1)}</span>
|
<span>{mode.charAt(0).toUpperCase() + mode.slice(1)}</span>
|
||||||
</label>
|
</label>
|
||||||
|
@ -74,6 +75,8 @@ const modes: ModesOptions[] = ["compact", "collapsed", "standard", "split"];
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const radioButtons = document.querySelectorAll('input[name="view"]');
|
const radioButtons = document.querySelectorAll('input[name="view"]');
|
||||||
|
const radioGroup = document.getElementById("radio-group") as HTMLElement;
|
||||||
|
const labels = radioGroup.querySelectorAll("label");
|
||||||
const imageWrapper = document.getElementById("image-wrapper") as HTMLElement;
|
const imageWrapper = document.getElementById("image-wrapper") as HTMLElement;
|
||||||
const indicators = document.querySelectorAll(".indicator");
|
const indicators = document.querySelectorAll(".indicator");
|
||||||
const modeOrder = ["compact", "collapsed", "standard", "split"];
|
const modeOrder = ["compact", "collapsed", "standard", "split"];
|
||||||
|
@ -127,15 +130,78 @@ const modes: ModesOptions[] = ["compact", "collapsed", "standard", "split"];
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
labels.forEach((label) => {
|
||||||
|
label.addEventListener("mouseenter", (e) => {
|
||||||
|
if (e.target instanceof HTMLLabelElement) {
|
||||||
|
const input = e.target.querySelector("input") as HTMLInputElement;
|
||||||
|
if (input) {
|
||||||
|
input.checked = true;
|
||||||
|
updateImages(input.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
indicators.forEach((indicator, index) => {
|
indicators.forEach((indicator, index) => {
|
||||||
indicator.addEventListener("click", () => {
|
indicator.addEventListener("click", () => {
|
||||||
updateImages(modeOrder[index]);
|
updateImages(modeOrder[index]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
indicator.addEventListener("mouseenter", () => {
|
||||||
|
updateImages(modeOrder[index]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
slider.addEventListener("input", () => {
|
slider.addEventListener("input", () => {
|
||||||
updateImages(modeOrder[parseInt(slider.value)]);
|
updateImages(modeOrder[parseInt(slider.value)]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let startX = 0;
|
||||||
|
let currentX = 0;
|
||||||
|
let isDragging = false;
|
||||||
|
|
||||||
|
imageWrapper.addEventListener("touchstart", (e) => {
|
||||||
|
startX = e.touches[0].clientX;
|
||||||
|
isDragging = true;
|
||||||
|
imageWrapper.style.transition = "none";
|
||||||
|
});
|
||||||
|
|
||||||
|
imageWrapper.addEventListener("touchmove", (e) => {
|
||||||
|
currentX = e.touches[0].clientX;
|
||||||
|
|
||||||
|
const deltaX = (currentX - startX) / 4;
|
||||||
|
|
||||||
|
const newTranslateX = deltaX + currentIndex * -100;
|
||||||
|
|
||||||
|
const maxTranslateX = (modeOrder.length - 1) * -100;
|
||||||
|
|
||||||
|
if (newTranslateX <= 10 && newTranslateX >= maxTranslateX - 10) {
|
||||||
|
imageWrapper.style.transform = `translateX(${newTranslateX}%)`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
imageWrapper.addEventListener("touchend", () => {
|
||||||
|
isDragging = false;
|
||||||
|
imageWrapper.style.transition = "transform 0.3s ease-in-out";
|
||||||
|
const deltaX = currentX - startX;
|
||||||
|
if (deltaX > 50 && currentIndex > 0) {
|
||||||
|
updateImages(modeOrder[currentIndex - 1]);
|
||||||
|
} else if (deltaX < -50 && currentIndex < modeOrder.length - 1) {
|
||||||
|
updateImages(modeOrder[currentIndex + 1]);
|
||||||
|
} else {
|
||||||
|
updateImages(modeOrder[currentIndex]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
imageWrapper.addEventListener("wheel", (e) => {
|
||||||
|
if (e.deltaY < 0 && currentIndex > 0) {
|
||||||
|
e.preventDefault();
|
||||||
|
updateImages(modeOrder[currentIndex - 1]);
|
||||||
|
} else if (e.deltaY > 0 && currentIndex < modeOrder.length - 1) {
|
||||||
|
e.preventDefault();
|
||||||
|
updateImages(modeOrder[currentIndex + 1]);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -147,21 +213,21 @@ const modes: ModesOptions[] = ["compact", "collapsed", "standard", "split"];
|
||||||
}
|
}
|
||||||
|
|
||||||
section > div {
|
section > div {
|
||||||
@apply flex flex-col gap-md rounded-lg p-6;
|
@apply flex flex-col gap-md rounded-lg py-6;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
@apply flex cursor-pointer items-center gap-3 rounded-md p-3 transition-colors hover:bg-gray-100;
|
@apply flex cursor-pointer items-center gap-3 rounded-md p-3 transition-colors duration-200 hover:bg-secondary;
|
||||||
|
}
|
||||||
|
|
||||||
|
label:has(input:checked) {
|
||||||
|
@apply bg-secondary;
|
||||||
}
|
}
|
||||||
|
|
||||||
label span {
|
label span {
|
||||||
@apply text-lg;
|
@apply text-lg;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="radio"] {
|
|
||||||
@apply h-4 w-4 text-secondary focus:ring-secondary;
|
|
||||||
}
|
|
||||||
|
|
||||||
#image-container {
|
#image-container {
|
||||||
@apply relative aspect-[1.55/1] overflow-clip rounded-lg;
|
@apply relative aspect-[1.55/1] overflow-clip rounded-lg;
|
||||||
}
|
}
|
||||||
|
@ -171,7 +237,7 @@ const modes: ModesOptions[] = ["compact", "collapsed", "standard", "split"];
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
@apply aspect-[1.55/1] bg-[#272626] object-cover;
|
@apply aspect-[1.55/1] bg-[#272626] object-cover first:rounded-l-lg last:rounded-r-lg;
|
||||||
}
|
}
|
||||||
|
|
||||||
#radio-group {
|
#radio-group {
|
||||||
|
|
|
@ -49,6 +49,14 @@ module.exports = {
|
||||||
],
|
],
|
||||||
dm: ["DM Sans"],
|
dm: ["DM Sans"],
|
||||||
},
|
},
|
||||||
|
fontSize: {
|
||||||
|
"scale-sm": "clamp(1rem, 2vw, 1.5rem)",
|
||||||
|
"scale-md": "clamp(1.5rem, 3vw, 2rem)",
|
||||||
|
"scale-lg": "clamp(3rem, 6vw, 4rem)",
|
||||||
|
"scale-xl": "clamp(4rem, 8vw, 5rem)",
|
||||||
|
"scale-2xl": "clamp(5rem, 10vw, 6rem)",
|
||||||
|
"scale-3xl": "clamp(6rem, 12vw, 7rem)",
|
||||||
|
},
|
||||||
screens: {
|
screens: {
|
||||||
"-sm": { max: "639px" },
|
"-sm": { max: "639px" },
|
||||||
"-md": { max: "767px" },
|
"-md": { max: "767px" },
|
||||||
|
@ -62,13 +70,15 @@ module.exports = {
|
||||||
plugin(({ addBase, addComponents, addUtilities, theme }) => {
|
plugin(({ addBase, addComponents, addUtilities, theme }) => {
|
||||||
addBase({
|
addBase({
|
||||||
h2: {
|
h2: {
|
||||||
"@apply text-7xl font-bold text-primary": {},
|
fontSize: `clamp(${theme("fontSize.6xl")}, 10vw, calc(${theme("fontSize.6xl")} + 1rem))`,
|
||||||
},
|
"@apply font-bold text-primary leading-none": {},
|
||||||
p: {
|
|
||||||
"@apply text-primary": {},
|
|
||||||
},
|
},
|
||||||
h3: {
|
h3: {
|
||||||
"@apply text-5xl font-bold text-primary": {},
|
fontSize: `clamp(${theme("fontSize.5xl")}, 10vw, calc(${theme("fontSize.5xl")} + 1rem))`,
|
||||||
|
"@apply font-bold text-primary leading-none": {},
|
||||||
|
},
|
||||||
|
p: {
|
||||||
|
"@apply text-primary leading-none": {},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
addComponents({
|
addComponents({
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue