关于javascript:前端每日实战第177号作品多张图片的鼠标悬停和滑动特效

37次阅读

共计 3682 个字符,预计需要花费 10 分钟才能阅读完成。

一种引起浏览者摸索趣味的办法是,页面关上之后并不马上把所有内容都出现给用户,而是暗藏其中的一部分内容,其余内容则须要用户交互之后才展现进去。这种形式很适合那些小众的、要营造艺术气氛的网站,通过特效来展示后续内容,有一种与用户对话的感觉。本作品就是采纳这样的形式,当页面加载之后先把图片遮住,而后当鼠标挪动到元素之上时,图片才展示进去。

成果预览

按下右侧的“点击预览”按钮能够在以后页面预览,点击链接能够全屏预览。

https://codepen.io/comehope/pen/MWejLqY

源代码下载

每日前端实战系列的全副源代码请从 github 下载:

https://github.com/comehope/front-end-daily-challenges

代码解读

一、DOM 构造

容器名为 .container,其中蕴含一个名为 .item 的元素。
.item 元素则蕴含 3 个子元素,.picture 示意图片自身,.title 是图片上的文字,.mask 是用来制作遮罩成果的元素。
作品实现时,会有多个 .item 元素,但此时咱们先只展现 1 张图片,待成果实现之后,再减少其余图片。

<div class="container">
    <div class="item">
        <img class="picture" src="images/toggle.png">
        <span class="title">Toggle</span>
        <div class="mask"></div>
    </div>
</div>

本作品用到的 4 张图片可从下列地址下载。
https://assets.codepen.io/947…
https://assets.codepen.io/947…
https://assets.codepen.io/947…
https://assets.codepen.io/947…

二、根底布局

设置页面背景色为深灰色,令容器居中。

body {
    background-color: #222;
    margin: 0;
    height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
}

设置图片尺寸,用绝对单位 em

.item {
    width: 18em;
    height: 12em;
}

.item .picture {width: 100%;}

成果如下图:

三、图片遮罩特效

因为先解决遮罩成果,所以把临时用不到的文字暗藏起来,防止烦扰。

.item .title {display: none;}

利用 .mask 元素为图片减少遮罩。遮罩大小是 20em * 20em 的一个大圆,背景色先暂用半透明的醒目的黄色,便于在开发过程中察看。

.item {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
}

.item .mask {
    position: absolute;
    width: 20em;
    height: 20em;
    background-color: hsla(60, 100%, 50%, 0.7);
    border-radius: 50%;
}

成果如下图:

下面只是测试了遮罩的大小,把方才的代码正文掉,改用 box-shadow 实现咱们真正须要的遮罩成果。这个遮罩层尺寸是 50em * 50em,远远大于图片自身,但它的大部分区域是内暗影,在内暗影之内才透出遮罩下方的图片来。
内暗影的尺寸是 15em,这是内暗影的半径,所以内暗影的直径是 30em,用遮罩元素的宽高 50em 减去遮罩的 30em,剩下的就是 20em,和方才测试的遮罩大小是一样的。

.item .mask {
    /*width: 20em;*/
    /*height: 20em;*/
    /*background-color: hsla(60, 100%, 50%, 0.7);*/
    width: 50em;
    height: 50em;
    color: hsla(60, 100%, 50%, 0.7);
    box-shadow: inset 0 0 0 15em;
}

成果如下图:

加上鼠标悬停成果试一下。留神,这里元素上的内暗影尺寸设置为 25em,这是内暗影的半径尺寸,那么暗影的直径就是 50em,和遮罩自身的尺寸是一样大的,这示意在默认状况下,整张图片都被内暗影遮住了;而鼠标悬停时,内暗影变小,就显示出了遮罩下方的图片。另外为遮罩层减少了 pointer-events: none 属性,它的作用是防止遮罩层响应鼠标事件。

.item .mask {
    box-shadow: inset 0 0 0 25em;
    transition: box-shadow 0.3s;
    pointer-events: none;
}

.item:hover .mask {box-shadow: inset 0 0 0 15em;}

再下来制作鼠标滑动时遮罩追随的成果。
先把遮罩移到图片的左上方。遮罩的高是 50emtop: -25em 就是令遮罩的程度中线与图片顶边对齐;同理,left: -25em 则是令遮罩的垂直中线与图片的右边对齐,两者叠加,就是遮罩的核心与图片的左上角对齐。

.item .mask {
    top: -25em;
    left: -25em;
}

减少脚本,为 .item 元素绑定 mousemove 事件,令鼠标在 .item 元素上滑动时,带动 .mask 元素滑动。

window.onload = init

function init() {let items = document.querySelectorAll('.item')
    items.forEach((item) => {
        item.addEventListener('mousemove', e => {let mask = item.querySelector('.mask')
            mask.style.transform = 'translate(' + e.offsetX + 'px,' + e.offsetY + 'px)'
        })
    })
}

至此,次要的成果曾经实现了,接下来再加强一下成果。
稍加大图片的原始尺寸,在鼠标悬停时复原图片大小,这样的成果是在鼠标进入图片区域时,图片能“扭曲抖动”一下,增强互动的成果。

.item .picture {transform: scale(1.1);
    transition: 0.3s;
}

.item:hover .picture {transform: scale(1);
}

鼠标悬停和滑动成果实现,上面这几行代码是一些收尾工作。
通过 overflow: hidden 属性暗藏掉图片之外的局部、容器加一点圆角、遮罩的色彩改用不通明的灰色。

.container {border-radius: 0.3em;}

.item {overflow: hidden;}

.item .mask {/*color: hsla(60, 100%, 50%, 0.7);*/
    color: #333;
}

成果如下图:

四、文字布局和特效

接下来解决文字。
先把文字显示进去,除了正文掉 display: none 之外,还要设置它的 z-index,令它显示在遮罩层的上方,再有也要勾销它的鼠标事件,避免它影响鼠标滑动成果。

.item .title {
    /*display: none;*/
    position: absolute;
    color: #777;
    z-index: 1;
    pointer-events: none;
}

设置文字款式。

.item .title {
    font-family: sans-serif;
    font-weight: bold;
    text-transform: uppercase;
}

减少文字特效,当鼠标滑入图片时,暗藏文字。

.item .title {transition: 0.2s;}

.item:hover .title {opacity: 0;}

成果如下图:

至此,单图图片的成果都实现了。

五、将特效利用到多张图片

减少多个 .item 元素。

<div class="container">
    <div class="item">
        <img class="picture" src="images/toggle.png">
        <span class="title">Toggle</span>
        <div class="mask"></div>
    </div>
    <!-- 此处再减少 3 个 .item 元素,代码略 -->
</div>

grid 布局把图片排列成田字格形态。

.container {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    grid-gap: 1em;
}

成果如下图:

功败垂成!

对于作者

张偶,网络笔名 @comehope,20 世纪末触网,被 Web 的无穷魅力所俘获,自此始终战斗在 Web 开发第一线。

《前端每日实战》专栏是我近年来实际我的项目式学习的笔记,以我的项目驱动学习,展示从灵感闪现到代码实现的残缺过程,亦可作为前端开发的练手习题和开发参考。

拙作《CSS3 艺术》一书已由人民邮电出版社出版,全彩印刷,用 100 多个活泼好看的实例,系统地分析了 CSS 与视觉效果相干的重要语法,并含有近 10 小时的视频演示解说。京东 / 天猫 / 当当有售。

正文完
 0