子比头部添加景深特效

ugOk.gif
子比头部添加景深特效插图

子比头部添加景深特效

因为朋友想建二次元网站,所以我帮他装饰网站,正好找到了一份景深的源码,就简单搞搞装上了。效果如上图所示。源码引用了星语的小木屋的《B站首页顶部景深特效[源码]》。实际效果可以看这个:http://114.132.162.28/

景深源码

我用夸克网盘分享了「B站景深源码.zip」,点击链接即可保存。打开「夸克APP」,无需下载在线播放视频,畅享原画5倍速,支持电视投屏。
链接:https://pan.quark.cn/s/1c967db0565f

代码

首先打开header.php,在<body>后面找个喜欢的位置放置如下代码:

<!-- TOOL-PATH: header.php --方便找代码位置 -->
        <!-- 顶部景深必要css -->
        <style>
            :root {
                --background-color: #2c3e50;
                --border-color: #7591AD;
                --text-color: #34495e;
                --color1: #EC3E27;
                --color2: #fd79a8;
                --color3: #0984e3;
                --color4: #00b894;
                --color5: #fdcb6e;
                --color6: #e056fd;
                --color7: #F97F51;
                --color8: #BDC581;
            }
            
            html {
                font-size: 14px;
            }
            
            .jingshen {
                width: 100vw;
                background-color: var(--background-color);
                font-family: 'Montserrat', sans-serif, Arial, 'Microsoft Yahei';
                position: absolute;
                top:0;
            }
            
            .jingshen .channel {
                position: absolute;
                width: 80%;
                text-align: center;
                bottom: 0%;
                left: 50%;
                transform: translate(-50%, -50%);
                font-size: 20px;
                font-weight: bold;
                color: #fff;
            }
            
            .jingshen .banner{
                position: relative;
                width: 100vw;
                height: 155px;
                overflow: hidden;
                background-color: #00b894;
            }
            
            .jingshen .image{
                position: absolute;
                width: 100%;
                height: 100%;
                display: flex;
                justify-content: center;
                align-items: center;
            }
           /*下面的代码保证了景深只在1200px宽度以上的设备上显示*/
            @media (max-width:1200px){
                .jingshen{
                    display: none;
                }
                .jingshen2{
                    display: none;
                }
            }

        </style>
        <div class="jingshen">
            <div class="banner">
                <div class="image"><img width="3000" height="250" src="/images/bg.png" loading='lazy'/> </div>
                <div class="image"><img width="1800" height="165" src="/images/girl1.png" loading='lazy'/> </div>
                <div class="image"><img width="3000" height="250" src="/images/grassland.png" loading='lazy'/> </div>
                <div class="image"><img width="1800" height="160" src="/images/mushroom.png" loading='lazy'/> </div>
                <div class="image"><img width="1800" height="165" src="/images/spirit.png" loading='lazy'/> </div>
                <div class="image"><img width="1950" height="178" src="/images/leaf.png" loading='lazy'/> </div>
            </div>
            <script>
                let x = 0;
                let x_new = 0;
                let x_offset = 0;
        
                let banner = document.querySelector('.banner');
                let images = document.querySelectorAll('.image');
        
                let window_width = document.documentElement.clientWidth;
                let step = window_width / 2 / 5;
        
                let data_images = [
                    { x: 0, b: 4 },
                    { x: 0, b: 0 },
                    { x: 0, b: 1 },
                    { x: 0, b: 4 },
                    { x: 0, b: 5 },
                    { x: 0, b: 6 },
                ]
        
                let init = () => {
                    // images[0].children[0].style = 'transform: translate(0px); filter: blur(4px);';
                    // images[1].children[0].style = 'transform: translate(0px); filter: blur(0px);';
                    // images[2].children[0].style = 'transform: translate(0px); filter: blur(1px);';
                    // images[3].children[0].style = 'transform: translate(0px); filter: blur(4px);';
                    // images[4].children[0].style = 'transform: translate(0px); filter: blur(5px);';
                    // images[5].children[0].style = 'transform: translate(0px); filter: blur(6px);';
                    for (const key in images) {
                        if (images.hasOwnProperty(key)) {
                            const element = images[key];
                            const element_data = data_images[key];
                            element.children[0].style = 'transition: .2s linear; transform: translate(' + element_data.x + 'px); filter: blur(' + element_data.b + 'px);';
                        }
                    }
                }
        
                banner.addEventListener('mouseover', (e) => {
                    x = e.clientX;
                    // console.log(x);
                });
                banner.addEventListener("mousemove", (e) => {
                    x_new = e.clientX;
                    // console.log(x_new);
                    x_offset = x - x_new;
                    // console.log(x_offset);
                    for (const key in images) {
                        if (images.hasOwnProperty(key)) {
                            let level = (6 - parseInt(key)) * 10;
                            const element = images[key];
                            const element_data = data_images[key];
                            let b_new = Math.abs(element_data.b + (x_offset / step));
                            let l_new = 0 - (x_offset / level);
                            element.children[0].style = 'transform: translate(' + l_new + 'px); filter: blur(' + b_new + 'px);';
                        }
                    }
        
                });
        
        
                banner.addEventListener("mouseout", (e) => {
                    init();
                });
        
                blink_index = 0;
                timeout = 4000;
                let blink = () => {
        
                    if (blink_index == 4) {
                        blink_index = 1;
                        timeout = 4000;
                    } else {
                        blink_index += 1;
                        timeout = 30;
                    }
        
                    images[1].children[0].src = 'images/girl' + blink_index + '.png';
                    setTimeout(() => {
                        blink();
                    }, timeout);
                }
        
                window.onload = () => {
                    init();
                    blink();
                }
        
            </script>
        </div>

