使用CSS實現《聲生不息》節目Logo

dragonir發表於2022-05-13
宣告:本文涉及圖文和模型素材僅用於個人學習、研究和欣賞,請勿二次修改、非法傳播、轉載、出版、商用、及進行其他獲利行為。

背景

《聲生不息》 是芒果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 開發技術相關知識,可閱讀我往期文章。轉載請註明原文地址和作者。如果覺得文章對你有幫助,不要忘了一鍵三連哦 ?

附錄

3D

參考

相關文章