与众不同的夜间开关交互效果

news2024/9/29 13:27:48

这个夜间模式切换开关效果是不是很炫酷,在短视频曾刷到过是一个国外的设计师看似是为了难为我们前端开发设计了一个元素超多且动画复杂的开关切换效果。

结果在逛 codepen 的时候发现真的被一个大佬给做出来了,效果真的很不错,而且还在原来的基础上增加了额外的元素,本文将逐步解析大佬的实现过程。

动画分析

基于开关的动画效果可以将相关动画步骤进行模块拆分,大概可以拆分为下列模块:

  • 开关内部的主色调由蓝色背景切换为黑色
  • 开关内部的圆由黄色(太阳的效果)切换为灰色(月亮的效果)
  • 开关内部的圆可见的有三个不同透明度的大圆跟随切换动画
  • 开关为亮色时有两层云朵,并伴有小飞机飞过的动画(封面动图不完整,可以看最后完成的效果)
  • 开关未暗色时有小星星且有闪烁的效果,并伴有太空熊飞过的动画(封面动图不完整,可以看最后完成的效果)
  • 开关切换为暗色时整个页面背景切换为暗色

除了上述比较核心的部分内容,还有一些CSS相关的细节,比如开关的3D边框效果,开关内部的圆阴影效果,切换过程中的贝塞尔曲线效果等,本文主要拆解核心实现的代码,全部代码有兴趣的可以看源码。

前置知识点

在正式开始前先介绍几个本文需要用到的知识点,方便后续的理解,首先是元素中以 aria- 开头的属性。

aria- 开头的属性是为了实现无障碍访问(Accessibility)而制定的一组Web标准属性,通常应用于HTML元素上,以提高网站的可访问性。其中“ARIA”全称为“Accessible Rich Internet Applications”,即可访问的丰富Internet应用程序。

本文会用到aria-pressedARIA属性,用于指示一个按钮或切换的状态是否被按下或打开。它可以是以下三种状态之一:

  • aria-pressed="false":按钮或切换处于关闭状态。
  • aria-pressed="true":按钮或切换处于开启状态。
  • aria-pressed="mixed":按钮或切换处于混合状态,例如在多个选项中选择了一些但不是全部。

使用aria-pressed属性有助于提高网站的可访问性,让使用屏幕阅读器的人员能够更好地理解页面上各个元素的作用和状态。

第二个是CSS函数 var(),用于引用先定义的变量值。它的语法为 var(--variable-name, default-value),其中:

  • --variable-name 表示变量名称,必须以两个连字符(--)开头,其后可以是任何自定义名称。
  • default-value 是可选的,表示在指定变量未定义或无效时要使用的默认值。

例如,假设我们定义了一个名为 --dark 的变量,当其值为1的时候,最终的代码则是 scale: 1,如果 --dark 没有定义则最终的代码是 scale: 0

.element {
  scale: var(--dark, 0);
}

使用变量可以帮助我们轻松地更新和维护样式表的数据,因为可以只更改变量的值,而不必在样式表每个出现的地方都进行更改。

基于上面提到的 aria-pressed,通过JS点击事件动态控制元素的 aria-pressed 值。

BUTTON.setAttribute("aria-pressed", IS_PRESSED ? false : true);

实际也就是控制了 --dark 的值,间接的也控制了所有使用了 --dark 定义的颜色、大小、字体和其他样式属性的值。

[aria-pressed=true] {
  --dark: 1;
}

本文的CSS代码中将使用大量的 var(--dark, default-value) 控制元素的显示隐藏及动画效果。

代码实现

背景颜色的切换

接下来开始基于上面的动画分析开始拆解各核心部分的具体代码实现,首先实现开关内部背景颜色的切换,核心代码如下,基于 --dark 的变化修改 background 背景色,最终计算出的值即是 --sky--night 的值,这里并没有使用到,只是为了方便查看,需要注意一点的是这里使用了 hsl 格式的色值,后面两个参数的值是需要百分比格式的值,所以增加了 * 1%

--sky: hsl(204, 53%, 47%);
--night: hsl(229, 25%, 16%);
background: hsl(
  calc(204 + (var(--dark, 0) * 25))
  calc((53 - (var(--dark, 0) * 28)) * 1%)
  calc((47 - (var(--dark, 0) * 31)) * 1%)
);