插入上面的代码之后,网站头部会出现景深的部分,但是会被顶部<header></header>内部的导航栏挡的严严实实。所以还需要加一些JS改进改进:

接着在header.php 中加入如下JS代码

<script>
            window.onload = function(){
                                var winWidth = 0;
                if (window.innerWidth)
                   winWidth = window.innerWidth;
                else if ((document.body) && (document.body.clientWidth))
                   winWidth = document.body.clientWidth;
                //变量t就是滚动条滚动时,到顶部的距离
                var t =document.documentElement.scrollTop||document.body.scrollTop;
                /*
                console.log(t);
                */
                if (winWidth >= 1200){
                    if ( t >= 155 ){
                        $('header').css({
                            'top':0,
                            'position':'fixed'
                        })
                    } else {
                        $('header').css({
                            'top':155-t,
                            'position':'fixed'
                        })
                    }
                } else {
                    $('header').css({
                        'top':0,
                        'position':'fixed'
                    })
                }
            }
            window.onscroll=function(){
                var winWidth = 0;
                if (window.innerWidth)
                   winWidth = window.innerWidth;
                else if ((document.body) && (document.body.clientWidth))
                   winWidth = document.body.clientWidth;
                //变量t就是滚动条滚动时,到顶部的距离
                var t =document.documentElement.scrollTop||document.body.scrollTop;
                /*
                console.log(t);
                */
                if (winWidth >= 1200){
                    if ( t >= 155 ){
                        $('header').css({
                            'top':0,
                            'position':'fixed'
                        })
                    } else {
                        $('header').css({
                            'top':155-t,
                            'position':'fixed'
                        })
                    }
                } else {
                    $('header').css({
                        'top':0,
                        'position':'fixed'
                    })
                }
            }
        </script>

这部分检查距离顶部距离是从网上找的,但我忘了出处了。。。这部分代码会让你的导航栏保持在景深区块的下面(景深区块在<style>中设定了高度为155px,所以只要保证:1.导航栏距离网页顶部的距离不小于155px,2.保证导航栏距离顶部大于155px时固定在视窗的上面,即top:0;,3.让导航栏随动)

但在这之后并没有完成。因为你会发现在<header>之后的元素会被移动后的导航栏挡住,有时候文章主内容还会挡住景深层。所以你还需要加入如下代码:

<!-- THEME-PATH: functions.php -->
        <!-- 顶部景深必要css -->
        <style>
            :root {
                --background-color: #2c3e50;
                --border-color: #7591AD;
                --text-color: #34495e;
                --color1: #EC3E27;
                --color2: #fd79a8;
                --color3: #0984e3;
                --color4: #00b894;
                --color5: #fdcb6e;
                --color6: #e056fd;
                --color7: #F97F51;
                --color8: #BDC581;
            }
            
            html {
                font-size: 14px;
            }
            
            .jingshen2 {
                visibility:hidden;
                width: 100vw;
                background-color: var(--background-color);
                font-family: 'Montserrat', sans-serif, Arial, 'Microsoft Yahei';
            }
            
            .jingshen2 .channel {
                position: absolute;
                width: 80%;
                text-align: center;
                bottom: 0%;
                left: 50%;
                transform: translate(-50%, -50%);
                font-size: 20px;
                font-weight: bold;
                color: #fff;
            }
            
            .jingshen2 .banner{
                position: relative;
                width: 100vw;
                height: 140px;
                overflow: hidden;
                background-color: #00b894;
            }
            
            .jingshen2 .image{
                position: absolute;
                width: 100%;
                height: 100%;
                display: flex;
                justify-content: center;
                align-items: center;
            }
            

        </style>
        <div class="jingshen2">
            <div class="banner">
                <div class="image"><img width="3000" height="200" src="/images/bg.png"> </div>
            </div>
        </div>

