美文网首页让前端飞Web前端之路网页前端后台技巧(CSS+HTML)
web前端入门到实战:html5网页特效-弧形菜单

web前端入门到实战:html5网页特效-弧形菜单

作者: 大前端世界 | 来源:发表于2019-12-03 16:34 被阅读0次

    效果:

    • 弧形菜单,文字按规则变形以及变换透明度
    • 简单的javascript,上手难度:简单

    学习笔记:

    text-decoration:

    最主要的功能就是给文字加上附着在文字底部,上方,或者中间的线(删除线)。

    默认。定义标准的文本。
    underline
    定义文本下的一条线。
    overline
    定义文本上的一条线。
    line-through
    定义穿过文本下的一条线。
    inherit
    规定应该从父元素继承 text-decoration 属性的值。

    隐藏超出边界的子元素:

    该例子中有13个菜单项,但只显示出12个,因为第1个和第13个超出了父元素的边界,被隐藏了。

    overflow: hidden;
    

    渐入隐藏效果:

    第2,3,11,12个虽然没有被隐藏,但看起来很朦胧。这样的效果首先是设置透明度,嗯,nth-child的用法

    .item:nth-child(2), .item:nth-child(3), .item:nth-child(11), .item:nth-child(12) {
      opacity: 0.2;
    }
    

    然后是邻近顶部和底部的线性渐变,这样看来菜单项似乎和背景融为一体了

    web前端开发学习Q-q-u-n: 731771211,分享学习的方法和需要注意的小细节,不停更新最新的教程和学习方法(详细的前端项目实战教学视频,PDF)
    .top {
      top: 0;
      background: linear-gradient(to bottom, steelblue 0%, rgba(70, 130, 180, 0) 100%);
    }
    
    .bottom {
      bottom: 0;
      background: linear-gradient(to bottom, rgba(70, 130, 180, 0) 0%, steelblue 100%);
    }
    

    按钮触摸渐变:

    下面这行代码的效果时,当鼠标放上按钮时,按钮花3秒从白色渐变成黑色,离开时立马从黑色变为白色。

    .btn {
      color: white;
    }
    .btn:hover {
      color: black;
      transition: color 3s;
    }
    

    如果我们想鼠标离开时也是黑色逐渐变为白色怎么办?同样加个transition:

    .btn {
      color: white;
     transition: color 3s;
    }
    .btn:hover {
      color: black;
      transition: color 3s;
    }
    

    吐槽一下,这儿的上下按钮是两个特殊符号,见html。win10输入法自带许多特殊符号,够弄出很多好玩的东西了

    <div class="btn prev" onClick="animation({}, 1);">˄</div>
    <div class="btn next" onClick="animation({}, 0);">˅</div>
    

    由于符号本身很小,于是用scale放大,为了防止用户复制内容时不小心选中它,以及为了防止被用户看出来是个符号,加上一个user-select:none,这样用户就选不中了。

    .btn {
          transform: scale(3, 1);
          user-select: none;
    }
    

    javascript详细解释:

    第一步:

    初始话一波,把除按钮之外的东西都定义好,就形成了一开始看到的界面

    
        const srart_pos = 90.75;
    const item_count = 13;
    const s = 0.52 * Math.PI / 180; //计算位移角度
    
    var pos = [];
    var elem = document.getElementsByClassName('item');
    
    function allocationItems() {
        //首先设置第7个元素处于中间最大的位置
        var i;
        var pp = elem[6].getElementsByTagName('a')[0].getAttribute('data-img');
        document.getElementById("pic").style.backgroundImage = "url('" + pp + "')";
        document.getElementById("pic").className = "img-box";
    
        //计算其它菜单项的位置
        pos[0] = srart_pos;
        for (i = 1; i < item_count; i++) {
            pos[i] = pos[i - 1] - 0.2;
            last_pos = pos[i];
        }
        for (i = 0; i < item_count + 1; i++) {
            elem[i].style.left = 240 + 250 * Math.sin(pos[i]) + 'px';
            elem[i].style.top = 240 + 250 * Math.cos(pos[i]) + 'px';
        }
    }
    allocationItems();
    
    

    注意下面这句,getAtrribute的名字要和html设定的属性值一样,看到data-img了吗?不过这个名字随便取就行了,叫”photo”之类的也可以,只要保证js和html一样就行

    var pp = elem[6].getElementsByTagName('a')[0].getAttribute('data-img');
    
    <a href="" data-img="img/6.jpg" target="_blank" rel="noopener">
                Can I use... Support tables for HTML5, CSS3, etc
    </a>
    web前端开发学习Q-q-u-n: 731771211,分享学习的方法和需要注意的小细节,不停更新最新的教程和学习方法(详细的前端项目实战教学视频,PDF)
    

    第二步:

    当按下按钮时,执行animation(),传个参数,1为向上,0为向上。现在看看animtaion函数里面有什么。首先是定义一些东西

    var $ = {
            radius: 250, //圆周半径
            speed: 10 // 速度单位
     }
     var e = elem;
    document.getElementById("pic").className = "hide";
    console.log(3);
    

    然后执行函数animate()。不过这个执行函数把别的函数当成参数传进去了,注意看。先不管当成参数传的函数是什么,暂时用不上。

    animate(function () {
            console.log(1);
            var i;
            for (i = 0; i < item_count; i++) {
    
                e[i].style.left = 240 + $.radius * Math.sin(pos[i]) + 'px';
                e[i].style.top = 240 + $.radius * Math.cos(pos[i]) + 'px';
                if (flag) {
                    pos[i] += s;
                } else {
                    pos[i] -= s;
                }
            }   /* callback function */
        }, 400, function changeItems() {
            console.log(2);
            var list = document.getElementById('list');
            var ch = flag ? list.firstElementChild : list.lastElementChild
            ch.remove();
            if (flag) {
                list.appendChild(ch);
            } else {
                list.insertBefore(ch, list.firstChild);
            }
            allocationItems();
        });
    

    然后看看animate()函数的定义:

    function animate(draw, duration, callback) {
            console.log(4);
            var start = performance.now();
    
             requestAnimationFrame(function run(time) {
                console.log(5);
                // 自启动来(按下按钮)的时差
                var timePassed = time - start;
                console.log(time, start)
                // 不能超过最大持续时间
                if (timePassed > duration)
                    timePassed = duration;
                //重新绘制菜单项的位置
                draw();
                console.log(6);
                if (timePassed < duration) {
                    console.log(7);
                    requestAnimationFrame(run);
                } else 
                {
                    console.log(8);
                    callback();
                    console.log(9);
                }
            });
        }
    

    先用performance.now()确定按下按钮的时间,储存在start中。然后用requestAnimationFrame执行run函数。至于run函数是什么,已经在requestAnimationFrame函数中定义好了。

    注意requestAnimationFrame调用时会给其中的函数传入DOMHighResTimeStamp参数,该参数与performance.now()的返回值相同,它表示requestAnimationFrame() 开始去执行其中函数的时刻。这就是为什么run函数的定义中会有个time参数了,其实就是目前的时刻。

    每次执行run函数,都要执行一遍draw函数。draw我单独放了出来,便于理解。仔细一看,这不就是更新菜单项的位置吗?菜单项位置并不是一下就从原位置到了指定位置,而是慢慢地移过去的,所以看起来很流畅。注意这儿的$和jquery没有关系,看看前面的定义即可。

    web前端开发学习Q-q-u-n: 731771211,分享学习的方法和需要注意的小细节,不停更新最新的教程和学习方法(详细的前端项目实战教学视频,PDF)
    function draw() {
            console.log(1);
            var i;
            for (i = 0; i < item_count; i++) {
                 e[i].style.left = 240 + $.radius * Math.sin(pos[i]) + 'px';
                e[i].style.top = 240 + $.radius * Math.cos(pos[i]) + 'px';
                if (flag) {
                    pos[i] += s;
                } else {
                    pos[i] -= s;
                }
        }
    }
    

    返回run函数,如果现在播放时间还没到规定的时间的话,再执行一遍run函数。如此反复下去。如果到了规定时间的话,就执行callback()。

    但到底执行的函数是什么样子?单独放出来一看,注意按向上的按钮时,flag = 1,否则flag = 0。假如按了向上的按钮,所有菜单项逆时针向上转,这时第一个菜单项需要接着第十三个菜单项后面,否则后面就空了。于是就把第一个菜单项取下来remove(),掉,于是原来的第二到第十三菜单项序号都变小一个,第八个变成了第七个,变成了最大的那个。然后再把取下的第一个当成第十三个接在最后面,又成了新的菜单排列。

    按向下的按钮也是一样。

    function changeItems() {
            console.log(2);
            var list = document.getElementById('list');
            var ch = flag ? list.firstElementChild : list.lastElementChild
            ch.remove();
            if (flag) {
                list.appendChild(ch);
            } else {
                list.insertBefore(ch, list.firstChild);
            }
            allocationItems();
        }
    

    相关文章

      网友评论

        本文标题:web前端入门到实战:html5网页特效-弧形菜单

        本文链接:https://www.haomeiwen.com/subject/nqjawctx.html