之前在网上看到一个特别骚气的页面阅读定位菜单,今天给大家分享一下原理,先看效果图:
这是我之前浏览联想官网上看到的一个效果图,觉得相当骚气。然后我把他的背景图扣下来,也做了一个,看看效果。
以下上代码:
- <ul class="fixd-menu" v-show="scrollMenu" :style="'transform:rotate('+MenuRotate+'deg)'">
- <li
- v-for="(item,index) in menu"
- :key="item.code"
- @click="fixedMenu(index)"
- :class="['fixd-menu-item','fixd'+item.code,fixeMenuNow===item.href?'fixd-now':'']"><a :href="'#'+item.href">{{item.title}}a>li>
- ul>
- @keyframes menurun(){
- from{
- left: 0;
- }
- to{
- left: 1rem;
- }
- }
- .fixd-menu{
- position: fixed;
- top: calc(50% - 2.91rem);
- left: 1rem;
- width: 3.28rem;
- height: 3.28rem;
- background-image: url(../images/runner.png);
- background-size: 100%;
- background-position: center;
- z-index: 999;
- transition: all 1s;
- }
-
- .fixd-menu .fixd-menu-item{
- font-size: .1rem;
- color: #fff;
- width: .95rem;
- height: .6rem;
- line-height: .6rem;
- text-align: center;
- background-position: center;
- background-size: 100%;
- background-repeat: no-repeat;
- position: absolute;
- }
- .fixd-menu .fixd-menu-item a{color: #fff;display: block;width: 100%;height: 100%;}
-
- .fixd-menu .fixd0{
- left: 1.15rem;
- top: .05rem;
- }
- .fixd-menu .fixd1{
- left: 1.928rem;
- top: .287rem;
- transform: rotate(37deg);
- }
- .fixd-menu .fixd2{
- left: 2.39rem;
- top: .95rem;
- transform: rotate(72deg);
- }
- .fixd-menu .fixd3{
- left: 2.39rem;
- top: 1.75rem;
- transform: rotate(109deg);
- }
- .fixd-menu .fixd4{
- left: 1.90rem;
- top: 2.38rem;
- transform: rotate(144deg);
- }
- .fixd-menu .fixd5{
- left: 1.16rem;
- top: 2.65rem;
- transform: rotate(180deg);
- }
- .fixd-menu .fixd6{
- left: .4rem;
- top: 2.38rem;
- transform: rotate(-144deg);
- }
- .fixd-menu .fixd7{
- left: -0.05rem;
- top: 1.73rem;
- transform: rotate(-109deg);
- }
- .fixd-menu .fixd8{
- left: -0.05rem;
- top: .94rem;
- transform: rotate(-72deg);
- }
- .fixd-menu .fixd9{
- left: .4rem;
- top: .299rem;
- transform: rotate(-37deg);
- }
- .fixd-now{background-image: url(../images/on_bg01.png);}
- data:{
- menu:[
- {title:'首页',href:'app',code:0},
- {title:'服务流程',href:'service',code:1},
- {title:'关于我们',href:'AboutUs',code:2},
- {title:'我们的优势',href:'Advantages',code:3},
- {title:'工程案例',href:'Project',code:4},
- {title:'领导团队',href:'introduction',code:5},
- {title:'联系我们',href:'Contact',code:6}
- ],
- DocumentTop:0,//页面上滚动
- scrollMenu:false,//滚动后显示的菜单
- fixeMenuNow:'',//当前悬浮菜单的选中
- MenuRotate:0//悬浮菜单旋转角度
- },
- methods:{
- scrolling(){//页面滚动监听
- this.DocumentTop =
- document.documentElement.scrollTop ||
- document.body.scrollTop ||
- window.pageYOffset;
- },
- fixedMenu(index){//转盘点击时轮盘旋转
- this.fixeMenuNow = window.location.hash.split('#')[1];
- this.MenuRotate = 0 - (index * 35);
- },
- autoScroll(){//页面滑动时转动轮盘
- var plate = document.getElementsByClassName('plate');
- /* 思路:(循环板块列表)当页面滚动等于阅读元素的offsetTop时,表示阅读到此位置了,轮盘的转动此时可通过阅读元素的id去菜单数组“menu”中查找 */
- var that = this;
- var readID = '';//当前阅读到的板块ID
- for(var i=0;i
length;i++){ - if(that.DocumentTop >= (plate[i].offsetTop-100) && that.DocumentTop < (plate[i].offsetTop + 100)){
- readID = plate[i].id;
- that.menu.map(function(item,index,arr){
- if(readID === item.href){
- that.MenuRotate = 0 -(item.code * 35)
- that.fixeMenuNow = item.href
- window.location.hash = "#"+item.href
- }
- })
- }
- }
- }
- },
- mounted(){//页面挂在完成后给window监听滚动事件,并调用/执行我们定义的事件函数。
- window.addEventListener("scroll",this.scrolling);
- },
- watch: {//这里监听当记录页面滚动的变量发生改变时,调用相对应的函数
- DocumentTop(newValue, oldValue) {
- if(newValue >= 130){
- this.scrollMenu = true
- this.fixeMenuNow = window.location.hash.split('#')[1];
- this.autoScroll()
- }
- if(newValue <= 50){
- this.scrollMenu = false
- window.location.hash = "#app";
- }
- }
- },
- ,
- beforeDestroy(){//页面销毁时移除窗口滚动监听
- window.removeEventListener("scroll",this.scrolling)
- }
以上就是所有实现代码:
1、你可以根据自己的需求设置菜单内容,当然这个menu内容的href值一定要和页面的节点id相对应,因为我们时通过设置锚点来定位页面内容的。
2、css样式设置了多个fixd1、fixd2、fixd3、……,这是因为我们的轮盘格子只有这么多,并不会因为菜单变多而增加背景图片的格子。哈哈!如果你需要更多的菜单,可以让你的ui给你设计出多个背景图,然后根据菜单列表个数来决定你要哪张背景图,这样就可以实现动态背景图了。
3、代码和逻辑执行流程:进入页面,先给window绑定监听滚动事件,把回调函数替换成我们自己定义的函数。此时我们记录页面滚动距离的变量(this.DocumentTop)就有了初始值了。当this.DocumentTop发生了改变,我们vue的监听函数(watch)就会起到作用。
4、监听函数(watch)内的newValue要判断大于130的原因是。默认菜单和顶部的高度,我希望的是当滚动到默认菜单消失时轮盘才显示,如下图:(这里可以根据自己的需求来写)