16 changed files with 1448 additions and 178 deletions
@ -0,0 +1,101 @@ |
|||
<template> |
|||
<div :class="{'hidden':hidden}" class="pagination-container"> |
|||
<el-pagination |
|||
:background="background" |
|||
:current-page.sync="currentPage" |
|||
:page-size.sync="pageSize" |
|||
:layout="layout" |
|||
:page-sizes="pageSizes" |
|||
:total="total" |
|||
v-bind="$attrs" |
|||
@size-change="handleSizeChange" |
|||
@current-change="handleCurrentChange" |
|||
/> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { scrollTo } from '@/utils/scroll-to' |
|||
|
|||
export default { |
|||
name: 'Pagination', |
|||
props: { |
|||
total: { |
|||
required: true, |
|||
type: Number |
|||
}, |
|||
page: { |
|||
type: Number, |
|||
default: 1 |
|||
}, |
|||
limit: { |
|||
type: Number, |
|||
default: 20 |
|||
}, |
|||
pageSizes: { |
|||
type: Array, |
|||
default() { |
|||
return [5, 20, 50, 100, 200 , 500] |
|||
} |
|||
}, |
|||
layout: { |
|||
type: String, |
|||
default: 'total, sizes, prev, pager, next, jumper' |
|||
}, |
|||
background: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
autoScroll: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
hidden: { |
|||
type: Boolean, |
|||
default: false |
|||
} |
|||
}, |
|||
computed: { |
|||
currentPage: { |
|||
get() { |
|||
return this.page |
|||
}, |
|||
set(val) { |
|||
this.$emit('update:page', val) |
|||
} |
|||
}, |
|||
pageSize: { |
|||
get() { |
|||
return this.limit |
|||
}, |
|||
set(val) { |
|||
this.$emit('update:limit', val) |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
handleSizeChange(val) { |
|||
this.$emit('pagination', { page: this.currentPage, limit: val }) |
|||
if (this.autoScroll) { |
|||
scrollTo(0, 800) |
|||
} |
|||
}, |
|||
handleCurrentChange(val) { |
|||
this.$emit('pagination', { page: val, limit: this.pageSize }) |
|||
if (this.autoScroll) { |
|||
scrollTo(0, 800) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.pagination-container { |
|||
background: #fff; |
|||
padding: 32px 16px; |
|||
} |
|||
.pagination-container.hidden { |
|||
display: none; |
|||
} |
|||
</style> |
@ -0,0 +1,614 @@ |
|||
<template> |
|||
<div class="sn" :class="show ? 'sn_show' : ''"> |
|||
|
|||
<!-- 1 --> |
|||
<!-- <div v-if="!show"> |
|||
<el-collapse @change="handleChange"> |
|||
<el-collapse-item title="今日收费TOP5" name="1"> |
|||
<div> |
|||
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="0.5rem" > |
|||
<el-form-item label="省份" prop="province"> |
|||
<el-select v-model="queryParams.province" placeholder="请选择省份" clearable size="small" |
|||
@change="areaDropDown"> |
|||
<el-option v-for="(item, i) in provinceOption" :key="i" :label="item.label" :value="item.label"> |
|||
</el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="城市" prop="city"> |
|||
<el-select v-model="queryParams.city" placeholder="请选择城市" clearable size="small" @change="areaDropDown"> |
|||
<el-option v-for="(item, i) in cityOption" :key="i" :label="item.label" :value="item.label"> |
|||
</el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="区域" prop="county"> |
|||
<el-select v-model="queryParams.county" placeholder="请选择区域" clearable size="small"> |
|||
<el-option v-for="(item, i) in countyOption" :key="i" :label="item.label" :value="item.label"> |
|||
</el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<div class="search"> |
|||
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">搜索</el-button> |
|||
<el-button icon="el-icon-refresh" size="small" @click="resetQuery">重置</el-button> |
|||
</div> |
|||
</el-form> |
|||
</div> |
|||
</el-collapse-item> |
|||
</el-collapse> |
|||
<div class="sn-body"> |
|||
<div class="table-header"> |
|||
<span style="width: 1rem">排行</span> |
|||
<span style="width: 2rem">停车场名称</span> |
|||
<span style="width: 2.1rem">收费金额</span> |
|||
<span style="width: .8rem">操作</span> |
|||
</div> |
|||
<vue-seamless-scroll :data="listData2" class="seamless-warp" :class-option="optionSetting"> |
|||
<div class="line" v-for="(item, index) in listData2" :key="index" |
|||
:class="item.accessType === '入场' ? 'in' : ''"> |
|||
<span class="td" v-if="index == 0" style="width: 1rem"><img src="/img/img3.png" alt=""></span> |
|||
<span class="td" v-if="index == 1" style="width: 1rem"><img src="/img/img4.png" alt=""></span> |
|||
<span class="td" v-if="index == 2" style="width: 1rem"><img src="/img/img5.png" alt=""></span> |
|||
<span class="td" v-if="index == 3" style="width: 1rem"><img src="/img/img6.png" alt=""></span> |
|||
<span class="td" v-if="index == 4" style="width: 1rem"><img src="/img/img7.png" alt=""></span> |
|||
<el-tooltip class="item" effect="dark" :content="item.parkingInfoName" placement="top"> |
|||
<span style="width: 2rem" class='title'>{{ item.parkingInfoName }}</span> |
|||
</el-tooltip> |
|||
<span style="width: 2.1rem">{{ item.totalAmount }}元</span> |
|||
<span style="width: .8rem" @click="toGo(item, index)">详情</span> |
|||
</div> |
|||
</vue-seamless-scroll> |
|||
</div> |
|||
</div> --> |
|||
|
|||
<!-- 2 --> |
|||
<div> |
|||
<el-collapse v-model="activeNames" @change="handleChange"> |
|||
<el-collapse-item title="今日收费TOP5" name="1"> |
|||
<div> |
|||
<el-form :model="queryParams" ref="queryForm" :inline="true" label-width="0.5rem"> |
|||
<el-form-item label="省份" prop="province"> |
|||
<el-select v-model="queryParams.province" placeholder="请选择省份" clearable size="small" |
|||
@change="areaDropDown"> |
|||
<el-option v-for="(item, i) in provinceOption" :key="i" :label="item.label" :value="item.label"> |
|||
</el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="城市" prop="city"> |
|||
<el-select v-model="queryParams.city" placeholder="请选择城市" clearable size="small" @change="areaDropDown"> |
|||
<el-option v-for="(item, i) in cityOption" :key="i" :label="item.label" :value="item.label"> |
|||
</el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="区域" prop="county"> |
|||
<el-select v-model="queryParams.county" placeholder="请选择区域" clearable size="small"> |
|||
<el-option v-for="(item, i) in countyOption" :key="i" :label="item.label" :value="item.label"> |
|||
</el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<div class="search"> |
|||
<el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">搜索</el-button> |
|||
<el-button icon="el-icon-refresh" size="small" @click="resetQuery">重置</el-button> |
|||
<el-button type="warning" icon="el-icon-refresh" size="small" @click="toGo('', '', false)">查看全部 |
|||
</el-button> |
|||
</div> |
|||
</el-form> |
|||
</div> |
|||
</el-collapse-item> |
|||
</el-collapse> |
|||
<div class="sn-body"> |
|||
<div class="table-header"> |
|||
<span style="width: 1rem">排行</span> |
|||
<span style="width: 2rem">停车场名称</span> |
|||
<span style="width: 2.1rem">收费金额</span> |
|||
<span style="width: .8rem">操作</span> |
|||
</div> |
|||
<div class="seamless-warp" :class="show ? 'sn_scroll' : ''"> |
|||
<div class="line" v-for="(item, index) in listData2" :key="index" |
|||
:class="item.accessType === '入场' ? 'in' : ''"> |
|||
<span class="td" v-if="index == 0" style="width: 1rem"><img src="/img/img3.png" alt=""></span> |
|||
<span class="td" v-if="index == 1" style="width: 1rem"><img src="/img/img4.png" alt=""></span> |
|||
<span class="td" v-if="index == 2" style="width: 1rem"><img src="/img/img5.png" alt=""></span> |
|||
<span class="td" v-if="index == 3" style="width: 1rem"><img src="/img/img6.png" alt=""></span> |
|||
<span class="td" v-if="index == 4" style="width: 1rem"><img src="/img/img7.png" alt=""></span> |
|||
<el-tooltip class="item" effect="dark" :content="item.parkingInfoName" placement="top"> |
|||
<span style="width: 2rem" class='title'>{{ item.parkingInfoName }}</span> |
|||
</el-tooltip> |
|||
<span style="width: 2.1rem">{{ item.totalAmount }}元</span> |
|||
<span style="width: .8rem" @click="toGo(item, index, true)">详情</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<el-col :span="23" class="twoPagePag"> |
|||
<pagination v-show="total > 0 && activeNames.length>0" :total="total" :page.sync="queryParams.pageNum" |
|||
:limit.sync="queryParams.pageSize" @pagination="getList" /> |
|||
</el-col> |
|||
</div> |
|||
|
|||
</div> |
|||
|
|||
|
|||
</template> |
|||
|
|||
<script> |
|||
import vueSeamlessScroll from 'vue-seamless-scroll' |
|||
import { BiApi, recursionAreasTree } from "@/api/form"; |
|||
export default { |
|||
name: "seamlessRank", |
|||
props: { |
|||
listData2: { |
|||
type: Array, |
|||
default() { |
|||
return [] |
|||
} |
|||
}, |
|||
authCode: { |
|||
type: String, |
|||
default() { |
|||
return '' |
|||
} |
|||
}, |
|||
total: { |
|||
default() { |
|||
return 0 |
|||
} |
|||
} |
|||
}, |
|||
components: { |
|||
vueSeamlessScroll |
|||
}, |
|||
watch: { |
|||
'listData2': { |
|||
deep: true, |
|||
handler: function (newV, oldV) { |
|||
console.log('watch中:', newV, oldV) |
|||
} |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
activeNames: [], |
|||
i: 2, |
|||
show: true, |
|||
// 省份 |
|||
provinceOption: [], |
|||
// 城市 |
|||
cityOption: [], |
|||
// 区 |
|||
countyOption: [], |
|||
// 查询参数 |
|||
queryParams: { |
|||
province: null, |
|||
city: null, |
|||
county: null, |
|||
authCode: null, |
|||
pageNum: 1, |
|||
pageSize: 5, |
|||
}, |
|||
optionSetting: { |
|||
step: 0.5, // 数值越大速度滚动越快 |
|||
limitMoveNum: this.listData2.length, // 开始无缝滚动的数据量 this.dataList.length |
|||
hoverStop: false, // 是否开启鼠标悬停stop |
|||
direction: 0, // 0向下 1向上 2向左 3向右 |
|||
autoPlay: true, |
|||
openWatch: true, // 开启数据实时监控刷新dom |
|||
singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1 |
|||
singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3 |
|||
waitTime: 1000 // 单步运动停止的时间(默认值1000ms) |
|||
} |
|||
} |
|||
}, |
|||
computed: { |
|||
|
|||
}, |
|||
mounted() { |
|||
this.areaDropDown() |
|||
}, |
|||
created() { |
|||
}, |
|||
methods: { |
|||
toGo(item, index, type) { |
|||
if (type) { |
|||
this.activeNames = []; |
|||
this.$emit("passfunction", item.pkParkingInfoId) |
|||
} else { |
|||
// 查询参数 |
|||
this.activeNames = []; |
|||
this.reset() |
|||
this.$emit("passfunction", '') |
|||
} |
|||
}, |
|||
handleChange(val) { |
|||
this.activeNames = val; |
|||
}, |
|||
reset() { |
|||
this.queryParams = { |
|||
province: null, |
|||
city: null, |
|||
county: null, |
|||
authCode: null, |
|||
pageNum: 1, |
|||
pageSize: 5, |
|||
} |
|||
}, |
|||
// 开放统计-车场排行 |
|||
getList() { |
|||
this.queryParams.authCode = this.authCode |
|||
BiApi.getParkingRanking(this.queryParams).then((res) => { |
|||
if (res && res.code === 200) this.$emit('changeMsg', res.rows, Number(res.total), true) |
|||
}) |
|||
}, |
|||
/** 重置按钮操作 */ |
|||
resetQuery() { |
|||
this.cityOption = []; |
|||
this.countyOption = []; |
|||
// 查询参数 |
|||
this.reset() |
|||
this.queryParams.authCode = this.authCode |
|||
BiApi.getParkingRanking(this.queryParams).then((res) => { |
|||
if (res && res.code === 200) this.$emit('changeMsg', res.rows, Number(res.total), false) |
|||
}) |
|||
}, |
|||
/** 搜索按钮操作 */ |
|||
handleQuery() { |
|||
this.activeNames = []; |
|||
this.getList(); |
|||
}, |
|||
|
|||
// 设置级联选择框的动态选择信息 |
|||
setProp() { |
|||
this.prop = { |
|||
lazy: true, |
|||
lazyLoad: (node, resolve) => { |
|||
let level = 2; |
|||
setTimeout(() => { |
|||
if (node.level == 0) { |
|||
recursionAreasTree |
|||
.areaDropDown() |
|||
.then((res) => { |
|||
// map方法根据你要的属性重组数组 |
|||
const cities = res.map((value) => ({ |
|||
treeId: value.value, |
|||
value: value.label, |
|||
label: value.label, |
|||
leaf: node.level >= level, |
|||
})); |
|||
|
|||
// 通过调用resolve将子节点数据返回,通知组件数据加载完成 |
|||
resolve(cities); |
|||
}) |
|||
.catch((err) => { |
|||
console.log(err); |
|||
}); |
|||
} |
|||
if (node.level != 0) { |
|||
let obj = { |
|||
parentId: node.data.treeId, |
|||
}; |
|||
recursionAreasTree |
|||
.areaDropDown(obj) |
|||
.then((res) => { |
|||
const areas = res.map((value) => ({ |
|||
treeId: value.value, |
|||
value: value.label, |
|||
label: value.label, |
|||
leaf: node.level >= level, |
|||
})); |
|||
// console.log(areas); |
|||
if (node.level == 2) { |
|||
this.areasList = [...areas]; |
|||
console.log(this.areasList); |
|||
} |
|||
// 通过调用resolve将子节点数据返回,通知组件数据加载完成 |
|||
resolve(areas); |
|||
}) |
|||
.catch((err) => { |
|||
console.log(err); |
|||
}); |
|||
} |
|||
}, 100); |
|||
}, |
|||
}; |
|||
}, |
|||
|
|||
// 获取单独省、市、县(区)下拉框 |
|||
areaDropDown(e) { |
|||
if (this.queryParams.province) { |
|||
if (this.queryParams.city) { |
|||
e = this.cityOption.filter(item => item.label === e)[0].value |
|||
} else { |
|||
e = this.provinceOption.filter(item => item.label === e)[0].value |
|||
} |
|||
} |
|||
if (!this.queryParams.province) { |
|||
this.queryParams.city = null; |
|||
this.queryParams.county = null; |
|||
this.cityOption = []; |
|||
this.countyOption = []; |
|||
} else if (!this.queryParams.city) { |
|||
this.queryParams.county = null; |
|||
this.countyOption = []; |
|||
} |
|||
let query = { |
|||
parentId: e, |
|||
}; |
|||
recursionAreasTree.areaDropDown(query).then((response) => { |
|||
if (!e) { |
|||
this.provinceOption = response; |
|||
} else if (e % 10000 == 0) { |
|||
this.queryParams.city = null; |
|||
this.queryParams.county = null; |
|||
this.cityOption = response; |
|||
} else { |
|||
this.queryParams.county = null; |
|||
this.countyOption = response; |
|||
} |
|||
}); |
|||
}, |
|||
}, |
|||
beforeDestroy() { |
|||
|
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
::-webkit-scrollbar-corner{ |
|||
display: none !important; |
|||
} |
|||
|
|||
.sn_scroll { |
|||
// overflow: scroll !important; |
|||
} |
|||
|
|||
.twoPagePag { |
|||
position: static !important; |
|||
} |
|||
|
|||
.pagination-container { |
|||
background: none !important; |
|||
padding: 0 0 !important; |
|||
} |
|||
|
|||
::v-deep .el-pagination__total { |
|||
color: #fff !important; |
|||
} |
|||
|
|||
::v-deep .el-pagination__jump { |
|||
color: #fff !important; |
|||
} |
|||
|
|||
.sn_show { |
|||
position: relative !important; |
|||
z-index: 999 !important; |
|||
overflow: visible !important; |
|||
} |
|||
|
|||
.sn_show .sn .sn-body { |
|||
color: #6FA8FF; |
|||
background-color: rgba(13, 36, 100, 0.2); |
|||
position: relative; |
|||
z-index: 999; |
|||
} |
|||
|
|||
.title { |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
.search { |
|||
display: flex; |
|||
justify-content: left; |
|||
margin-left: .5rem; |
|||
} |
|||
|
|||
::v-deep .el-input__inner { |
|||
background: none; |
|||
border-color: #5A7FFF; |
|||
color: #fff !important; |
|||
} |
|||
|
|||
::v-deep .el-form--inline .el-form-item__label { |
|||
color: #fff; |
|||
} |
|||
|
|||
::v-deep .el-collapse-item__wrap { |
|||
border-bottom: none; |
|||
} |
|||
|
|||
::v-deep .el-collapse-item__content { |
|||
background-color: #071643; |
|||
} |
|||
|
|||
::v-deep .el-form--inline .el-form-item__content { |
|||
width: 1.4rem; |
|||
} |
|||
|
|||
::v-deep .el-form-item { |
|||
margin-bottom: 0; |
|||
margin-right: 0 !important; |
|||
width: 2rem; |
|||
} |
|||
|
|||
::v-deep .el-form--inline .el-form-item__label { |
|||
font-size: 0.18rem !important; |
|||
text-align: center !important; |
|||
padding-right: 0; |
|||
} |
|||
|
|||
::v-deep .el-collapse { |
|||
border: none; |
|||
} |
|||
|
|||
::v-deep .el-collapse-item__header { |
|||
box-sizing: border-box; |
|||
padding-left: 0.5rem; |
|||
height: 0.7rem; |
|||
line-height: 0.7rem; |
|||
font-size: 0.25rem; |
|||
color: #fff; |
|||
background: url(../../assets/img/brand/parkIngo.png) no-repeat; |
|||
background-size: 9.8rem 0.7rem; |
|||
border: none; |
|||
} |
|||
|
|||
::v-deep .el-input--small .el-input__inner { |
|||
height: 0.4rem; |
|||
line-height: 0.4rem; |
|||
} |
|||
|
|||
.line { |
|||
display: flex; |
|||
align-items: center; |
|||
height: .41rem; |
|||
line-height: .41rem; |
|||
} |
|||
|
|||
.td { |
|||
color: #fff; |
|||
text-align: center; |
|||
border: none; |
|||
font-size: 0.14rem; |
|||
|
|||
img { |
|||
width: 0.4rem; |
|||
display: block; |
|||
margin: 0 auto; |
|||
height: 0.4rem; |
|||
// margin-top: .1rem; |
|||
} |
|||
} |
|||
|
|||
.topBg { |
|||
height: 0.7rem; |
|||
background: url(/img/img1.png) no-repeat; |
|||
background-size: contain; |
|||
display: flex; |
|||
align-items: center; |
|||
padding-left: 0.5rem; |
|||
color: #aeceff; |
|||
font-size: 0.21rem; |
|||
} |
|||
|
|||
.left-top { |
|||
height: 3.5rem; |
|||
position: relative; |
|||
background: url(/img/img2.png) no-repeat; |
|||
background-size: cover; |
|||
margin-bottom: 0.5rem; |
|||
} |
|||
|
|||
.tbody .tr:nth-child(odd) { |
|||
background: #06184b; |
|||
} |
|||
|
|||
//奇数行 |
|||
|
|||
.table { |
|||
width: 100%; |
|||
border-spacing: 0; |
|||
border-color: transparent; |
|||
|
|||
.thead { |
|||
background: #061131; |
|||
width: 100%; |
|||
height: 0.575rem; |
|||
line-height: 0.575rem; |
|||
font-size: 0.2rem; |
|||
|
|||
.td { |
|||
color: #6fa8ff; |
|||
text-align: center; |
|||
border: none; |
|||
font-size: 0.2rem; |
|||
} |
|||
} |
|||
|
|||
.tbody { |
|||
width: 100%; |
|||
|
|||
.td { |
|||
color: #fff; |
|||
text-align: center; |
|||
border: none; |
|||
font-size: 0.14rem; |
|||
|
|||
img { |
|||
width: 0.4rem; |
|||
display: block; |
|||
margin: 0 auto; |
|||
height: 0.4rem; |
|||
} |
|||
} |
|||
|
|||
.tr { |
|||
width: 100%; |
|||
height: 0.5rem; |
|||
line-height: 0.5rem; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.sn { |
|||
// position: absolute; |
|||
overflow: hidden; |
|||
display: block; |
|||
width: 6.3rem; |
|||
// height: 3.5rem; |
|||
margin-bottom: 0.5rem; |
|||
|
|||
.sn-title { |
|||
box-sizing: border-box; |
|||
padding-left: 0.5rem; |
|||
height: 0.7rem; |
|||
line-height: 0.7rem; |
|||
font-size: 0.25rem; |
|||
color: #fff; |
|||
background: url(../../assets/img/brand/parkIngo.png) no-repeat; |
|||
background-size: 9.8rem 0.7rem; |
|||
} |
|||
|
|||
.sn-body { |
|||
color: #6FA8FF; |
|||
background-color: rgba($color: #0d2464, $alpha: 0.2); |
|||
|
|||
.table-header { |
|||
height: 0.6rem; |
|||
line-height: 0.6rem; |
|||
|
|||
span { |
|||
font-size: 0.2rem; |
|||
text-align: center; |
|||
display: inline-block; |
|||
} |
|||
} |
|||
|
|||
.seamless-warp { |
|||
color: #fff; |
|||
height: 2.25rem; |
|||
overflow: hidden; |
|||
visibility: visible; |
|||
|
|||
.line { |
|||
&:nth-child(2n) { |
|||
|
|||
background: rgba(14, 75, 255, 0.1); |
|||
} |
|||
|
|||
span { |
|||
height: 0.45rem; |
|||
line-height: 0.45rem; |
|||
font-size: 0.175rem; |
|||
text-align: center; |
|||
display: inline-block; |
|||
} |
|||
} |
|||
|
|||
.in { |
|||
color: #1BDB7F; |
|||
} |
|||
|
|||
} |
|||
|
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,58 @@ |
|||
Math.easeInOutQuad = function(t, b, c, d) { |
|||
t /= d / 2 |
|||
if (t < 1) { |
|||
return c / 2 * t * t + b |
|||
} |
|||
t-- |
|||
return -c / 2 * (t * (t - 2) - 1) + b |
|||
} |
|||
|
|||
// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
|
|||
var requestAnimFrame = (function() { |
|||
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) } |
|||
})() |
|||
|
|||
/** |
|||
* Because it's so fucking difficult to detect the scrolling element, just move them all |
|||
* @param {number} amount |
|||
*/ |
|||
function move(amount) { |
|||
document.documentElement.scrollTop = amount |
|||
document.body.parentNode.scrollTop = amount |
|||
document.body.scrollTop = amount |
|||
} |
|||
|
|||
function position() { |
|||
return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop |
|||
} |
|||
|
|||
/** |
|||
* @param {number} to |
|||
* @param {number} duration |
|||
* @param {Function} callback |
|||
*/ |
|||
export function scrollTo(to, duration, callback) { |
|||
const start = position() |
|||
const change = to - start |
|||
const increment = 20 |
|||
let currentTime = 0 |
|||
duration = (typeof (duration) === 'undefined') ? 500 : duration |
|||
var animateScroll = function() { |
|||
// increment the time
|
|||
currentTime += increment |
|||
// find the value with the quadratic in-out easing function
|
|||
var val = Math.easeInOutQuad(currentTime, start, change, duration) |
|||
// move the document.body
|
|||
move(val) |
|||
// do the animation unless its over
|
|||
if (currentTime < duration) { |
|||
requestAnimFrame(animateScroll) |
|||
} else { |
|||
if (callback && typeof (callback) === 'function') { |
|||
// the animation is done so lets callback
|
|||
callback() |
|||
} |
|||
} |
|||
} |
|||
animateScroll() |
|||
} |
Loading…
Reference in new issue