整个页面的背景切换是在按钮点击的时候给body设置了 data-dark-mode 属性。

document.body.setAttribute("data-dark-mode", IS_PRESSED ? false : true);

通过 data-dark-mode 属性值取不同的背景色值。

:root {
  --bg: hsl(219, 30%, 88%);
  --color: hsl(219 30% 20%);
}

[data-dark-mode=true] {
  --bg: hsl(219, 30%, 12%);
  --color: hsl(219 30% 98%);
}

开关内部圆的背景色切换动画

然后是开关内部的圆由黄色(太阳的效果)切换为灰色(月亮的效果),仔细观察切换过程中的效果可以发现,切换后的灰色圆是从左往右覆盖黄色圆的效果,由此可见实现方式可以是基于定位,灰色圆层级高于黄色圆,或者灰色圆是黄色圆的子元素,这里的实现是基于父子元素实现。

整个切换过程有两个动画,首先是整个圆从左往右的平移过程,默认 --dark 没有定义时最终计算出的值是 0px--dark 为1时基于当前的总宽度减去的自身圆的宽度「3 / 8 * var(–width)」即是需要平移的距离。

translate: calc(
    var(--dark, 0) * (var(--width) - (3 / 8 * var(--width)))
  ) 0;

然后圆内部的背景切换动画,默认月亮背景元素进行平移X轴100%,切换完成后修改平移X轴为0%。

translate: calc((100 - (var(--dark, 0) * 100)) * 1%) 0%;

再增加相应的过渡动画就可以看到两个背景色可见的切换过程效果。

transition: translate var(--speed) ease-in-out;

外部的父元素增加了 overflow: hidden,所以默认平移X轴100%是不可见的,大家看下面没有增加 overflow: hidden 代码的效果就更清晰实现的原理了。

  • 增加三个不同透明度的圆跟随切换动画

这个实现相对比较简单,基于 radial-gradient 径向渐变绘制三层背景色,其实就是同一个色值渐变的开始和结束位置不一样叠在一起形成的不同深浅颜色。基于定位将这个背景定位于圆的中心,平移的动画和上面圆的平移类似,只是由于背景区域的扩大,导致平移的数值会变小,这里就不贴代码了。

background:
    radial-gradient(hsl(0 0% 100% / 0.25) 40%, transparent 40.5%),
    radial-gradient(hsl(0 0% 100% / 0.25) 56%, transparent 56.5%)
    hsl(0 0% 100% / 0.25);

云朵 & 星星切换动画

云朵 & 星星的复杂度就高很多了,所以这里不再使用纯CSS实现,基于svg实现,svg涉及的代码量很多就不全部贴出来了,云朵总共有两个颜色,所以是有两块svg代码,可以看到下面的path对应的fill色值是不同的,其他的就是具体的path路径不一样了。

<!-- light模式的云1 -->
<svg aria-hidden=true class="toggle__backdrop" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 290 228">
  <g class="clouds">
    <path fill="#D9D9D9" d="M335..." />
  </g>
</svg>
<!-- light模式的云2 -->
<svg aria-hidden=true class="toggle__backdrop" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 290 228">
  <g class="clouds">
    <path fill="#fff" d="M328..." />
  </g>
</svg>

这里的云朵和星星的动画稍微有点不一样,不再是左右平移,而是上下平移,所以 translate 只修改Y轴的值。

transition: translate var(--speed) var(--easing);
translate: 0 calc(
  var(--dark, 0) * (100% - (3 / 8 * var(--width)))
);

仔细看有的星星会有闪烁的效果,其实就是通过给对应svg元素设置动画控制元素的缩放,并给不同的星星设置不同的执行时间和延迟执行时间。

animation: twinkle 4s -2s infinite;

@keyframes twinkle {
  0%, 40%, 60%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(0);
  }
}

太空熊 & 小飞机

这两个元素都有两个动画,比如太空熊在飞过开关区域的时候自身是在旋转的,就像在太空一样,小飞机飞过的时候也不是直线飞出的,在动画过程中Y轴增加了一定比例的变化。这里有些不一样的时候上面的平移动画都是左右上下移动,可以看到这里是斜着平移的,说明在平移的时候两个方向的值都在发生变化,以下是太空熊相关动画的代码。小飞机相关的代码就不再列举了,核心都是通过平移配合过渡实现动画效果。

