每年的苹果新产品发布,其官网都会配套更新相应的单页滚动产品介绍页。其中的动画特效都非常有意思,今年 iPhone 14 Pro 的介绍页不例外。
最近,刚好有朋友问到,其对官网的一段文字特效特别感兴趣,看适用简单却不知从何下手,我们来看看:
整个动画大致是,随着页面的向下滚动,整个文字从无到出现,再经历一轮渐变色的变化,最后再逐渐消失。
本文,就将介绍 2 种使用 CSS 实现该效果的方式。
第一种方式是借助 background-clip。
background-clip:background-clip 设置元素的背景(背景图片或颜色)是否延伸到边框、内边距盒子、内容盒子下面。
而 background-clip: text 可以实现背景被裁剪成文字的前景色。使用了这个属性的意思是,以区块内的文字作为裁剪区域向外裁剪,文字的背景即为区块的背景,文字之外的区域都将被裁剪掉。
看个最简单的 Demo ,没有使用 background-clip:text :
<div>Clip</div>
<style>
div {
font-size: 180px;
font-weight: bold;
color: deeppink;
background: url($img) no-repeat center center;
background-size: cover;
}
</style>
效果如下:
background-clip:text我们稍微改造下上面的代码,添加 background-clip:text:
div {
font-size: 180px;
font-weight: bold;
color: deeppink;
background: url($img) no-repeat center center;
background-size: cover;
background-clip: text;
}
效果如下:
看到这里,可能有人就纳闷了,,啥玩意呢,这不就是文字设置
color 属性嘛。
color: transparent别急!当然还有更有意思的,上面由于文字设置了颜色,挡住了 div 块的背景,如果将文字设置为透明呢?文字是可以设置为透明的 color: transparent 。
div {
color: transparent;
background-clip: text;
}
效果如下:
CodePen Demo - background-clip: text
通过将文字设置为透明,原本 div 的背景就显现出来了,而文字以外的区域全部被裁剪了,这就是 background-clip: text 的作用。
因此,对于上述效果,我们只需要实现一个从透明到渐变色到透明的渐变背景即可,随着鼠标的滚动移动背景的 background-position 即可!
有了上面的铺垫,我们很容易的实现上述的苹果官网的文字效果。(先不考虑滚动的话)
看看代码:
<div class="g-wrap">
<p>灵动的 iPhone 新玩法,迎面而来。重大的安全新功能,为拯救生命而设计。创新的 4800 万像素主摄,让细节纤毫毕现。更有 iPhone 芯片中的速度之王,为一切提供强大原动力。
</p>
</div>
.g-wrap {
background: #000;
p {
width: 800px;
color: transparent;
background: linear-gradient(-4deg, transparent, transparent 25%, #ffb6ff, #b344ff,transparent 75%, transparent);
background-clip: text;
background-size: 100% 400%;
background-position: center 0;
animation: textScroll 6s infinite linear alternate;
}
}
@keyframes textScroll {
100% {
background-position: center 100%;
}
}
我们这里核心的就是借助了 linear-gradient(-4deg, transparent, transparent 25%, #ffb6ff, #b344ff,transparent 75%, transparent) 这个渐变背景,实现一个从透明到渐变色到透明的渐变背景,配合了 background-clip: text。
再利用动画,控制背景的 background-position,这样一个文字渐现再渐隐的文字动画就实现了:
CodePen Demo -- iPhone 14 Pro Text Animation | background-clip: text
上面一种方式很好,这里再介绍另外一种使用混合模式 mix-blend-mode 实现的方式。
假设,我们先实现这样一幅黑底白字的结构:
<div class="text">灵动的 iPhone 新玩法,迎面而来。重大的安全新功能,为拯救生命而设计。创新的 4800 万像素主摄,让细节纤毫毕现。更有 iPhone 芯片中的速度之王,为一切提供强大原动力。
</div>
.text {
color: #fff;
background: #000;
}
再另外实现这样一个渐变背景,从黑色到渐变色(#ffb6ff 到 #b344ff)到黑色的渐变色:
<div class="g-wrap">
<div class="text">灵动的 iPhone 新玩法,迎面而来。重大的安全新功能,为拯救生命而设计。创新的 4800 万像素主摄,让细节纤毫毕现。更有 iPhone 芯片中的速度之王,为一切提供强大原动力。
<div class="bg"></div>
</div>
</div>
.text {
position: relative;
color: #fff;
background: #000;
}
.bg {
position: absolute;
top: 0;
left: 0;
right: 0;
width: 100%;
height: 400%;
background: linear-gradient(-3deg, #000, #000 25%, #ffb6ff 30%, #ffb6ff, #b344ff, #b344ff 70%, #000 75%, #000);
}
.bg 大概是长这样,相对于 .text 而言,其高度是其 4 倍:
这两个图形叠加在一起会是咋样?应该不会有太多化学反应:
我们给 .bg 加上一个上下移动的动画,我们看看效果:
好像没什么东西?文字也被挡住了。但是!如果在这里,我们运用上混合模式,那效果就完全不一样了,这里,我们会运用到 mix-blend-mode: darken。
.bg {
//...
mix-blend-mode: darken
}
再看看效果:
Wow,借助不同的混合模式,我们可以实现不同的颜色叠加效果。这里 mix-blend-mode: darken 的作用是,只有白色文字部分会显现出上层的 .bg 的颜色,而黑色背景部分与上层背景叠加的颜色仍旧为黑色,与 background-clip: text 有异曲同工之妙。
再简单的借助 overflow: hidden,裁剪掉 .text 元素外的背景移动,整个动画就实现了。
完整的代码如下:
<div class="g-wrap">
<div class="text">灵动的 iPhone 新玩法,迎面而来。重大的安全新功能,为拯救生命而设计。创新的 4800 万像素主摄,让细节纤毫毕现。更有 iPhone 芯片中的速度之王,为一切提供强大原动力。
<div class="bg"></div>
</div>
</div>
.g-wrap {
width: 100vw;
height: 100vh;
background: #000;
.text {
position: relative;
color: transparent;
color: #fff;
background: #000;
overflow: hidden;
}
.bg {
position: absolute;
top: 0;
left: 0;
right: 0;
width: 100%;
height: 400%;
background: linear-gradient(-3deg, #000, #000 25%, #ffb6ff 30%, #ffb6ff, #b344ff, #b344ff 70%, #000 75%, #000);
mix-blend-mode: darken;
animation: textScroll 6s infinite linear alternate;
}
}
@keyframes textScroll {
100% {
transform: translate(0, -75%);
}
}
这样,借助混合模式,我们也实现了题目的文字特效:
CodePen Demo -- iPhone 14 Pro Text Animation | mix-blend-mode
当然,原动画的实现是结合页面的滚动实现的。
在之前,我介绍了 CSS 最新的特性 @scroll-timeline,譬如这两篇文章:
@scroll-timeline 能够设定一个动画的开始和结束由滚动容器内的滚动进度决定,而不是由时间决定。
意思是,我们可以定义一个动画效果,该动画的开始和结束可以通过容器的滚动来进行控制。
但是!伤心的是,这个如此好的特性,最近已经被规范废弃,已经不再推荐使用了:
这里,我们使用传统的方法,那就必须得借助了 JavaScript 了,JavaScript 结合滚动的部分不是本文的重点,对于页面滚动配合动画时间轴,我们通常会使用 GSAP。
我们结合上述的混合模式的方法,很容易得到结合页面滚动的完整代码:
<div class="g-wrap">
<div class="text">灵动的 iPhone 新玩法,迎面而来。重大的安全新功能,为拯救生命而设计。创新的 4800 万像素主摄,让细节纤毫毕现。更有 iPhone 芯片中的速度之王,为一切提供强大原动力。
<div class="bg"></div>
</div>
</div>
<div class="g-scroll"></div>
.g-wrap {
position: fixed;
top: 0;
left: 0;
display: flex;
width: 100vw;
height: 100vh;
background: #000;
.text {
position: relative;
width: 800px;
color: #fff;
background: #000;
overflow: hidden;
}
.bg {
position: absolute;
top: 0;
left: 0;
right: 0;
width: 100%;
height: 400%;
background: linear-gradient(-3deg, #000, #000 25%, #ffb6ff, #b344ff, #000 75%, #000);
mix-blend-mode: darken;
}
}
.g-scroll {
position: relative;
width: 100vw;
height: 400vw;
}
gsap.timeline({
scrollTrigger: {
trigger: ".g-scroll",
start: "top top",
end: "bottom bottom",
scrub: 1
}
}).fromTo(".bg", { y: 0 }, { y: "-75%" }, 0);
可以看到,唯一的不同之处,就是利用了 gsap.timeline 结合滚动容器,触发动画。
效果如下:
CodePen Demo -- iPhone 14 Pro Text Animation | GSAP
好了,本文到此结束,希望本文对你有所帮助 ?
更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。
如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
我有一大串格式化数据(例如JSON),我想使用Psychinruby同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
MIMO技术的优缺点优点通过下面三个增益来总体概括:阵列增益。阵列增益是指由于接收机通过对接收信号的相干合并而活得的平均SNR的提高。在发射机不知道信道信息的情况下,MIMO系统可以获得的阵列增益与接收天线数成正比复用增益。在采用空间复用方案的MIMO系统中,可以获得复用增益,即信道容量成倍增加。信道容量的增加与min(Nt,Nr)成正比分集增益。在采用空间分集方案的MIMO系统中,可以获得分集增益,即可靠性性能的改善。分集增益用独立衰落支路数来描述,即分集指数。在使用了空时编码的MIMO系统中,由于接收天线或发射天线之间的间距较远,可认为它们各自的大尺度衰落是相互独立的,因此分布式MIMO
遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg
通常,数组被实现为内存块,集合被实现为HashMap,有序集合被实现为跳跃列表。在Ruby中也是如此吗?我正在尝试从性能和内存占用方面评估Ruby中不同容器的使用情况 最佳答案 数组是Ruby核心库的一部分。每个Ruby实现都有自己的数组实现。Ruby语言规范只规定了Ruby数组的行为,并没有规定任何特定的实现策略。它甚至没有指定任何会强制或至少建议特定实现策略的性能约束。然而,大多数Rubyist对数组的性能特征有一些期望,这会迫使不符合它们的实现变得默默无闻,因为实际上没有人会使用它:插入、前置或追加以及删除元素的最坏情况步骤复
在ruby中,你可以这样做:classThingpublicdeff1puts"f1"endprivatedeff2puts"f2"endpublicdeff3puts"f3"endprivatedeff4puts"f4"endend现在f1和f3是公共(public)的,f2和f4是私有(private)的。内部发生了什么,允许您调用一个类方法,然后更改方法定义?我怎样才能实现相同的功能(表面上是创建我自己的java之类的注释)例如...classThingfundeff1puts"hey"endnotfundeff2puts"hey"endendfun和notfun将更改以下函数定
这段代码似乎创建了一个范围从a到z的数组,但我不明白*的作用。有人可以解释一下吗?[*"a".."z"] 最佳答案 它叫做splatoperator.SplattinganLvalueAmaximumofonelvaluemaybesplattedinwhichcaseitisassignedanArrayconsistingoftheremainingrvaluesthatlackcorrespondinglvalues.Iftherightmostlvalueissplattedthenitconsumesallrvaluesw