手把手教你实现一个聚光灯

1,291 阅读3分钟

前言

马上到年底了,有的公司会举办隆重的年会,在年会上有一种非常常见的工具 —— 聚光灯。

聚光灯特效是一种常见的舞台灯光效果,通过灯光的聚焦和扩散来营造出特定的光线效果。聚光灯特效可以用于各种演出场合,为演出增添氛围和视觉效果。而我们这次就是来通过 CSS+JS 来简单实现一个聚光灯特效。

效果预览

最终实现的效果如码上掘金所示。

HTML + CSS

看完了整体效果,我们接下来实现一下它。首先我们看到 HTML+CSS 部分,来实现聚光灯的基本框架,相关代码如下。

 <section>
        <h2>聚光灯</h2>
 </section>
 <div class="light"></div>

这里首先通过标题标签定义好聚光灯的部分。接下来的<div>标签具有一个类名为light,用于表示聚光灯的灯光部分。这个<div>标签可以通过 CSS 样式进行进一步的设计和布局。

section{
    position: relative;
    min-height: 100vh;
    background: #000;
    display: flex;
    align-items: center;
    justify-content: center;
}
section h2{
    color: #fff;
    font-size: 15em;
    cursor: default;
}

CSS 部分,这里首先为名为 section 的元素做了样式处理,将元素的定位设置为相对定位,相对于其正常位置进行定位。接着将元素的最小高度设置为视口高度的100%。然后设置元素的背景颜色以及显示方式(让元素居中对齐)。

最后,再为 section 内部的 h2 元素做样式处理,将 h2 元素的文本颜色设置为白色,字体大小设置为15em,将鼠标指针设置为默认样式。到这里就完成了对 section 部分的样式处理了。

.light{
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: radial-gradient(circle at var(--x) var(--y),transparent 10%,rgba(0,0,0,0.95) 20%);
}

最后为名为light的元素,也就是灯光元素添加相关样式。将元素的定位设置为固定定位,相对于浏览器窗口进行定位,并且覆盖整个浏览器窗口。这里加入了一个背景属性 —— "background: radial-gradient(circle at var(--x) var(--y),transparent 10%,rgba(0,0,0,0.95) 20%)"表示的意思是将元素的背景设置为径向渐变,渐变起点为变量 (--x, --y) 所代表的位置,透明度从10%95% 变化。

到这里,整个CSS的实现就完成了。

JS部分

接下来就到了控制逻辑实现的关键部分了,相关代码如下。

 <script>
        const pos = document.documentElement
        pos.addEventListener('mousemove',e=>{
            pos.style.setProperty('--x',e.clientX+'px')
            pos.style.setProperty('--y',e.clientY+'px')
        })
    </script>

这里用于监听鼠标移动事件,并根据鼠标位置动态改变页面元素的样式。

首先,代码通过 document.documentElement 获取到文档的根元素,即 <html> 元素。

然后,使用 addEventListener 方法绑定了一个 mousemove 事件监听器,当鼠标移动时,会触发该事件。

在事件处理函数中,代码通过 e.clientX 获取鼠标在页面中的水平位置,通过 e.clientY 获取鼠标在页面中的垂直位置。接下来,代码使用 setProperty 方法,通过设置 CSS 变量 --x--y 的值,将鼠标的水平位置和垂直位置分别作为变量的值。

最终,页面中使用这些 CSS 变量来控制元素的样式,实现了鼠标移动时元素样式的动态变化,也就是达到了我们最终实现的聚光灯效果了。

总结

以上就是该聚光灯效果的实现过程了,总的来说就是通过鼠标悬停来实现一个聚光灯效果。代码简单易懂,呈现的效果也具有特色,非常适合用来学习前端三件套的基础知识。完整代码在码上掘金里可以查看,欢迎大家在评论区里讨论~