共计 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;}
再下来制作鼠标滑动时遮罩追随的成果。
先把遮罩移到图片的左上方。遮罩的高是 50em
,top: -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 小时的视频演示解说。京东 / 天猫 / 当当有售。