<template>
<div class="container">
<div class="title">
</div>
<div id="banner">
<div class="img-list img-wrapper">
<div class="img-box">
<div class="info">
<h3>one</h3>
</div>
<img src="@/assets/projectImage/1.png" alt="" />
</div>
<div class="img-box">
<div class="info">
<h3>two</h3>
</div>
<img src="@/assets/projectImage/2.png" alt="" />
</div>
<div class="img-box">
<div class="info">
<h3>three</h3>
</div>
<img src="@/assets/projectImage/3.png" alt="" />
</div>
<div class="img-box">
<div class="info">
<h3>four</h3>
</div>
<img src="@/assets/projectImage/4.png" alt="" />
</div>
<div class="img-box">
<div class="info">
<h3>five</h3>
</div>
<img src="@/assets/projectImage/5.png" alt="" />
</div>
<div class="img-box" id="last-img-box">
<div class="info">
<h3>six</h3>
</div>
<img src="@/assets/projectImage/6.png" alt="" />
</div>
</div>
</div>
<div class="btn-group">
<button class="last btn">
<svg
t="1686471404424"
class="icon left"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="2373"
width="128"
height="128"
>
<path
d="M862.485 481.154H234.126l203.3-203.3c12.497-12.497 12.497-32.758 0-45.255s-32.758-12.497-45.255 0L135.397 489.373c-12.497 12.497-12.497 32.758 0 45.254l256.774 256.775c6.249 6.248 14.438 9.372 22.627 9.372s16.379-3.124 22.627-9.372c12.497-12.497 12.497-32.759 0-45.255l-203.3-203.301h628.36c17.036 0 30.846-13.81 30.846-30.846s-13.81-30.846-30.846-30.846z"
fill=""
p-id="2374"
></path>
</svg>
</button>
<button class="next btn">
<svg
t="1686471404424"
class="icon right"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="2373"
width="128"
height="128"
>
<path
d="M862.485 481.154H234.126l203.3-203.3c12.497-12.497 12.497-32.758 0-45.255s-32.758-12.497-45.255 0L135.397 489.373c-12.497 12.497-12.497 32.758 0 45.254l256.774 256.775c6.249 6.248 14.438 9.372 22.627 9.372s16.379-3.124 22.627-9.372c12.497-12.497 12.497-32.759 0-45.255l-203.3-203.301h628.36c17.036 0 30.846-13.81 30.846-30.846s-13.81-30.846-30.846-30.846z"
fill=""
p-id="2374"
></path>
</svg>
</button>
</div>
</div>
</template>
<script setup>
import { ref, computed, onMounted } from "vue";
import pic01 from "@/assets/projectImage/1.png";
import pic02 from "@/assets/projectImage/2.png";
import pic03 from "@/assets/projectImage/3.png";
import pic04 from "@/assets/projectImage/4.png";
import pic05 from "@/assets/projectImage/5.png";
import pic06 from "@/assets/projectImage/6.png";
onMounted(() => {
const imgListOne = document.querySelector(".img-list");
// 获取图片类数组,并将其转化为数组
let imgBoxList = Array.prototype.slice.call(
document.querySelectorAll(".img-list .img-box")
);
const imgBoxCount = imgBoxList.length;
const root = document.documentElement;
const btnGroup = document.querySelector(".btn-group");
const lastBtn = document.querySelector(".last");
const nextBtn = document.querySelector(".next");
const lastImgBox = document.getElementById("last-img-box");
// 获取--post-spacing和--post-size的值
const postSpacing = Number(
getComputedStyle(root).getPropertyValue("--post-spacing").replace("vw", "")
);
const postSize = Number(
getComputedStyle(root).getPropertyValue("--post-size").replace("vw", "")
);
// 根据图片的数量动态获取img-list的宽度
let imgListLength = (postSize + postSpacing) * imgBoxCount;
console.log(imgListLength);
// 根据图片的数量动态获取img-box的宽度
const imgBoxLength = postSize + postSpacing;
let index = 0;
let indexOne = 1;
let timer = null;
let animationTime = 0.5;
// 初始化数组中元素的的顺序,将最后一张图片放在第一位与html部分图片展示位置一致
imgBoxList.unshift(imgBoxList.pop());
// 设置imgListOne动画时间
imgListOne.style.transition = animationTime + "s ease";
// 设置按钮出现时间
setTimeout(function () {
btnGroup.style.opacity = "1";
btnGroup.style.bottom = "5%";
}, animationTime * 1000);
// 点击事件
function cilckFun(flag) {
//下一张 next
if (flag == "next") {
index--;
console.log(index);
// 因为右边没有显示的图片比较多,所以可以直接先整体向左移动
imgListOne.style.left = imgBoxLength * index + "vw";
setTimeout(function () {
imgListOne.style.transition = "none";
// 当点击下一个累计达到图片数量时,相当于要回到原点,则重置变量和位置
if (Math.abs(index) == imgBoxCount) {
index = 0;
imgListOne.style.left = 0;
imgBoxList.forEach((item) => {
if (item.id == "last-img-box") {
item.style.transform = `translateX(-160.68vw)`;
} else {
item.style.transform = "none";
}
});
} else {
// 当第一张图片为last-img-box时,说明已经跑完了一轮,则将其放在最后的位置,初始状态其为-160.68vw
if (imgBoxList[0].id == "last-img-box") {
lastImgBox.style.transition = "none";
lastImgBox.style.transform = "translateX(0px)";
} else if (index >= 0) {
/*
这种情况是为了解决在点击完第last,再点击next时造成的bug问题,其实就是回退,再点击last之前
没有加transform属性,点击last以后则添加了transform属性,再次点击next按钮后应该不加transform
*/
imgBoxList[0].style.transform = "none";
} else {
// 正常情况下,点击next,则将最左侧的图片移到最后
imgBoxList[0].style.transform = "translateX(160.68vw)";
}
}
// 模拟移动情况,将最左侧的图片(元素)移动到最后
imgBoxList.push(imgBoxList.shift());
}, animationTime * 1000);
} else {
// 上一张 last
index++;
console.log(index);
// 模拟移动情况,把最右侧的图片(元素)移动到最前
imgBoxList.unshift(imgBoxList.pop());
// 因为左侧图片只会有一张,所以需要先移动图片到左侧,再进行imgListOne的移到
if (imgBoxList[0].id == "last-img-box" && index != 0) {
// 当第一张图片为last-img-box时,说明已经跑完了一轮,此时相对于一开始的位置为-321.36vw
imgBoxList[0].style.transform = "translateX(-321.36vw)";
} else if (index < 0) {
// 这种情况与点击next按钮出现的回退现象一致
imgBoxList[0].style.transform = "none";
} else {
// 正常情况下,点击last,则将最右侧的图片移到最前
imgBoxList[0].style.transform = "translateX(-160.68vw)";
}
imgListOne.style.left = imgBoxLength * index + "vw";
lastImgBox.style.transition = "none";
// 当点击下一个累计达到图片数量时,相当于要回到原点,则重置变量和位置
if (Math.abs(index) == imgBoxCount) {
index = 0;
setTimeout(function () {
imgListOne.style.transition = "none";
imgListOne.style.left = 0;
imgBoxList.forEach((item) => {
if (item.id == "last-img-box") {
item.style.transform = "translateX(-160.68vw)";
} else {
item.style.transform = "none";
}
});
}, animationTime * 1000);
}
}
imgListOne.style.transition = animationTime + "s ease";
}
//节流函数
function throttle(fn, delay) {
return function () {
if (timer) {
return;
}
fn.apply(this, arguments);
timer = setTimeout(() => {
timer = null;
}, delay);
};
}
nextBtn.onclick = throttle(() => cilckFun("next"), animationTime * 1000);
lastBtn.onclick = throttle(() => cilckFun("last"), animationTime * 1000);
});
</script>
<style lang="scss" scoped>
.container {
width: 100%;
height: 90vh;
position: relative;
// padding: 100px 0;
// overflow: hidden;
// background-color: green;
}
@font-face {
font-family: Millik;
font-weight: 700;
src: url(./asset/font/Millik.c3f91cb.ttf) format("truetype");
text-rendering: optimizeLegibility;
}
:global(:root) {
--post-spacing: 1.78vw;
--post-size: 25vw;
--mask-size: 100vw;
}
* {
padding: 0;
margin: 0;
font-family: Millik, Arial, sans-serif;
font-size: 62.5%;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
box-sizing: border-box;
}
// body {
// background: #fff;
// background-image: url(./asset/image/grid.svg);
// background-repeat: repeat;
// background-size: 300px 300px;
// }
.title {
position: absolute;
height: 600px;
width: 800px;
text-align: center;
left: 50%;
top: 5%;
transform: translate(-50%, -5%);
p {
font-size: 4rem;
font-weight: 800;
white-space: nowrap;
}
}
#banner {
overflow: hidden;
position: relative;
width: 100vw;
height: calc(var(--post-size) / 0.72);
mask: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNDQwIiBoZWlnaHQ9IjUwMCIgdmlld0JveD0iMCAwIDE0NDAgNTAwIiBpZD0iaiI+CiAgPHBhdGggZmlsbD0icmdiKDIwMCwyMDAsMjAwKSIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMCAwczI3NS4wNCAxMDAgNzIwIDEwMFMxNDQwIDAgMTQ0MCAwdjUwMHMtMjc1LjA0LTEwMC03MjAtMTAwUzAgNTAwIDAgNTAwVjB6Ii8+Cjwvc3ZnPgo=);
mask-repeat: no-repeat;
mask-position: center;
mask-size: var(--mask-size);
position: absolute;
top: 10%;
.img-wrapper {
display: flex;
position: absolute;
width: 100%;
float: left;
height: calc(var(--post-size) / 0.72);
transform: translate(10.60vw, 0);
animation: admission 1.5s;
.img-box {
height: 100%;
display: inline-block;
margin-right: var(--post-spacing);
position: relative;
cursor: pointer;
.info {
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
left: 0;
top: 0;
height: 100%;
width: 100%;
background: hsla(0, 0%, 9%, 0.5);
text-align: center;
color: #fff9f1;
font-size: 4rem;
}
img {
width: var(--post-size);
height: 100%;
object-position: center;
object-fit: cover;
}
&:last-child {
transform: translate(-160.68vw, 0);
}
}
}
}
.btn-group {
// height: 0vh;
position: absolute;
left: 50%;
bottom:10%;
// padding-top: 20px;
// top: 50%;
transform: translate(-50%, -50%);
transition: 1s;
opacity: 0;
// background-color: pink;
width: 10vw;
display: flex;
justify-content: space-between;
.btn {
width: 60px;
height: 60px;
border-radius: 50%;
border: 1px solid #171717;
background-color: #fff;
margin: 10px;
cursor: pointer;
transition: 0.4s;
box-sizing: border-box;
&:hover {
transform: scale(1.2);
background-color: #000;
.icon {
fill: #fff;
}
}
.icon {
width: 30px;
height: 30px;
}
.right {
transform: rotate(180deg);
}
}
}
.img-list {
left: 0;
}
@keyframes admission {
0% {
transform: translate(140vw, 0);
}
100% {
transform: translate(10.60vw, 0);
}
}
</style>