V_LN
KPCKevin Powell - Community
•Created by V_LN on 9/9/2024 in #front-end
Infinite scroller switches direction mid way through
.tag-list {
margin: 0;
padding-inline: 0;
list-style: none;
}
.tag-list li {
padding: 1rem;
background: var(--clr-primary-400);
border-radius: 0.5rem;
box-shadow: 0 0.5rem 1rem -0.25rem var(--clr-primary-900);
}
.scroller__inner {
padding-block: 1rem;
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
.scroller {
max-width: 600px;
}
.scroller[data-animated="true"] {
overflow: hidden;
-webkit-mask: linear-gradient(
90deg,
transparent,
white 20%,
white 80%,
transparent
);
mask: linear-gradient(
90deg,
transparent,
white 20%,
white 80%,
transparent
);
}
.scroller[data-animated="true"] .scroller__inner {
width: max-content;
flex-wrap: nowrap;
animation:
scroll
var(--_animation-duration, 5s)
linear
infinite;
}
@keyframes scroll {
to {
transform: translateX(calc(-50% - 0.5rem));
}
}
.tag-list {
margin: 0;
padding-inline: 0;
list-style: none;
}
.tag-list li {
padding: 1rem;
background: var(--clr-primary-400);
border-radius: 0.5rem;
box-shadow: 0 0.5rem 1rem -0.25rem var(--clr-primary-900);
}
.scroller__inner {
padding-block: 1rem;
display: flex;
gap: 1rem;
flex-wrap: wrap;
}
.scroller {
max-width: 600px;
}
.scroller[data-animated="true"] {
overflow: hidden;
-webkit-mask: linear-gradient(
90deg,
transparent,
white 20%,
white 80%,
transparent
);
mask: linear-gradient(
90deg,
transparent,
white 20%,
white 80%,
transparent
);
}
.scroller[data-animated="true"] .scroller__inner {
width: max-content;
flex-wrap: nowrap;
animation:
scroll
var(--_animation-duration, 5s)
linear
infinite;
}
@keyframes scroll {
to {
transform: translateX(calc(-50% - 0.5rem));
}
}
4 replies
KPCKevin Powell - Community
•Created by V_LN on 9/9/2024 in #front-end
Infinite scroller switches direction mid way through
const easeIn = (t) => t * t;
const easeOut = (t) => 1 - Math.pow(1 - t, 2);
useEffect(() => {
updateAnimationSpeed(10);
const accelerate = () => {
smoothSpeedTransition(10, 1, 3000, easeIn);
};
const decelerate = () => {
smoothSpeedTransition(1, 20, 5000, easeOut);
};
accelerate();
setTimeout(() => {
decelerate();
}, 3000);
return () => {};
}, []);
const scrollerAttributes = {
className: "scroller",
"data-animated": isAnimated ? "true" : undefined,
"data-direction": dataDirection,
};
return (
<div {...scrollerAttributes} ref={scrollerRef}>
<ul
className='tag-list scroller__inner'
ref={animationRef}
>
{scrollerContent.map((item, index) => (
<li key={index}>
<div className='flex flex-col items-center'>
<div className="w-[100px] h-[100px] overflow-clip">
<img src={item.winnable.image} alt={item.winnable.title} className="w-full h-auto" />
</div>
<h3 className='mt-2'>{item.winnable.title}</h3>
</div>
</li>
))}
</ul>
</div>
);
}
const easeIn = (t) => t * t;
const easeOut = (t) => 1 - Math.pow(1 - t, 2);
useEffect(() => {
updateAnimationSpeed(10);
const accelerate = () => {
smoothSpeedTransition(10, 1, 3000, easeIn);
};
const decelerate = () => {
smoothSpeedTransition(1, 20, 5000, easeOut);
};
accelerate();
setTimeout(() => {
decelerate();
}, 3000);
return () => {};
}, []);
const scrollerAttributes = {
className: "scroller",
"data-animated": isAnimated ? "true" : undefined,
"data-direction": dataDirection,
};
return (
<div {...scrollerAttributes} ref={scrollerRef}>
<ul
className='tag-list scroller__inner'
ref={animationRef}
>
{scrollerContent.map((item, index) => (
<li key={index}>
<div className='flex flex-col items-center'>
<div className="w-[100px] h-[100px] overflow-clip">
<img src={item.winnable.image} alt={item.winnable.title} className="w-full h-auto" />
</div>
<h3 className='mt-2'>{item.winnable.title}</h3>
</div>
</li>
))}
</ul>
</div>
);
}
4 replies
KPCKevin Powell - Community
•Created by V_LN on 9/9/2024 in #front-end
Infinite scroller switches direction mid way through
Code to component:
import '../../css/InfiniteScroller.css';
import React, { useEffect, useState, useRef } from "react";
export default function InfiniteScroller({ items, winningItemId, dataDirection }) {
const [scrollerContent, setScrollerContent] = useState(items);
const [isAnimated, setIsAnimated] = useState(false);
const scrollerRef = useRef(null);
const animationRef = useRef(null);
const hasDuplicated = useRef(false);
useEffect(() => {
if (!hasDuplicated.current && !window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
setScrollerContent((prevContent) => {
let newContent = [...prevContent];
for (let i = 0; i < 3; i++) {
newContent = [...newContent, ...items];
}
return newContent;
});
setIsAnimated(true);
hasDuplicated.current = true;
}
}, [items]);
const updateAnimationSpeed = (speed) => {
if (animationRef.current) {
animationRef.current.style.setProperty('--_animation-duration', `${speed}s`);
}
};
const smoothSpeedTransition = (startSpeed, endSpeed, duration, easingFunction) => {
let startTime = null;
const step = (timestamp) => {
if (!startTime) startTime = timestamp;
const elapsed = timestamp - startTime;
const progress = Math.min(elapsed / duration, 1);
const easedProgress = easingFunction(progress);
const newSpeed = startSpeed + (endSpeed - startSpeed) * easedProgress;
updateAnimationSpeed(newSpeed);
if (progress < 1) {
requestAnimationFrame(step);
}
};
requestAnimationFrame(step);
};
import '../../css/InfiniteScroller.css';
import React, { useEffect, useState, useRef } from "react";
export default function InfiniteScroller({ items, winningItemId, dataDirection }) {
const [scrollerContent, setScrollerContent] = useState(items);
const [isAnimated, setIsAnimated] = useState(false);
const scrollerRef = useRef(null);
const animationRef = useRef(null);
const hasDuplicated = useRef(false);
useEffect(() => {
if (!hasDuplicated.current && !window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
setScrollerContent((prevContent) => {
let newContent = [...prevContent];
for (let i = 0; i < 3; i++) {
newContent = [...newContent, ...items];
}
return newContent;
});
setIsAnimated(true);
hasDuplicated.current = true;
}
}, [items]);
const updateAnimationSpeed = (speed) => {
if (animationRef.current) {
animationRef.current.style.setProperty('--_animation-duration', `${speed}s`);
}
};
const smoothSpeedTransition = (startSpeed, endSpeed, duration, easingFunction) => {
let startTime = null;
const step = (timestamp) => {
if (!startTime) startTime = timestamp;
const elapsed = timestamp - startTime;
const progress = Math.min(elapsed / duration, 1);
const easedProgress = easingFunction(progress);
const newSpeed = startSpeed + (endSpeed - startSpeed) * easedProgress;
updateAnimationSpeed(newSpeed);
if (progress < 1) {
requestAnimationFrame(step);
}
};
requestAnimationFrame(step);
};
4 replies
KPCKevin Powell - Community
•Created by V_LN on 8/5/2024 in #front-end
Text dissapears when set to relative
nvm its because of another eleemnet thats setting the graident on the text
3 replies
KPCKevin Powell - Community
•Created by V_LN on 8/5/2024 in #front-end
Text dissapears when set to relative
3 replies