你能帮我创造一个无限旋转木马的效果吗?我有一个方法来做到这一点是通过重新启动图像轮播检查如果我到达图像的末尾,并返回到0与“progress = (progress <= 0) ? 100 : 0;
“,但我不喜欢它的效果,我想当我到达结束或几乎结束的项目,图像将始终继续显示,也就是说,它将始终在左侧和右侧都有图像,而不会看到重新启动转盘的效果
let progress = 50;
let startX = 0;
let active = 0;
let isDown = false;
const perView = 1
let totalScroll = 0
let autoplayInterval;
/*--------------------
Contants
--------------------*/
const speedWheel = 0.02
const speedDrag = -0.1
/*--------------------
Get Z
--------------------*/
const getZindex = (array, index) => (array.map((_, i) => (index === i) ? array.length : array.length - Math.abs(index - i)))
/*--------------------
Items
--------------------*/
const $items = document.querySelectorAll('.carousel-item')
const $cursors = document.querySelectorAll('.cursor')
const displayItems = (item, index, active) => {
const zIndex = getZindex([...$items], active)[index]
item.style.setProperty('--zIndex', zIndex)
item.style.setProperty('--active', (index-active)/$items.length)
}
/*--------------------
Animate
--------------------*/
const animate = () => {
progress = Math.max(0, Math.min(progress, 100))
active = Math.floor(progress/100*($items.length-1))
$items.forEach((item, index) => displayItems(item, index, active))
}
animate()
/*--------------------
Click on Items
--------------------*/
$items.forEach((item, i) => {
item.addEventListener('click', () => {
progress = (i/$items.length) * 100 + 10
animate()
})
})
const carousel = document.querySelector('.carousel-container');
const slides = document.querySelectorAll('.carousel-item');
const totalItems = $items.length;
const autoPlay = () => {
if (!isDown) {
progress += 6; // Ajusta la velocidad del autoplay según lo desees
if (progress >= 100) {
active = totalItems - 1; // Establecer la última imagen como activa
progress = 100; // Mantener el progreso al 100%
animate();
if (active === totalItems - 1) {
setTimeout(() => {
progress = (progress <= 0) ? 100 : 0;
}, 1500); // Establece el tiempo para mostrar la última imagen antes de reiniciar
}
} else {
animate();
}
}
};
/* Iniciar autoplay */
autoplayInterval = setInterval(autoPlay, 1000)
/*--------------------
Handlers
--------------------*/
const handleWheel = e => {
const wheelProgress = e.deltaY * speedWheel
progress = progress + wheelProgress
animate()
}
const handleMouseMove = (e) => {
if (e.type === 'mousemove') {
$cursors.forEach(($cursor) => {
$cursor.style.transform = `translate(${e.clientX}px, ${e.clientY}px)`
})
}
if (!isDown) return
const x = e.clientX || (e.touches && e.touches[0].clientX) || 0
const mouseProgress = (x - startX) * speedDrag
progress = progress + mouseProgress
startX = x
animate()
}
const handleMouseDown = e => {
isDown = true
startX = e.clientX || (e.touches && e.touches[0].clientX) || 0
}
const handleMouseUp = () => {
isDown = false
}
/*--------------------
Listeners
--------------------*/
document.addEventListener('mousedown', handleMouseDown)
document.addEventListener('mousemove', handleMouseMove)
document.addEventListener('mouseup', handleMouseUp)
document.addEventListener('touchstart', handleMouseDown)
document.addEventListener('touchmove', handleMouseMove)
document.addEventListener('touchend', handleMouseUp)
.carousel {
position: relative;
z-index: 1;
height: 550px;
overflow: hidden;
pointer-events: none;
background-image: url(img/Banner-NET-1.jpg);
background-size: contain;
}
.carousel-item {
--items: 10;
--width: clamp(150px, 30vw, 250px);
--height: clamp(150px, 40vw, 350px);
--x: calc(var(--active) * 800%);
--y: calc(var(--active) * 200%);
--rot: calc(var(--active) * 120deg);
--opacity: calc(var(--zIndex) / var(--items) * 3 - 2);
overflow: hidden;
position: absolute;
z-index: var(--zIndex);
width: var(--width);
height: var(--height);
margin: calc(var(--height) * -0.5) 0 0 calc(var(--width) * -0.5);
border-radius: 10px;
top: 50%;
left: 50%;
user-select: none;
transform-origin: 0% 100%;
box-shadow: 0 10px 50px 10px rgba(0, 0, 0, 0.5);
background: black;
pointer-events: all;
transform: translate(var(--x), var(--y)) rotate(var(--rot));
transition: transform 0.8s cubic-bezier(0, 0.02, 0, 1);
}
.carousel-item .carousel-box {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
transition: opacity 0.8s cubic-bezier(0, 0.02, 0, 1);
opacity: var(--opacity);
font-family: "Orelo-sw-db", serif;
}
.carousel-item .carousel-box:before {
content: "";
position: absolute;
z-index: 0;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to bottom, rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0) 30%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.5));
}
.portfolio-item-link .full-image:before {
z-index: -999;
}
.carousel-item .title {
position: absolute;
z-index: 1;
color: #fff;
bottom: 20px;
left: 20px;
transition: opacity 0.8s cubic-bezier(0, 0.02, 0, 1);
font-size: clamp(20px, 3vw, 30px);
text-shadow: 0 4px 4px rgba(0, 0, 0, 0.1);
}
.carousel-item .num {
position: absolute;
z-index: 1;
color: #fff;
top: 10px;
left: 20px;
transition: opacity 0.8s cubic-bezier(0, 0.02, 0, 1);
font-size: clamp(20px, 10vw, 80px);
}
.carousel-item img {
width: 100%;
height: 100%;
object-fit: cover;
pointer-events: none;
}
.layout {
position: absolute;
z-index: 0;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.layout:before {
content: "";
position: absolute;
z-index: 1;
top: 0;
left: 90px;
width: 10px;
height: 100%;
border: 1px solid #fff;
border-top: none;
border-bottom: none;
opacity: 0.15;
}
.layout .box {
position: absolute;
bottom: 0;
left: 30px;
color: #fff;
transform-origin: 0% 10%;
transform: rotate(-90deg);
font-size: 9px;
line-height: 1.4;
text-transform: uppercase;
opacity: 0.4;
}
/*# sourceMappingURL=style.css.map */
.icono {
position: absolute;
top: 150px;
left: 103px;
color: #fff;
border: solid 1px #fff;
border-radius: 30px;
padding: 5px;
transition-property: all;
transition-duration: 200ms;
transition-timing-function: ease;
z-index: 999;
}
.icono:hover {
color: #413B52;
border: solid 1px #fff;
width: 50px;
height: 50px;
left: 103px;
top: 147px;
}
@media (max-width: 767px) {
.icono {
position: absolute;
top: 50% !important; /* Centrado vertical */
left: 50% !important; /* Centrado horizontal */
transform: translate(-50%, -50%) !important; /* Ajuste para centrar en ambas direcciones */
color: #fff;
border: solid 1px #fff;
border-radius: 30px;
padding: 5px;
transition: all 200ms ease;
z-index: 999;
}
.title {
display: flex;
align-items: center; /* Centrado vertical */
justify-content: center; /* Centrado horizontal */
/* Agrega estilos adicionales si es necesario */
}
.title h5 {
margin: 0; /* Elimina el margen predeterminado del <h5> */
/* Agrega estilos adicionales si es necesario */
}
.carousel-item .title {
position: absolute;
z-index: 1;
color: #fff;
bottom: 28% !important;
left: 30% !important;
transition: opacity 0.8s cubic-bezier(0, 0.02, 0, 1);
font-size: clamp(20px, 3vw, 30px);
text-shadow: 0 4px 4px rgba(0, 0, 0, 0.1);
}
.carousel-item {
--items: 10;
--width: clamp(190px, 30vw, 250px) !important;
--height: clamp(230px, 40vw, 350px) !important;
--x: calc(var(--active) * 800%);
--y: calc(var(--active) * 200%);
--rot: calc(var(--active) * 120deg);
--opacity: calc(var(--zIndex) / var(--items) * 3 - 2);
overflow: hidden;
position: absolute;
z-index: var(--zIndex);
width: var(--width);
height: var(--height);
margin: calc(var(--height) * -0.5) 0 0 calc(var(--width) * -0.5);
border-radius: 10px;
top: 50%;
left: 50%;
user-select: none;
transform-origin: 0% 100%;
box-shadow: 0 10px 50px 10px rgba(0, 0, 0, 0.5);
background: black;
pointer-events: all;
transform: translate(var(--x), var(--y)) rotate(var(--rot));
transition: transform 0.8s cubic-bezier(0, 0.02, 0, 1);
}
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="carousel">
<div class="carousel-item">
<div class="carousel-box">
<a href="https://www.youtube.com/watch?v=i4OGOxjSflQ" target="_self" class="portfolio-item-link full-image" data-fancybox="thegem-portfolio" data-elementor-open-lightbox="no"><svg class="icono" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-player-play-filled" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M6 4v16a1 1 0 0 0 1.524 .852l13 -8a1 1 0 0 0 0 -1.704l-13 -8a1 1 0 0 0 -1.524 .852z" stroke-width="0" fill="currentColor" />
</svg></a>
<div class="title"><h5>test text 01</h5></div>
<img src="http://pruebas.significadosyletras.com/slider/img/zif.jpg" />
</div>
</div>
<div class="carousel-item">
<div class="carousel-box">
<a href="https://www.youtube.com/watch?v=i4OGOxjSflQ" target="_self" class="portfolio-item-link full-image" data-fancybox="thegem-portfolio" data-elementor-open-lightbox="no"><svg class="icono" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-player-play-filled" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M6 4v16a1 1 0 0 0 1.524 .852l13 -8a1 1 0 0 0 0 -1.704l-13 -8a1 1 0 0 0 -1.524 .852z" stroke-width="0" fill="currentColor" />
</svg></a>
<div class="title"><h5>test text 02</h5></div>
<img src="http://pruebas.significadosyletras.com/slider/img/zif.jpg" />
</div>
</div>
<div class="carousel-item">
<div class="carousel-box">
<a href="https://www.youtube.com/watch?v=i4OGOxjSflQ" target="_self" class="portfolio-item-link full-image" data-fancybox="thegem-portfolio" data-elementor-open-lightbox="no"><svg class="icono" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-player-play-filled" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M6 4v16a1 1 0 0 0 1.524 .852l13 -8a1 1 0 0 0 0 -1.704l-13 -8a1 1 0 0 0 -1.524 .852z" stroke-width="0" fill="currentColor" />
</svg></a>
<div class="title"><h5>test text 03</h5></div>
<img
src="http://pruebas.significadosyletras.com/slider/img/zif.jpg"
/>
</div>
</div>
<div class="carousel-item">
<div class="carousel-box">
<a href="https://www.youtube.com/watch?v=i4OGOxjSflQ" target="_self" class="portfolio-item-link full-image" data-fancybox="thegem-portfolio" data-elementor-open-lightbox="no"><svg class="icono" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-player-play-filled" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M6 4v16a1 1 0 0 0 1.524 .852l13 -8a1 1 0 0 0 0 -1.704l-13 -8a1 1 0 0 0 -1.524 .852z" stroke-width="0" fill="currentColor" />
</svg></a>
<div class="title"><h5>test text 04</h5></div>
<img src="http://pruebas.significadosyletras.com/slider/img/zif.jpg" />
</div>
</div>
<div class="carousel-item">
<div class="carousel-box">
<a href="https://www.youtube.com/watch?v=i4OGOxjSflQ" target="_self" class="portfolio-item-link full-image" data-fancybox="thegem-portfolio" data-elementor-open-lightbox="no"><svg class="icono" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-player-play-filled" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M6 4v16a1 1 0 0 0 1.524 .852l13 -8a1 1 0 0 0 0 -1.704l-13 -8a1 1 0 0 0 -1.524 .852z" stroke-width="0" fill="currentColor" />
</svg></a>
<div class="title"><h5>test text 05</h5></div>
<img src="http://pruebas.significadosyletras.com/slider/img/zif.jpg" />
</div>
</div>
<div class="carousel-item">
<a href="https://www.youtube.com/watch?v=i4OGOxjSflQ" target="_self" class="portfolio-item-link full-image" data-fancybox="thegem-portfolio" data-elementor-open-lightbox="no"><svg class="icono" xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-player-play-filled" width="44" height="44" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<path d="M6 4v16a1 1 0 0 0 1.524 .852l13 -8a1 1 0 0 0 0 -1.704l-13 -8a1 1 0 0 0 -1.524 .852z" stroke-width="0" fill="currentColor" />
</svg></a>
<div class="carousel-box">
<div class="title"><h5>test text 06</h5></div>
<img src="http://pruebas.significadosyletras.com/slider/img/zif.jpg" />
</div>
</div>
</div></body></html>
1条答案
按热度按时间s3fp2yjn1#
Marquee看起来工作的很好(HTML),否则,你可以动画图像从A点移动到B点,然后在屏幕外传送回A点,有效地模仿无限的图像传送带