// 平移动画
translate: calc(var(--dark, 0) * 400%) calc(var(--dark, 0) * -350%);
transition: translate calc(var(--speed) + (var(--dark, 0) * (var(--bear-speed) - var(--speed)))) calc(var(--bear-speed) * (0.4 * var(--dark, 0))) linear;

// 自身旋转动画
rotate: calc(var(--dark, 0) * 360deg);
transition: rotate calc(var(--speed) + (var(--dark, 0) * (var(--bear-speed) - var(--speed)))) calc(var(--bear-speed) * 0.4) linear, scale var(--speed) ease-in-out;

最后

在这里我们已经介绍了整个实现过程的核心,实现了交互效果,但还有一些其他的功能如3D阴影、过渡、贝塞尔曲线动画等没有进行具体的介绍。如果对这些功能感兴趣,可以查看源代码进行详细了解。

初看起来,交互效果可能会让人感到非常棘手,各种细节效果都混在一起。但是,一旦开始了实现,就会发现其实并不难。将任务拆分成一个个小步骤去实现,大事化小小事化了。

看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~

专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)

参考

源码:https://codepen.io/jh3y/pen/LYgj

在线预览:https://code.juejin.cn/pen/7231072547259809852

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/545737.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

矩池云教程|体验 OpenAI 最近推出的 3D 生成模型 Shap-E!

Shap-E 是由 OpenAI 最近推出的3D生成模型&#xff0c;使用者可以通过简单的文字或图像进行三维模型的生成&#xff0c;OpenAI 认为相比于点云的生成模型Point-E&#xff0c;Shap-E的收敛更快。本文将展示如何在矩池云上体验3D模型生成。 Shap-E&#xff1a;https://github.co…

自动生成测试用例_接口测试用例自动生成工具

前言 写用例之前&#xff0c;我们应该熟悉API的详细信息。建议使用抓包工具Charles或AnyProxy进行抓包。 har2case 我们先来了解一下另一个项目har2case 他的工作原理就是将当前主流的抓包工具和浏览器都支持将抓取得到的数据包导出为标准通用的 HAR 格式&#xff08;HTTP A…

软件测试需要学会写代码吗?

无论是刚入测试行业的萌新&#xff0c;还是已经在测试行业闯荡了两三年的小司机们&#xff0c;都会琢磨一个问题&#xff1a;如果要持续发展下去&#xff0c;我要不要懂代码&#xff1f; 在软件测试初级阶段&#xff0c;不需要编程能力。但是任何一个职业&#xff0c;都会追求…

【网络协议详解】——IPv6协议(学习笔记)

&#x1f4d6; 前言&#xff1a;IPv6 协议是未来互联网的发展方向&#xff0c;它的推出为网络通信和互联带来了更大的便利性和更广阔的发展空间。相比于 IPv4&#xff0c;IPv6 支持更多的地址空间、更高效的路由和唯一的全球性地址等特点&#xff0c;可以更好地满足未来数字化时…

Mac电脑 Vscode : Flutter 开发环境搭建(最细节教程)

参考链接&#xff1a; MacVSCode安装flutter环境_mac vscode配置flutter_GalenWu的博客-CSDN博客 mac搭建Flutter环境以及初始化项目 - 简书 注意&#xff1a; *下载xcode 就包含git了, *苹果芯片和intel 芯片需要的环境不同&#xff0c;苹果芯片需要安装&#xff1a; Im…

攻防世界web新手区部分题解

前言&#xff1a;博主是个安全小白&#xff0c;正在努力学习中&#xff0c;会随着学习进度不定期更新完善本篇博客。 这里是目录 1.robots2.view_source3.backup4.disabled_button5.get_post6.cookie7.ics-068.PHP2 1.robots 题目描述: X老师上课讲了Robots协议&#xff0c;小宁…

SpringBoot+Redis完成数据缓存(内容丰富度一定超出你的想象)

SpringBootRedis完成数据缓存 去年今日此门中 人面桃花相映红 人面不知何处去 桃花依旧笑春风 感谢相遇&#xff01;感谢自己&#xff0c;努力的样子很给力&#xff01; 为了更多朋友看见&#xff0c;还是和大家说一声抱歉&#xff0c;限制为粉丝可见&#xff01;有问题可以随时…

基于SSM+JSP的大学生社团管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

数字信号处理基础(二):FFT和IFFT的使用以及详细分析代码书写思路

