乐趣区

关于javascript:使用CSS实现声生不息节目Logo

申明:本文波及图文和模型素材仅用于集体学习、钻研和观赏,请勿二次批改、非法流传、转载、出版、商用、及进行其余获利行为。

背景

《声生不息》是芒果 TV、香港电视广播有限公司和湖南卫视联合推出的港乐竞唱献礼节目,听着音乐好像回到了那个令人思念的港风席卷整个亚洲的年代。

该节目 Logo 采纳经典红蓝配色,有限符号 造型,满满的设计感。本文在仅采纳原生 CSS 的状况下,尽量还原实现该 Logo 造型,本文内容尽管非常简单,然而用到的知识点挺多的,比方:repeating-linear-gradientclip-pathbackground-clipWindow.getComputedStyle()CSSStyleDeclaration.getPropertyValue() 等。

成果

先来看看实现成果吧。

点击右上角的 半圆 形态,页面主体可切换为红色。

在线预览

👁‍🗨 Github:https://dragonir.github.io/sh…
👁‍🗨 Codepen:https://codepen.io/dragonir/f…

实现

开始之前,先把 Logo 中用到的次要色彩作为 CSS 变量,后续会在多处用到这几种色彩,并要通过变量实现页面主体 色彩切换 性能。

:root {
  --black: #010101;
  --red: #F66034;
  --blue: #0A68DF;
}

步骤 0:第一个圆 🔴

察看 Logo 原型能够发现,第一个 🔴 纯红色条纹 款式成果,能够通过 repeating-linear-gradient 实现条纹背景成果,并设置伪元素 ::after 为背景彩色实现圆环款式。

<div class="logo">
  <div class="cycle cycle_1"></div>
</div>
.cycle {
  height: 500px;
  width: 500px;
  border-radius: 50%;
  position: relative;
  box-sizing: border-box;
}
.cycle_1 {
  z-index: 2;
  background: var(--red);
  background: repeating-linear-gradient(180deg,var(--red),var(--red) 12px, var(--black) 0,  var(--black) 22px);
  border: 12px solid var(--black);
}
.cycle_1::after {
  content: '';
  display: inline-block;
  height: 200px;
  width: 200px;
  background: var(--black);
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -100px;
  margin-left: -100px;
  border-radius: 50%;
  z-index: 3;
}

💡 repeating-linear-gradient

repeating-linear-gradient 创立一个由反复线性突变组成的 <image>,和 linear-gradient 采纳雷同的参数,但它会在所有方向上反复突变以笼罩其整个容器。

语法

repeating-linear-gradient([<angle> | to <side-or-corner> ,]? <color-stop> [, <color-stop>]+ )
                            \---------------------------------/ \----------------------------/
                                      突变轴的定义                           色标列表
  • <side-or-corner>:形容突变线的起始点地位。它蕴含两个关键词:第一个指出垂直地位 leftright,第二个指出程度地位 topbottom。关键词的先后顺序无影响,且都是可选的。to top, to bottom, to leftto right 这些值会被转换成角度 0 度180 度270 度90 度。其余值会被转换为一个以向顶部地方方向为终点顺时针旋转的角度。突变线的完结点与其终点 中心对称
  • <angle>:用角度值指定突变的方向或角度。角度 顺时针 减少。
  • <color-stop>:由一个 <color> 值组成,并且跟随着一个可选的起点地位,能够是一个<percentage> 或者是沿着突变轴的 <length>

示例

// 一个歪斜 45 度的反复线性突变, 从蓝色开始突变到红色
repeating-linear-gradient(45deg, blue, red);
// 一个由下至上的反复线性突变, 从蓝色开始,40% 后变绿,最初突变到红色
repeating-linear-gradient(0deg, blue, green 40%, red);

🎏 每次反复,色标地位的偏移量都是 基准突变长度(最初一个色标和第一个之间的间隔)的倍数。因而,最初色标的色值应该与第一个色标的色值保持一致;如果不统一的话,会导致十分突兀的突变成果。
🎏 与其余突变一样,线形反复突变没有提供固定的尺寸;即, 它没有原始尺寸或首选尺寸,也没有首选的比例。它将自适应于对应元素的尺寸。

步骤 1:第二个圆 🔵

增加第二个圆 🔵 置于第一个圆 🔴 的底层,它的款式是从左到右的径向突变,通过 linear-gradient 即可实现。

<div class="logo">
  <div class="cycle cycle_1"></div>
  <div class="cycle cycle_2"></div>
</div>
.cycle_2 {
  margin-left: -160px;
  background: linear-gradient(to right, var(--red), var(--blue));
  border: 12px solid var(--black);
}
.cycle_2::after {
  content: '';
  display: inline-block;
  height: 200px;
  width: 200px;
  background: var(--black);
  position: absolute;
  top: 50%;
  left: 50%;
  margin-top: -100px;
  margin-left: -100px;
  border-radius: 50%;
  z-index: 3;
}

步骤 2:两个圆的重叠局部 🔴🔵

底部重叠局部,应用 clip-path 裁切出一个半圆成果,置于所有最顶层。

.cycle_2::before {
  position: absolute;
  box-sizing: border-box;
  top: -12px;
  left: -12px;
  content: '';
  display: inline-block;
  height: 500px;
  width: 500px;
  background: var(--red);
  border-radius: 50%;
  -webkit-clip-path: polygon(0 50%, 100% 50%, 100% 100%, 0 100%);
  clip-path: polygon(0 50%, 100% 50%, 100% 100%, 0 100%);
  z-index: 3;
  border: 12px solid var(--black);
}

💡 clip-path

clip-path 应用裁剪形式创立元素的可显示区域。区域内的局部显示,区域外的暗藏。

语法

// 关键字   值
// none
clip-path: none;
// <clip-source> 值
clip-path: url(resources.svg#c1);
// <geometry-box> 值
clip-path: margin-box;
clip-path: border-box;
clip-path: padding-box;
clip-path: content-box;
clip-path: fill-box;
clip-path: stroke-box;
clip-path: view-box;
// <basic-shape> 值
clip-path: inset(100px 50px);
clip-path: circle(50px at 0 100px);
clip-path: ellipse(50px 60px at 0 10% 20%);
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
clip-path: path('M0.5,1 C0.5,1,0,0.7,0,0.3 A0.25,0.25,1,1,1,0.5,0.3 A0.25,0.25,1,1,1,1,0.3 C1,0.7,0.5,1,0.5,1 Z');
// 盒模型和形态值联合
clip-path: padding-box circle(50px at 0 100px);
// 全局值
clip-path: inherit;
clip-path: initial;
clip-path: revert;
clip-path: revert-layer;
clip-path: unset;
  • <clip-source>:用 url() 援用 SVG<clipPath> 元素
  • <basic-shape>:一种形态,其大小和地位由 <geometry-box> 的值定义。如果没有指定 <geometry-box>,则将应用 border-box 用为参考框。取值可为以下值中的任意一个:

    • inset():定义一个 inset 矩形。
    • circle():定义一个圆形,应用一个半径和一个圆心地位。
    • ellipse():定义一个椭圆,应用两个半径和一个圆心地位。
    • polygon():定义一个多边形,应用一个 SVG 填充规定和一组顶点。
    • path():定义一个任意形态,应用一个可选的 SVG 填充规定和一个 SVG 门路定义。
  • <geometry-box>:如果同 <basic-shape> 一起申明,它将为根本形态提供相应的参考框盒。通过自定义,它将利用确定的盒子边缘包含任何形态边角(如被 border-radius 定义的剪切门路)。几何框盒的可选值:

    • margin-boxmargin box 作为援用框。
    • border-boxborder box 作为援用框。
    • padding-boxpadding box 作为援用框。
    • content-boxcontent box 作为援用框。
    • fill-box:利用对象边界框 object bounding box 作为援用框。
    • stroke-box:应用笔触边界框 stroke bounding box 作为援用框。
    • view-box:应用最近的 SVG 视口 viewport 作为援用框。如果 viewBox 属性被指定来为元素创立 SVG 视口,援用框将会被定位在坐标系的原点,援用框位于由 viewBox 属性建设的坐标系的原点,援用框的尺寸用来设置 viewBox 属性的宽高值。
  • none:不创立剪切门路。

步骤 3:重叠局部优化 🔴🔵

将重叠局部设置为与第二个圆 🔵 雷同的渐变色,能够产生由第一圆 🔴 过渡为第二圆 🔵 的错觉。

.cycle_2::before {background: linear-gradient(to right, var(--red), var(--blue));
}

步骤 4:文字 🅰

Logo 文字是从左到右由蓝到红的突变成果,能够通过将文字的盒背景设置为渐变色,而后通过 background-clip: text 将背景被裁剪成文字的前景色来实现。

<h1 class="text"> 声生不息 </h1>
.text {background: linear-gradient(to right, var(--blue), var(--red));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  font-style: italic;
}

💡 background-clip

background-clip 设置元素的背景图片或色彩是否延长到边框、内边距盒子、内容盒子上面。如果没有设置background-imagebackground-color,那么这个属性只有在 border 被设置为非 soild、通明或半透明时能力看到视觉效果,否则本属性产生的款式变动会被边框笼罩。

语法

// 关键字         值
background-clip: border-box;
background-clip: padding-box;
background-clip: content-box;
background-clip: text;
// 全局值
background-clip: inherit;
background-clip: initial;
background-clip: unset;
  • border-box:背景延长至边框外沿,然而在边框上层。
  • padding-box:背景延长至内边距 padding 外沿。不会绘制到边框处。
  • content-box:背景被裁剪至内容区 content box 外沿。
  • text:背景被裁剪成文字的前景色(实验性属性)。

步骤 5:点击切换成果 🔲

点击右上角的的半圆形图案 ,能够实现将 Logo 黑白 切换为 纯白色,该性能是通过切换定义在 :root 下的 CSS 变量 值实现的,能够通过以下办法实现 CSS 变量 值的切换。

<span class="toggle" id="toggle" title="点击切换色彩"></span>

半圆形图案 的噪点背景成果是通过增加一张噪点图实现。

.toggle {background: linear-gradient(to left bottom, var(--blue), rgba(0, 0, 0, 0)), url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAgMAAADXB5lNAAAADFBMVEUvLy9eXl6AgICoqKhWH7o7AAAABHRSTlMSEhIS3WyPCwAAA1hJREFUOMsN0M3rDHEcwPH3d3y/4zcr67s1s3bIU62y8nBxcVCf79pZ4WBWsx6TVbvyEKUolJrxmBTj4SecVqE4OTjgIP6D5eC8DkouOJAj19fxhXJCWn811mk1Sp1q0J0q6AoNF7ZQ0uD+74CBj3otoUUEmJc0wqVEr2Ulatp1/6HYA9SGwfn+s6ftD8zsbic1idsPVrfcoQRYSrvbd7PdA7TY6cKcbfrwRXaJaqgTXSfDKd625S7XGB1YraJ0yuatOJmJvf5aqIwYINvBGIr+gZiDl80Qdoh3M1GTfuCzf1+yEetme3loJ3Hf6yijG5S9rRa7XI7Nzu1AYGF5Bd1cNeplTmN8yJpV8kYrpKEIAzXDgbBK2QhhTb37NP4P1aqRZ3ua6DVLb2AKjVpgBkbHie4QGFVqxDcpgL4tlTUMNKKgazpmWC+CkBBkTu59dpl+XikMg+U5izd/9z+KpxcFYvxxs01Vtho32XLZBNRmy8YWQBszOV6ES9r7cvQdshRbKVdfOrDKeyB+MeXsWvMmI95/Pdsp7J5MydZHR9MonithyhIllnSppjGaQRkb7vVyTaqNhLUsVI5I/HEDi3JYWdu+KEgsmkzJXGPZ97wQyqPREfp+vmAvzo3AfhF9HvZS1SiZL9H4pVgfhmofCltJ3wxq9/961Aaqq3HpzsFroqtPe9SVm3Ol5yd3f99TueB46l+9lB/drm4PxXs/4j4j5k6pAzS88njnDp72JijRYlYFRMaxfY8q20pWZjGLdKsCP2YoVYXl9RK1Kp7Xpx8MLYEe+gIWlUDwJNABR0AVAGQ4rfcCrci5YQYZonhi9ckLVrkTeCTeL5+0H7+Lw1baYjGu+6ddepc6qeLc8EhvL3dvf5Xi9maHyrGnCmFXXo7bk83O3C6FFYVDURtfLD4YVUpO011EfYvktpukxpKogevhPViJPC6tmWnOcxkaJYnwOw2zyoYKeAmKIlfpILLxBmOo3yLlkzh5+yTKmkvtrsc3oP8Tx7t8YTms2Be9a0TJNJ21Gb6k5mwY9Vn/P2vRSHu7tiZ2kx6mrMtCoqPG+9w3YWxOw5EZDcszz+tUQhZlq8j8Rw77ynqzi7XaV3kH8x62ScfWdhZpkgX3wWdZcibtbFASgOEfZmfZzbdc/O0AAAAASUVORK5CYII=');
}
// 获取根元素
const root = document.querySelector(':root');
// 创立获取变量值的函数
const getCssVariable = (key) =>  {return getComputedStyle(root).getPropertyValue(key);
}
// 创立设置变量值的函数
const setCssVariable = (key, value) => {root.style.setProperty(key, value);
}
// 点击切换 CSS 变量值
document.getElementById('toggle').addEventListener('click', () => {if (getCssVariable('--blue') === '#FFFFFF') {setCssVariable('--blue', '#0A68DF');
    setCssVariable('--red', '#F66036');
  } else {setCssVariable('--blue', '#FFFFFF');
    setCssVariable('--red', '#FFFFFF');
  }
}, false);

💡 Window.getComputedStyle()

Window.getComputedStyle() 办法返回一个对象,该对象在利用 active 样式表并解析这些值可能蕴含的任何根本计算后,返回元素的所有 CSS 属性的值。

语法:

let style = window.getComputedStyle(element, [pseudoElt]);
  • 参数

    • element:用于获取计算款式的 Element
    • pseudoElt:可选,指定一个要匹配的伪元素的字符串。必须对一般元素省略或 null
  • 返回值:返回的 style 是一个实时的 CSSStyleDeclaration 对象,当元素的款式更改时,它会自动更新。

🎏 getComputedStyle 能够从伪元素拉取款式信息,如 ::after, ::before, ::marker, ::line-marker

💡 CSSStyleDeclaration.getPropertyValue()

CSSStyleDeclaration.getPropertyValue() 接口返回一个 DOMString,其中蕴含申请的 CSS 属性的值。

语法

var value = style.getPropertyValue(property);
  • 参数property 是一个 DOMString,是须要查问的 CSS 属性名称。
  • 返回值valueDOMString,蕴含查找属性的值。若对应属性没有设置,则返回空字符串。

步骤 6:噪点背景

仔细观察的话,页面背景并不是单纯的彩色,而是会有轻微的相似电视机 📺 雪花 噪点成果,通过以下款式即可实现噪点成果。

<div class="bg"></div>

背景是一张噪点图片,设置背景时将 background-repeat 设置为 repeat 并增加通过translate 实现位移的动画实现噪点晃动成果。

.bg {
  position: fixed;
  top: -50%;
  left: -50%;
  right: -50%;
  bottom: -50%;
  width: 200%;
  height: 200vh;
  background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABAAgMAAADXB5lNAAAADFBMVEUvLy9eXl6AgICoqKhWH7o7AAAABHRSTlMSEhIS3WyPCwAAA1hJREFUOMsN0M3rDHEcwPH3d3y/4zcr67s1s3bIU62y8nBxcVCf79pZ4WBWsx6TVbvyEKUolJrxmBTj4SecVqE4OTjgIP6D5eC8DkouOJAj19fxhXJCWn811mk1Sp1q0J0q6AoNF7ZQ0uD+74CBj3otoUUEmJc0wqVEr2Ulatp1/6HYA9SGwfn+s6ftD8zsbic1idsPVrfcoQRYSrvbd7PdA7TY6cKcbfrwRXaJaqgTXSfDKd625S7XGB1YraJ0yuatOJmJvf5aqIwYINvBGIr+gZiDl80Qdoh3M1GTfuCzf1+yEetme3loJ3Hf6yijG5S9rRa7XI7Nzu1AYGF5Bd1cNeplTmN8yJpV8kYrpKEIAzXDgbBK2QhhTb37NP4P1aqRZ3ua6DVLb2AKjVpgBkbHie4QGFVqxDcpgL4tlTUMNKKgazpmWC+CkBBkTu59dpl+XikMg+U5izd/9z+KpxcFYvxxs01Vtho32XLZBNRmy8YWQBszOV6ES9r7cvQdshRbKVdfOrDKeyB+MeXsWvMmI95/Pdsp7J5MydZHR9MonithyhIllnSppjGaQRkb7vVyTaqNhLUsVI5I/HEDi3JYWdu+KEgsmkzJXGPZ97wQyqPREfp+vmAvzo3AfhF9HvZS1SiZL9H4pVgfhmofCltJ3wxq9/961Aaqq3HpzsFroqtPe9SVm3Ol5yd3f99TueB46l+9lB/drm4PxXs/4j4j5k6pAzS88njnDp72JijRYlYFRMaxfY8q20pWZjGLdKsCP2YoVYXl9RK1Kp7Xpx8MLYEe+gIWlUDwJNABR0AVAGQ4rfcCrci5YQYZonhi9ckLVrkTeCTeL5+0H7+Lw1baYjGu+6ddepc6qeLc8EhvL3dvf5Xi9maHyrGnCmFXXo7bk83O3C6FFYVDURtfLD4YVUpO011EfYvktpukxpKogevhPViJPC6tmWnOcxkaJYnwOw2zyoYKeAmKIlfpILLxBmOo3yLlkzh5+yTKmkvtrsc3oP8Tx7t8YTms2Be9a0TJNJ21Gb6k5mwY9Vn/P2vRSHu7tiZ2kx6mrMtCoqPG+9w3YWxOw5EZDcszz+tUQhZlq8j8Rw77ynqzi7XaV3kH8x62ScfWdhZpkgX3wWdZcibtbFASgOEfZmfZzbdc/O0AAAAASUVORK5CYII=') repeat 0 0;
  background-repeat: repeat;
  animation: bg-animation .2s infinite;
}
@keyframes bg-animation {0% { transform: translate(0,0) }
  10% {transform: translate(-5%,-5%) }
  // ...
  100% {transform: translate(5%,0) }
}

残缺代码:https://github.com/dragonir/s…

总结

本文蕴含的知识点次要包含:

  • repeating-linear-gradient 条纹背景
  • clip-path 形态裁切
  • background-clip 设置元素的背景延长
  • Window.getComputedStyle() 获取计算后元素的所有 CSS 属性的值
  • CSSStyleDeclaration.getPropertyValue() 获取申请的 CSS 属性的值

想理解其余前端常识或 WEB 3D 开发技术相干常识,可浏览我往期文章。转载请注明原文地址和作者 。如果感觉文章对你有帮忙,不要忘了 一键三连哦 👍

附录

  • [1]. 📷 前端实现很哇塞的浏览器端扫码性能
  • [2]. 🌏 前端瓦片地图加载之塞尔达传说旷野之息
  • [3]. 🆒 仅用 CSS 几步实现赛博朋克 2077 格调视觉效果
  • ...

3D

  • [1]. 🦊 Three.js 实现 3D 凋谢世界小游戏:阿狸的多元宇宙
  • [2]. 🔥 Three.js 火焰成果实现艾尔登法环动静 logo
  • [3]. 🐼 Three.js 实现 2022 冬奥主题 3D 趣味页面,含冰墩墩
  • ...

参考

  • https://developer.mozilla.org…
  • https://developer.mozilla.org…
  • https://developer.mozilla.org…
  • https://developer.mozilla.org…
  • https://developer.mozilla.org…
退出移动版