4

使用CSS实现《声生不息》节目Logo - Dragonir

 1 year ago
source link: https://www.cnblogs.com/dragonir/p/16265984.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

使用CSS实现《声生不息》节目Logo

772544-20220513112330553-1891924737.png

声明:本文涉及图文和模型素材仅用于个人学习、研究和欣赏,请勿二次修改、非法传播、转载、出版、商用、及进行其他获利行为。

772544-20220513094340813-369891995.png

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

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

先来看看实现效果吧。

772544-20220513094401883-1065325265.png

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

772544-20220513094411887-1456408701.png

👁‍🗨 Github:https://dragonir.github.io/shengshengbuxi/
👁‍🗨 Codepen:https://codepen.io/dragonir/full/OJQRBad

开始之前,先把 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;
}
772544-20220513094427341-1057230041.png

💡 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;
}
772544-20220513110717684-1620104747.png

步骤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);
}
772544-20220513110727305-1770263572.png

💡 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));
}
772544-20220513110754465-1336547373.png

步骤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;
}
772544-20220513110804866-1606666837.png

💡 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,包含查找属性的值。若对应属性没有设置,则返回空字符串。
772544-20220513110819029-1830420675.png

步骤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/shengshengbuxi

本文包含的知识点主要包括:

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

想了解其他前端知识或 WEB 3D 开发技术相关知识,可阅读我往期文章。转载请注明原文地址和作者。如果觉得文章对你有帮助,不要忘了一键三连哦 👍

3D

作者:dragonir 本文地址:https://www.cnblogs.com/dragonir/p/16265984.html


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK