Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
用說, Flash的效果大家都清楚。實(shí)際上,HTML5和JavaScript擁有很多新屬性,可以用它們來替代Flash。W3Cschool精選16個(gè)超牛逼的HTML5和JavaScript特效,看了這些特效,未來的Web發(fā)展前途無量。
1.特效:FlowerPower
創(chuàng)作者使用花朵作為畫刷,以貝茲曲線方式繪圖。
2.特效:Breathing Galaxies
動(dòng)態(tài)變換直徑及顏色,可通過鼠標(biāo)或鍵盤產(chǎn)生新形狀,這個(gè)效果不錯(cuò)!
3.特效:Noise Field
移動(dòng)鼠標(biāo)可改變粒子運(yùn)動(dòng),點(diǎn)擊可隨機(jī)生成不同粒子效果。
4.特效:HTML5 Canvas粒子效果文字動(dòng)畫特效
W3Cschool利用HTML5,制造出了粒子效果文字動(dòng)畫特效。只要你輸入框中輸入想要展示的文字,回車后即可在canvas上繪制出粒子效果的文字動(dòng)畫,相當(dāng)酷的動(dòng)畫效果。
5.特效:Swirling Tentacles
三維脈沖效果,沿著脈沖線有運(yùn)動(dòng)的顏色漸變模塊。
6.特效:Keylight
雙擊生成兩個(gè)以后的鍵即可發(fā)出聲音,移動(dòng)鍵的位置可產(chǎn)生不同的聲音效果。W3Cschool上面有很多這樣的教程,有興趣可以去看一下!
7.特效:Rotating Spiral
旋轉(zhuǎn)的螺旋效果,單擊可以控制開始和停止旋轉(zhuǎn),是不是覺得高大上?
8.Blob
拖動(dòng)水滴有重力效果,雙擊可以分離,小水滴碰到大水滴會(huì)合并。
9.Trail
彩色顆粒跟隨鼠標(biāo)運(yùn)動(dòng)效果,帶尾巴淡出效果。
10.Graph Layout
一種交互的力向圖布局效果,刷新三觀。
11.Typographic Effects
使用HTML5 Canvas實(shí)現(xiàn)的文本特性,效果超過Flash。
12.Crazy Tentacles
移動(dòng)鼠標(biāo)可以進(jìn)行涂鴉,點(diǎn)擊鼠標(biāo)可以清除畫布,看著確實(shí)瘋狂。
13.Nebula
吸引眼球的粒子系統(tǒng),目的是測(cè)試WebGL性能,如果滑動(dòng)鼠標(biāo),可以產(chǎn)生絢麗效果。
14.WebGL Globe
WebGL Globe 是一個(gè)開放的地理數(shù)據(jù)可視化平臺(tái),我們鼓勵(lì)你復(fù)制代碼,添加自己的數(shù)據(jù),創(chuàng)建自己的應(yīng)用。
15.Particle Playground
用鼠標(biāo)和粒子進(jìn)行交互,能發(fā)現(xiàn)不一樣的精彩。
16.Surface
使用WebGL實(shí)現(xiàn)的水面特效實(shí)驗(yàn),可放入一張照片,使用鼠標(biāo)觸動(dòng)水面會(huì)有奇特效果。
上面的HTML5和JavaScript特效,簡(jiǎn)直趕超F(xiàn)lash。W3Cschool上面有很多用戶留言稱HTML5和JavaScriptit將替代Flash,不過對(duì)于這種說法,也不知道怎么去評(píng)判。畢竟這些用戶說的也是很有道理,你認(rèn)為JavaScriptit會(huì)替代Flash嗎?很想知道你的答案!
公眾號(hào):w3c技術(shù)教程
提供專業(yè)的web技術(shù)教程、手冊(cè)、工具。
一種構(gòu)建靈活的系統(tǒng)頁(yè)面主題方案
前置技術(shù)點(diǎn)
閱讀此篇文章前,最好有下列知識(shí)
css 基礎(chǔ)知識(shí)
dart-sass 預(yù)處理器編程
webpack 以及 postcss
tailwindcss 含有 jit 的 v2/v3
前言
我們?cè)谌粘I钪校徽撌窃L問網(wǎng)站,手機(jī)App,還是小程序,時(shí)常會(huì)用到 切換主題 這個(gè)功能。它能夠?yàn)橛脩籼峁┮欢ǖ淖远x顯示界面的能力,同時(shí)手機(jī)系統(tǒng)級(jí)別的主題也能夠更換,比如 light(明亮模式) 和 dark(黑暗模式)。
那么如何讓我們編寫的應(yīng)用,在改動(dòng)不大的情況下,能夠快速的適配多個(gè)主題呢?
這就需要設(shè)計(jì)一個(gè)方案了。
方案設(shè)計(jì)
方案參考
這里我們以程序員們最熟悉的 Github 為例,它的主題切換是這樣做的:
它在 根元素 那預(yù)設(shè)了幾套 css 變量值, 然后通過 js 去動(dòng)態(tài)修改 html 根元素上的 data-color-mode 和 data-dark-theme 這些屬性的值,從而讓不同的 css 選擇器選中這個(gè)根元素,并以此來動(dòng)態(tài)的切換 :root 中的 css 變量的值。
同時(shí)這些變量都被廣泛的使用在各種的 原子化的 class 和 @apply 中,一旦變量一換,所有使用到這些class的控件和布局都收到影響,自然整個(gè)主題就改變了。
1. 提煉css變量
首先我們第一步要做的就是提煉css變量,這些主要由設(shè)計(jì)師提供。
這里以顏色為例,主要包含 同個(gè)顏色的多態(tài),控件各個(gè)狀態(tài)的顏色,提示警告錯(cuò)誤,字體中,標(biāo)題,副標(biāo)題,正文,提示的顏色 等等。當(dāng)然像字體大小,陰影這類也是同樣的。
這方面就不細(xì)說了,在提取到變量之后我們就可以開始進(jìn)行命名工作:
// constants.scss // 這是一個(gè) scss 的 map數(shù)據(jù)結(jié)構(gòu),保存默認(rèn)的初始值 $root-vars:( --color-fg-default: #adbac7, --color-fg-muted: #768390, --color-fg-subtle: #545d68, --color-fg-on-emphasis: #cdd9e5, --color-scale-gray-0: #cdd9e5, --color-scale-gray-1: #adbac7, --color-scale-gray-2: #909dab, --color-scale-gray-3: #768390, // ... )
可以注意到,在維護(hù)的變量中,顏色占了絕大部分,而且我們保存的都是顏色的hex格式,并沒有按照rgba的格式,把透明度(opacity)保存下來, 這是為什么? 答案會(huì)在后面揭曉。
接著,維護(hù)完這個(gè)sass:map ,我們編寫一個(gè)工具類 util.scss 來把顏色變量轉(zhuǎn)化為字符串:
// util.scss @use 'sass:color'; @use 'sass:meta'; @function getRgbString($color) { @if (meta.type-of($color) == color) { @return color.red($color) color.green($color) color.blue($color); } @else { @return $color; } }
然后在全局樣式 global.scss 中添加:
// global.scss @use './constants.scss' as C; @use './util.scss' as Util; :root { @each $var, $color in C.$root-vars { #{$var}: Util.getRgbaString($color); } }
這樣我們的那些變量默認(rèn)值字符串就添加進(jìn)了 :root 根元素中:
/* result */ :root{ --color-canvas-default-transparent: 34 39 46; --color-marketing-icon-primary: 108 182 255; --color-marketing-icon-secondary: 49 109 202; --color-diff-blob-addition-num-text: 173 186 199; --color-diff-blob-addition-fg: 173 186 199; --color-diff-blob-addition-num-bg: 87 171 90; --color-diff-blob-addition-line-bg: 70 149 74; --color-diff-blob-addition-word-bg: 70 149 74; --color-diff-blob-deletion-num-text: 173 186 199; ... }
這里注意全局變量中存儲(chǔ)的是字符串,并不是顏色變量本身。
但是有了這些,沒有對(duì)應(yīng)的 class 和 scss 變量,我們還是很不好使用這些變量的,那么怎么進(jìn)行工程化來提升我們的開發(fā)效率呢?接下來重點(diǎn)來了。
2. scss 與 js通信,動(dòng)態(tài)生成 scss 變量與原子化 class
首先編寫 export.scss 用于暴露對(duì)象給 js 使用:
// export.scss @use './constants.scss' as C; @use './util.scss' as Util; :export { @each $var, $color in C.$root-vars { #{$var}: Util.getRgbaString($color); } }
然后利用 webpack sass-loader 中 js 和 scss 的通信方法,就可以生成:
variables.scss (全局scss變量文件)
extendColors.cjs (tailwindcss colors 配置文件)
// generator.js 生成器 import variables from '@/assets/scss/export.scss' // 簡(jiǎn)易的去除前綴 removeColorPrefix(str) { return str.substring(8) } // 此時(shí)的 variables 是一個(gè) object // 那么scss全局變量的模板生成為: scssFilterShadow(str) { return `rgb(var(${str}))` } // scss模板為 ${{ removeColorPrefix(k) }}:{{ scssFilterShadow(k) }}; // 此時(shí) 原子化的 `tailwindcss colors` 文件生成為: jsFilterShadow(str) { return `withOpacityValue('${str}')` } // tailwindcss模板為 '{{ removeColorPrefix(k) }}':{{ jsFilterShadow(k) }},
通過這種方式,我們把生成的結(jié)果寫入 variables.scss 和 extendColors.cjs 文件內(nèi),從而便捷把第一步中維護(hù)的如此之多的 css變量,全部快速方便的轉(zhuǎn)化為同等的 scss變量 和 tailwindcss 配置
3. 全局scss文件變量注入
生成 variables.scss后,我們可以配置一下 sass-loader 來讓其中的變量無需顯式引入,即可在全局生效:
// sass-loader { additionalData: '@use "@/assets/scss/variables.scss" *;', }
這樣我們就可以在任意的 vue <style>, 或者 .scss 文件內(nèi)使用到所有 variables.scss 中聲明的變量了。
4. 原子化的 class 生成
生成 extendColors.cjs 后,我們?cè)诶锩嫣砑?
function withOpacityValue(variable) { return ({ opacityValue }) => { if (opacityValue === undefined) { return `rgb(var(${variable}))` } return `rgb(var(${variable}) / ${opacityValue})` } }
這是為了結(jié)合 jit引擎,來動(dòng)態(tài)的調(diào)整所有顏色的透明度。有了它,我們就能編寫出以下的代碼:
h1{ @apply text-header-text; // 等價(jià)于 // color: rgb(var(--color-header-text)) } h2{ @apply text-header-text/70; // 等價(jià)于 // color: rgb(var(--color-header-text) / 0.7) }
這也是我們要給根元素中的 css變量 賦值為 R G B 格式的原因了!
本質(zhì)上講,是我們?cè)诶迷?css 中 rgb(rgba是rgb的別名) 構(gòu)造方法來創(chuàng)建顏色變量:
/* rgb的函數(shù)Syntax */ rgb(255,255,255) /* white */ rgb(255,255,255,.5) /* white with 50% opacity */ rgb(255 255 255) /* CSS Colors 4 space-separated values */ rgb(255 255 255 / .5); /* white with 50% opacity, using CSS Colors 4 space-separated values */
從上面這段代碼片段中,我們可以看到,列出的 rgb(R G B / A)就是現(xiàn)在使用的方案。
當(dāng)然我們也可以更改上述的 getRgbString 和 withOpacityValue 這2個(gè)方法,把 , 這個(gè)分隔符加入進(jìn)去,再把 / 去除,從而使用它 rgb(R,G,B,A) 這個(gè)構(gòu)造方式。
這樣我們?cè)谑褂脮r(shí)就可以生成出這樣的樣式:
.neutral{ background-color: rgb(var(--color-neutral-muted)); &:hover{ background-color: rgb(var(--color-neutral-muted) / 0.4); } }
是不是非常的靈活?
接下來只要把 extendColors.cjs 導(dǎo)入進(jìn) tailwind.config.js 配置中,就可以自動(dòng)生成 class 和 vscode 的智能提示了:
// tailwind.config.js const extendColors = require('./client/theme/extendColors.cjs') const colors = require('tailwindcss/colors') module.exports = { // ... theme:{ extend:{ colors:{ ...extendColors.colors, } //... }, colors:{ transparent: 'transparent', current: 'currentColor', black: colors.black, white: colors.white, gray: colors.gray, }, // ... } // ... }
這樣,我們只需要把主題變更依賴的變量們,寫進(jìn)各種控件,layout,容器中去,所有的 css 變量就生效了,切換主題就非常的方便。
5. 動(dòng)態(tài)修改根節(jié)點(diǎn)變量
很多場(chǎng)景下我們的應(yīng)用主題,不是從前端維護(hù)的幾套預(yù)設(shè)方案中進(jìn)行選擇,而是由用戶自定義配置,保存在數(shù)據(jù)庫(kù)中,每次請(qǐng)求后端才能獲取到。
這種獲取方式意味著前端這里,只保留一套默認(rèn)的預(yù)設(shè)方案。所以我們通常會(huì)在獲取到后端給的主題數(shù)據(jù)后,動(dòng)態(tài)的修改 css變量 的值。
具體怎么做呢?本質(zhì)上就是調(diào)用 CSSStyleDeclaration.setProperty(),來設(shè)置 document.documentElement 的變量值。
為了讓它更好用,我們可以進(jìn)行封裝,并建立一套瀏覽器本地的緩存機(jī)制,這些在此不再敘述,條條大道通羅馬。
兼容性
注意此方案是放棄 IE 的! (都上 tailwindcss 了),其余瀏覽器兼容良好。
總結(jié)
這種方式,實(shí)際上利用了很多的 css, sass, webpack,tailwindcss 的特性,筆者回過頭來看,發(fā)現(xiàn)這個(gè)方案在實(shí)現(xiàn)后,好用是非常好用的。
變量,原子化class, 公共提取和智能提示一應(yīng)俱全,就是要對(duì)上面一些技術(shù)點(diǎn)有比較充分的理解。
如果您對(duì)此篇文章有建議或者更好的方案,也歡迎聯(lián)系筆者一起探討。
筆者的聯(lián)系方式
附錄
源碼
文來自 Advanced CSS Theming with Custom Properties and Javascript - (https://www.sitepoint.com/css-theming-custom-properties-javascript/)
在關(guān)于CSS主題的本教程中,我們將使用CSS自定義屬性(也稱為CSS變量)來為簡(jiǎn)單的HTML頁(yè)面實(shí)現(xiàn)動(dòng)態(tài)主題。 我們將創(chuàng)建暗色和亮色的示例主題,然后編寫JavaScript在用戶點(diǎn)擊按鈕時(shí)在這兩者之間切換。
就像在典型的編程語(yǔ)言中一樣,變量用于存儲(chǔ)值。 在CSS中,它們通常用于存儲(chǔ)顏色、字體名稱、字體大小、長(zhǎng)度單位等。它們可以在樣式表中的多個(gè)位置重復(fù)使用。 大多數(shù)開發(fā)者都稱呼為“CSS變量”,但官方名稱是“自定義屬性”。
CSS自定義屬性可以修改在整個(gè)樣式表中引用的變量。 以前,只有使用Sass等CSS預(yù)處理器才能實(shí)現(xiàn)這一點(diǎn)。
在創(chuàng)建動(dòng)態(tài)主題示例之前,讓我們先來了解一下自定義屬性的基礎(chǔ)知識(shí)。
自定義屬性是一個(gè)名稱以兩個(gè)連字符( - )開頭的屬性,如--foo。 它們定義了可以使用var()來引用的變量。 讓我們看看下面的例子:
在 :root 選擇器中定義自定義屬性意味著它們可以在全局文檔空間中應(yīng)用于所有元素。 :root 是一個(gè)CSS偽類,它匹配文檔的根元素 - <html>元素。 它類似于html選擇器,但具有更高的特異性。
你可以在文檔中的任何位置訪問 :root 自定義屬性的值:
你也可以預(yù)設(shè)一個(gè)備用值,例如
如果自定義屬性沒有定義的話,備用值將被使用。
在除了:root或html選擇器之外的CSS選擇器內(nèi)定義定義屬性可以使變量用于匹配元素及其子元素。
諸如Sass之類的CSS預(yù)處理器通常用于輔助前端Web開發(fā)。 預(yù)處理器的有用功能中就包括了變量。 但是Sass變量和CSS自定義屬性之間有什么區(qū)別呢?
讓我們開始給項(xiàng)目新建一個(gè)文件夾:
接著,在文件夾中新建一個(gè)index.html:
然后寫入以下代碼:
我們添加了一個(gè)使用<nav>標(biāo)簽的導(dǎo)航欄,一個(gè)頁(yè)腳和一個(gè)用<div>包裹著的按鈕(用于在明暗主題之間切換)還有一些虛擬的Lorem Ipsum文本。
現(xiàn)在讓我們來寫樣式。在同一個(gè)文件的<head>里創(chuàng)建<style>標(biāo)簽并添加以下代碼:
CSS3的HSL(色調(diào),飽和度,亮度)表示法用于定義顏色。 色調(diào)是色環(huán)上的角度,示例所使用的350表示紅色。 通過更改飽和度(顏色百分比)和亮度(百分比),所有頁(yè)面的顏色都會(huì)出現(xiàn)不同的變化。
使用HSL能讓我們只需更改色調(diào)值,即可輕松嘗試主題的不同主色調(diào)。 我們還可以使用CSS變量作為色調(diào)值,并通過更改樣式表中的單個(gè)值或使用JavaScript來切換顏色主題。
以下是這個(gè)頁(yè)面的截圖:
讓我們使用CSS變量來保存頁(yè)面中所有顏色的色調(diào)值。 在<style>標(biāo)簽的頂部添加一個(gè):root選擇器來添加一個(gè)全局CSS變量:
接下來,我們用-main-hue變量來替換掉所有hsl()中寫死的350值。 例如,這是導(dǎo)航選擇器:
現(xiàn)在,如果你要指定除紅色以外的任何顏色,則只需將相應(yīng)的值賦給--main-hue即可。 這是一些例子:
我們定義了紅、藍(lán)、綠3種自定義屬性,然后把--red-hue賦值給--main-hue。
以下是3種不同--main-hue值的頁(yè)面截圖:
CSS的自定義屬性提供了這幾個(gè)好處:
使用JavaScript從一組預(yù)定義值或用戶提交的hue值(它應(yīng)該在0到360之間)中來動(dòng)態(tài)設(shè)置--main-hue的值,我們可以為用戶提供許多彩色的主題。
例如以下的代碼可以將--main-hue的值設(shè)置為240(藍(lán)色):
現(xiàn)在,讓我們來為這個(gè)頁(yè)面提供一個(gè)暗色的主題。 為了更好地控制不同實(shí)體的顏色,我們需要添加更多的變量。
通過頁(yè)面的樣式,我們可以在:root中定義相應(yīng)顏色的自定義屬性后,用變量替換不同選擇器中的所有HSL顏色:
使用適當(dāng)?shù)淖远x屬性名稱。 例如, - nav-bg-color是指導(dǎo)航背景的顏色,而--nav-text-color是指導(dǎo)航前景/文本的顏色。
現(xiàn)在復(fù)制粘貼:root選擇器及其內(nèi)容,然后添加一個(gè)暗色的主題屬性:
如果將具有暗色值的主題屬性添加到<html>元素,此主題就會(huì)被激活。
我們現(xiàn)在可以手動(dòng)地通過降低HSL顏色的亮度值來提供暗色主題,或者我們也可以使用其他技巧,例如invert( )和brightness( )等這些常用的CSS濾鏡來調(diào)整圖像的渲染,也可以與其他任何元素一起使用。
將以下代碼添加到:root [theme ='dark']:
invert( )濾鏡會(huì)反轉(zhuǎn)所選元素中的所有顏色(在例子中為每個(gè)元素)。 可以使用百分比或數(shù)字來指定反轉(zhuǎn)值。 值為100%或1時(shí)將完全反轉(zhuǎn)元素的色調(diào)、飽和度和亮度值。
brightness( )濾鏡會(huì)使元素更亮或更暗。 值為0時(shí)會(huì)出現(xiàn)完全黑暗的元素。
invert( )濾鏡會(huì)使一些元素非常明亮。 可以通過設(shè)置brightness(0.6)來調(diào)低亮度。
不同暗度的暗色主題截圖:
現(xiàn)在,當(dāng)用戶點(diǎn)擊Dark / Light按鈕時(shí),我們來使用JavaScript在暗色和亮色主題之間切換。 在index.html中,在<body>標(biāo)簽的底部添加<script>內(nèi)聯(lián)腳本,然后加入以下代碼:
Document.documentElement指向文檔的根DOM元素 - 即<html>。 此代碼使用.hasAttribute( )方法檢查主題屬性是否存在,如果該屬性不存在則添加暗色值,然后就會(huì)切換到黑暗主題。 否則,它會(huì)刪除該屬性,從而切換到亮色主題。
使用JavaScript來改變CSS自定義屬性
通過使用JavaScript,我們可以訪問自定義屬性并動(dòng)態(tài)更改其值。 在我們的示例中,我們將亮度值寫死了,但它可以被動(dòng)態(tài)更改。 首先,在HTML中dart/light按鈕的旁邊添加滑塊:
滑塊的初始值為1,允許用戶調(diào)到最低0.3。
接下來,在:root[theme='dark']中添加一個(gè)暗度的自定義屬性,初始值為1:
在brightness濾鏡中用此自定義屬性替換掉原先的固定值:
最后,添加以下JavaScript代碼控制滑塊的值來動(dòng)態(tài)地改變--theme-darkness的值:
我們監(jiān)聽滑塊的事件變化,并使用setProperty( )方法相應(yīng)地設(shè)置--theme-darkness的值。
我們還可以將brightness濾鏡應(yīng)用于亮色主題。 在:root選擇器添加--theme-darkness自定義屬性:
然后在同一個(gè)選擇器內(nèi)添加brightness濾鏡:
以下是暗色主題最終結(jié)果的截圖:
還有亮色主題最終結(jié)果的截圖:
在本教程中,我們已經(jīng)了解了如何使用CSS自定義屬性來創(chuàng)建主題并在它們之間動(dòng)態(tài)切換。 我們使用了HSL配色方案,它允許我們指定具有色調(diào)、飽和度和亮度值的顏色以及CSS濾鏡(invert和brightness)以創(chuàng)建亮色主題的暗色版本。
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。