目录 1. fft和ifft的原理1.1 fft1.2 ifft 2. 书写代码思路3. 完整代码4. 结果图 1. fft和ifft的原理 1.1 fft fft是快速傅里叶变换&#xff0c;是MATLAB中计算信号频谱的函数&#xff0c;使用方法是fft(x)&#xff0c;直接对信号x进行fft计算。 由于fft函数计算信号的频谱是0…

国考省考行测:资料分析,两年复合增长率

国考省考行测&#xff1a;资料分析&#xff0c;两年复合增长率 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要的还是申论和行测&#xff0c;所以大家认真准备吧&#xff0c;我讲一起屡屡…

考研算法第十三天:二叉排序树 【二叉排序树的插入和遍历】

这道题很妙。题目给的二叉排序树好像没学过其实就是二叉查找树。然后这道题主要的就是思路 1.节点的初始化&#xff08;记住&#xff09; struct TreeNode {int val;TreeNode *left;TreeNode *right;TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; 2.节点的插入 …

HTTPS 的加密流程

文章目录 前言一.HTTPS 是什么二."加密" 是什么四.HTTPS解决了哪些问题五.HTTPS 的工作过程对称加密非对称加密引入证书 前言 本文介绍了HTTPS的加密流程&#xff0c;以及HTTPS在保护用户数据安全和确保通信机密性方面的重要性。通过详细解释HTTPS的工作原理和加密流…

网络安全里的主要岗位有哪些?小白如何快速入门?

入门Web安全、安卓安全、二进制安全、工控安全还是智能硬件安全等等&#xff0c;每个不同的领域要掌握的技能也不同。 当然入门Web安全相对难度较低&#xff0c;也是很多人的首选。主要还是看自己的兴趣方向吧。 本文就以下几个问题来说明网络安全大致学习过程&#x1f447; 网…

ChatGPT:世界已经永远改变了,而大多数人尚无所觉

1、你发现没有&#xff0c;现在跟朋友交流&#xff0c;言必聊ChatGPT。几乎所有人都在蹭GPT的热度&#xff0c;无论是头部企业还是普通的个人开发者&#xff0c;都想趁着ChatGPT东风狂赚一笔。有卖ChatGPT账号的、有借用ChatGPT的API集成服务让人付费试用的&#xff0c;还有人利…

Android第一代加壳技术的验证、测试和探究

Android第一代加壳测试&#xff0c;网上有很多文章&#xff0c;本文只是在前人基础上测试和验证。因此&#xff0c;本文的重点在于动手和实践。 第一代加壳技术有三个项目&#xff0c;分别是&#xff1a; 加壳程序。主要是把需要加壳的原程序加密后&#xff0c;放在壳程序中&…

全能超高清解码播放器_完美解码

哈喽&#xff0c;大家好。今天给各位小伙伴们测试了一款全能超高清解码播放器——完美解码。 这是一款为众多影视发烧友精心打造的专业高清播放器。超强HDTV支持&#xff0c;画质远超主流播放器&#xff01;全面开启硬件加速&#xff0c;CPU资源占用低&#xff0c;强劲高清解码…

Matplotlib绘制漂亮的饼状图|python绘制漂亮的饼状图

python绘图系列文章目录 往期python绘图合集: python绘制简单的折线图 python读取excel中数据并绘制多子图多组图在一张画布上 python绘制带误差棒的柱状图 python绘制多子图并单独显示 python读取excel数据并绘制多y轴图像 python绘制柱状图并美化|不同颜色填充柱子 python随机…

LeetCode刷题 --- 栈

栈&#xff08;stack&#xff09;是一种用于存储数据的简单数据结构。栈一个有序线性表&#xff0c;只能在表的一端&#xff08;PS&#xff1a;栈顶&#xff09;执行插人和删除操作。最后插人的元素将被第一个删除。所以&#xff0c;栈也称为后进先出&#xff08;Last In First…

AI在狂飙,ChatGPT-4可直接在iPhone上使用啦

今天凌晨&#xff0c;OpenAI 正式在 App Store 推出了 ChatGPT 的 iOS app&#xff0c;瞬间冲上苹果商店免费榜第二名&#xff0c;效率榜第一名。 于是兴致勃勃的去下载体验了一番。整体不错&#xff0c;以后手机使用官方的 ChatGPT 更方便啦&#xff01;而且使用 GPT4 不再麻…