因为懒得再改代码了,就直接用之前的代码,只不过增加了一个class:jingshen2,。这个地方用visibility:hidden;将jingshen2中的图片隐藏,让这个图片作为占位符为我们顶出来140px的高度,这个高度可以去 .jingshen2 .banner的height中修改。CSS的visibility最低支持IE 4.0。所以完全不用怕有的游客浏览器太烂了出现多出一个景深区域的问题。

废案

当初原本想把占位图片的HTML做个小工具放到子比的“所有顶部”中。但我发现,那个所有不包括论坛,好像还不包括作者页面。所以废弃了。相关代码如下:

/* B站首页顶部景深特效[源码] */
class jingshen_2481asd extends WP_Widget {

    function __construct() {
        /* 定义结构 */
        $widget_ops = array('classname' => '顶部景深', 
                            'description' => "展示顶部景深占位符" );
        parent::__construct('顶部景深', "2481ASD-顶部景深的占位符", $widget_ops);
    }

    public function widget($args,$instance){
        /* 输出显示在页面上 */
        extract( $args );
        $title = apply_filters( 'widget_title', $instance['title']);
        $num   = isset($instance['num'])?$instance['num']:'8';
        
        ?>
        <style>
            :root {
                --background-color: #2c3e50;
                --border-color: #7591AD;
                --text-color: #34495e;
                --color1: #EC3E27;
                --color2: #fd79a8;
                --color3: #0984e3;
                --color4: #00b894;
                --color5: #fdcb6e;
                --color6: #e056fd;
                --color7: #F97F51;
                --color8: #BDC581;
            }
            
            html {
                font-size: 14px;
            }
            
            .jingshen2 {
                visibility:hidden;
                width: 100vw;
                background-color: var(--background-color);
                font-family: 'Montserrat', sans-serif, Arial, 'Microsoft Yahei';
            }
            
            .jingshen2 .channel {
                position: absolute;
                width: 80%;
                text-align: center;
                bottom: 0%;
                left: 50%;
                transform: translate(-50%, -50%);
                font-size: 20px;
                font-weight: bold;
                color: #fff;
            }
            
            .jingshen2 .banner{
                position: relative;
                width: 100vw;
                height: 140px;
                overflow: hidden;
                background-color: #00b894;
            }
            
            .jingshen2 .image{
                position: absolute;
                width: 100%;
                height: 100%;
                display: flex;
                justify-content: center;
                align-items: center;
            }
            

        </style>
        <div class="jingshen2">
            <div class="banner">
                <div class="image"><img width="3000" height="200" src="/images/bg.png"> </div>
            </div>
        </div>
        <?php
        
        wp_reset_postdata();

        //echo $content;

    }

    public function form($instance){
        /* 给小工具(widget) 添加表单内容 */
        $title = (isset($instance['title'])) ? $instance['title'] : __( 'Products', 'ndb' );
        $num = isset($instance['num'])?$instance['num']:'8';
        ?>
        <p>
            <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title :'); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>"  name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
        </p>
        <p>
            <label for="<?php echo $this->get_field_id('num'); ?>"><?php _e('Number :'); ?></label>
            <input class="widefat" id="<?php echo $this->get_field_id('num'); ?>"  name="<?php echo $this->get_field_name( 'num' ); ?>" type="text" value="<?php echo esc_attr( $num ); ?>" />
        </p>
    <?php

    }

    public function update( $new_instance, $old_instance ) {
        /* 更新保存 */
        $instance = array();
        $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
        $instance['num'] = ( ! empty( $new_instance['num'] ) ) ? strip_tags( $new_instance['num'] ) : '';
        return $instance;
    }    
}



function asd2481_register_widget() {
    register_widget( 'jingshen_2481asd' );
    /*
    Failed:
    register_widget( 'wobbay_swiper' );
    */
}
add_action( 'widgets_init', 'asd2481_register_widget' );

为什么小工具加入后会多出俩输入框,但并没有什么用呢。因为这个代码是我从我还在开发的主题里取下来的,我懒得修改了。

结束语

这就是所有的步骤了,我觉得不难,挺好用呢,就是记得如果你更新主题,记得备份。移植到其他主题上的时候,记得改改控制导航栏JS代码中的jQuery。

顺带我打个广告QwQ,我搞了个动漫资讯站,可以来看看:www.hnav.moe。

依据 CC BY-SA 3.0 CN 国际许可协议 进行授权,转载请附上出处链接及本声明。

感谢您的来访,获取更多精彩文章请收藏本站。

© 版权声明
THE END
喜欢就支持一下吧
点赞26 分享
评论 共2条
头像
欢迎提交您的评论,共创文明良好交流环境,请勿提交违规言论!
提交
头像

昵称

取消
昵称表情代码图片
    • 头像Mark0