vue版本左右按钮点击移动 时间轴------ Timeline
效果:
代码:
<template>
<div class="carousel">
<span class="el-icon-d-arrow-left" @click="leftBtn(1)"></span>
<div class="list" v-bind:style="{ left: left + 'px' }">
<div class="listItem" v-for="(item, i) in activities" :key="i">
<div @click="iconClick(i)" :class="{ active: isActive == i }"></div>
<span :class="{ active1: isActive == i }">{{ item.timestamp }}月</span>
</div>
</div>
<span class="el-icon-d-arrow-right" @click="leftBtn(2)"></span>
</div>
</template>
<script>
export default {
name: "carousel",
data() {
return {
left: 0, //移动距离,num
isActive: 3, //当前选中样式
num: 0, //计数器
activities: [
{
timestamp: "1",
},
{
timestamp: "2",
},
{
timestamp: "3",
},
{
timestamp: "4",
},
{
timestamp: "5",
},
{
timestamp: "6",
},
{
timestamp: "7",
},
{
timestamp: "8",
},
{
timestamp: "2022-1",
},
{
timestamp: "10",
},
{
timestamp: "11",
},
{
timestamp: "12",
},
],
};
},
methods: {
leftBtn(val) {
let list = document.querySelector(".list"); //总长度
let listItem = document.querySelector(".listItem"); //1个宽度
// 剩余宽度点击数= (总宽度-视口宽度)/一个样式宽度
let listNum =
(list.scrollWidth - list.offsetWidth) / listItem.scrollWidth;
//左边点击
if (val == 2 && listNum > this.num) {
this.num++;
this.isActive++;
this.left -= listItem.scrollWidth;
} else if (val == 1 && listNum < this.num + listNum) {
//右边点击
this.num--;
this.isActive--;
this.left += listItem.scrollWidth;
}
},
iconClick(val) {
this.isActive = val;
},
},
mounted() {},
};
</script>
<style lang="less" scope>
.carousel {
// border: 1px solid yellow;
position: relative;
height: 100px;
width: 50vw;
overflow: hidden;
white-space: nowrap;
.list {
margin: 0;
padding: 0;
height: 100%;
position: relative;
.listItem {
box-sizing: border-box;
display: inline-block;
margin: 0;
padding: 0;
width: 5vw;
height: 100%;
position: relative;
background-image: url(../../assets/bg.svg);
background-size: 100% 100%;
text-align: center;
div {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 15px;
width: 15px;
background-color: #00192e;
border-radius: 50%;
// animation: mymove 5s infinite;
}
div:hover {
background-color: #f1ee2c;
}
.active {
height: 15px;
width: 15px;
transition: background 1s ease 0.5s; /*简写*/
// transition-property: width; /*过渡属性名*/
// transition-duration: 5s; /*持续时间,默认为0*/
// transition-timing-function: ease; /*速度*/
// transition-delay: 3s; /*延迟*/
// border-radius: 50%;
background-color: #409eff;
cursor: pointer;
}
.active1 {
color: #409eff;
}
@keyframes mymove {
// from {
// left: 2.5vw;
// }
to {
left: 7.5vw;
}
}
span {
font-size: 12px;
position: absolute;
top: 75%;
left: 50%;
transform: translate(-50%, -50%);
}
}
}
.el-icon-d-arrow-left {
cursor: pointer;
position: absolute;
top: 50%;
left: 10px;
z-index: 2;
transform: translate(-50%, -50%);
}
.el-icon-d-arrow-right {
position: absolute;
top: 50%;
cursor: pointer;
right: 0px;
z-index: 2;
transform: translate(-50%, -50%);
}
.el-icon-d-arrow-right:hover {
color: #409eff;
}
.el-icon-d-arrow-left:hover {
color: #409eff;
}
}
</style>
直接引用,如有问题 勿怪,
# 之前按钮来回切换写反了效果,修改了一下 2022-3.-30 13:18 之前没修改
带一点点拖拽,没完全修复
<template>
<div class="carousel">
<span class="el-icon-d-arrow-left" @click="leftBtn(1)"></span>
<div class="list" v-bind:style="{ left: left + 'px' }" v-drag>
<div class="listItem" v-for="(item, i) in activities" :key="i">
<div @click="iconClick(i)" :class="{ active: isActive == i }"></div>
<span :class="{ active1: isActive == i }">{{ item.timestamp }}</span>
</div>
</div>
<span class="el-icon-d-arrow-right" @click="leftBtn(2)"></span>
</div>
</template>
<script>
export default {
name: "carousel",
data() {
return {
left: 0, //移动距离,num
isActive: 3, //当前选中样式
num: 0, //计数器
activities: [
{
timestamp: "1",
},
{
timestamp: "2",
},
{
timestamp: "3",
},
{
timestamp: "4",
},
{
timestamp: "5",
},
{
timestamp: "6",
},
{
timestamp: "7",
},
{
timestamp: "8",
},
{
timestamp: "2022-1",
},
{
timestamp: "10",
},
{
timestamp: "11",
},
{
timestamp: "12",
},
{
timestamp: "2022",
},
],
};
},
methods: {
leftBtn(val) {
let list = document.querySelector(".list"); //总长度
let listItem = document.querySelector(".listItem"); //1个宽度
// 剩余宽度点击数= (总宽度-视口宽度)/一个样式宽度
let listNum =
(list.scrollWidth - list.offsetWidth) / listItem.scrollWidth;
//左边点击
if (val == 2 && listNum > this.num) {
this.num++;
this.isActive++;
this.left -= listItem.scrollWidth;
} else if (val == 1 && listNum < this.num + listNum) {
//右边点击
this.num--;
this.isActive--;
this.left += listItem.scrollWidth;
}
},
iconClick(val) {
this.isActive = val;
console.log(val);
},
},
directives: {
drag: {
// 指令的定义
inserted: function(el) {
// el.drag();
console.log(el);
//获取元素
// var dv = document.getElementById("dv");
let x = 0;
let y = 0;
let l = 0;
let t = 0;
let isDown = false;
//鼠标按下事件
el.onmousedown = function(e) {
console.log(e);
//获取x坐标和y坐标
x = e.clientX;
// y = e.clientY;
//获取左部和顶部的偏移量
l = el.offsetLeft;
t = el.offsetTop;
//开关打开
isDown = true;
//设置样式
el.style.cursor = "move";
};
//鼠标移动
window.onmousemove = function(e) {
if (isDown == false) {
return;
}
//获取x和y
let nx = e.clientX;
// let ny = e.clientY;
//计算移动后的左偏移量和顶部的偏移量
let nl = nx - (x - l);
// let nt = ny - (y - t);
el.style.left = nl + "px";
// el.style.top = nt + "px";
};
//鼠标抬起事件
el.onmouseup = function() {
//开关关闭
isDown = false;
el.style.cursor = "default";
};
},
},
},
mounted() {},
};
</script>
<style lang="less" scope>
.carousel {
// border: 1px solid yellow;
position: relative;
height: 100px;
width: 50vw;
overflow: hidden;
white-space: nowrap;
.list {
margin: 0;
padding: 0;
height: 100%;
position: relative;
.listItem {
box-sizing: border-box;
display: inline-block;
margin: 0;
padding: 0;
width: 5vw;
height: 100%;
position: relative;
background-image: url(../../assets/bg.svg);
background-size: 100% 100%;
text-align: center;
div {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 15px;
width: 15px;
background-color: #00192e;
border-radius: 50%;
// animation: mymove 5s infinite;
}
div:hover {
background-color: #f1ee2c;
}
.active {
height: 15px;
width: 15px;
transition: background 1s ease 0.5s; /*简写*/
// transition-property: width; /*过渡属性名*/
// transition-duration: 5s; /*持续时间,默认为0*/
// transition-timing-function: ease; /*速度*/
// transition-delay: 3s; /*延迟*/
// border-radius: 50%;
background-color: #409eff;
cursor: pointer;
}
.active1 {
color: #409eff;
}
@keyframes mymove {
// from {
// left: 2.5vw;
// }
to {
left: 7.5vw;
}
}
span {
font-size: 12px;
position: absolute;
top: 75%;
left: 50%;
transform: translate(-50%, -50%);
}
}
}
.el-icon-d-arrow-left {
cursor: pointer;
position: absolute;
top: 50%;
left: 10px;
z-index: 2;
transform: translate(-50%, -50%);
}
.el-icon-d-arrow-right {
position: absolute;
top: 50%;
cursor: pointer;
right: 0px;
z-index: 2;
transform: translate(-50%, -50%);
}
.el-icon-d-arrow-right:hover {
color: #409eff;
}
.el-icon-d-arrow-left:hover {
color: #409eff;
}
}
</style>
|