整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

16个超牛逼的HTML5和JavaScript特效

用说, Flash的效果大家都清楚。实际上,HTML5和JavaScript拥有很多新属性,可以用它们来替代Flash。W3Cschool精选16个超牛逼的HTML5和JavaScript特效,看了这些特效,未来的Web发展前途无量。

1.特效:FlowerPower

创作者使用花朵作为画刷,以贝兹曲线方式绘图。

2.特效:Breathing Galaxies

动态变换直径及颜色,可通过鼠标或键盘产生新形状,这个效果不错!

3.特效:Noise Field

移动鼠标可改变粒子运动,点击可随机生成不同粒子效果。

4.特效:HTML5 Canvas粒子效果文字动画特效

W3Cschool利用HTML5,制造出了粒子效果文字动画特效。只要你输入框中输入想要展示的文字,回车后即可在canvas上绘制出粒子效果的文字动画,相当酷的动画效果。

5.特效:Swirling Tentacles

三维脉冲效果,沿着脉冲线有运动的颜色渐变模块。

6.特效:Keylight

双击生成两个以后的键即可发出声音,移动键的位置可产生不同的声音效果。W3Cschool上面有很多这样的教程,有兴趣可以去看一下!

7.特效:Rotating Spiral

旋转的螺旋效果,单击可以控制开始和停止旋转,是不是觉得高大上?

8.Blob

拖动水滴有重力效果,双击可以分离,小水滴碰到大水滴会合并。

9.Trail

彩色颗粒跟随鼠标运动效果,带尾巴淡出效果。

10.Graph Layout

一种交互的力向图布局效果,刷新三观。

11.Typographic Effects

使用HTML5 Canvas实现的文本特性,效果超过Flash。

12.Crazy Tentacles

移动鼠标可以进行涂鸦,点击鼠标可以清除画布,看着确实疯狂。

13.Nebula

吸引眼球的粒子系统,目的是测试WebGL性能,如果滑动鼠标,可以产生绚丽效果。

14.WebGL Globe

WebGL Globe 是一个开放的地理数据可视化平台,我们鼓励你复制代码,添加自己的数据,创建自己的应用。

15.Particle Playground

用鼠标和粒子进行交互,能发现不一样的精彩。

16.Surface

使用WebGL实现的水面特效实验,可放入一张照片,使用鼠标触动水面会有奇特效果。

上面的HTML5和JavaScript特效,简直赶超Flash。W3Cschool上面有很多用户留言称HTML5和JavaScriptit将替代Flash,不过对于这种说法,也不知道怎么去评判。毕竟这些用户说的也是很有道理,你认为JavaScriptit会替代Flash吗?很想知道你的答案!

公众号:w3c技术教程

提供专业的web技术教程、手册、工具。

态调整web系统主题? 看这一篇就够了

一种构建灵活的系统页面主题方案

前置技术点

阅读此篇文章前,最好有下列知识

  1. css 基础知识

  2. dart-sass 预处理器编程

  3. webpack 以及 postcss

  4. tailwindcss 含有 jitv2/v3

前言

我们在日常生活中,不论是访问网站,手机App,还是小程序,时常会用到 切换主题 这个功能。它能够为用户提供一定的自定义显示界面的能力,同时手机系统级别的主题也能够更换,比如 light(明亮模式)dark(黑暗模式)

那么如何让我们编写的应用,在改动不大的情况下,能够快速的适配多个主题呢?

这就需要设计一个方案了。

方案设计

方案参考

这里我们以程序员们最熟悉的 Github 为例,它的主题切换是这样做的:

它在 根元素 那预设了几套 css 变量值, 然后通过 js 去动态修改 html 根元素上的 data-color-modedata-dark-theme 这些属性的值,从而让不同的 css 选择器选中这个根元素,并以此来动态的切换 :root 中的 css 变量的值。

同时这些变量都被广泛的使用在各种的 原子化的 class@apply 中,一旦变量一换,所有使用到这些class的控件和布局都收到影响,自然整个主题就改变了。

1. 提炼css变量

首先我们第一步要做的就是提炼css变量,这些主要由设计师提供。

这里以颜色为例,主要包含 同个颜色的多态控件各个状态的颜色提示警告错误字体中,标题,副标题,正文,提示的颜色 等等。当然像字体大小,阴影这类也是同样的。

这方面就不细说了,在提取到变量之后我们就可以开始进行命名工作:

// constants.scss // 这是一个 scss 的 map数据结构,保存默认的初始值 $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,   // ... )

可以注意到,在维护的变量中,颜色占了绝大部分,而且我们保存的都是颜色的hex格式,并没有按照rgba的格式,把透明度(opacity)保存下来, 这是为什么? 答案会在后面揭晓。

接着,维护完这个sass:map ,我们编写一个工具类 util.scss 来把颜色变量转化为字符串:

// 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);   } }

这样我们的那些变量默认值字符串就添加进了 :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;   ... }

这里注意全局变量中存储的是字符串,并不是颜色变量本身。

但是有了这些,没有对应的 classscss 变量,我们还是很不好使用这些变量的,那么怎么进行工程化来提升我们的开发效率呢?接下来重点来了。

2. scss 与 js通信,动态生成 scss 变量与原子化 class

首先编写 export.scss 用于暴露对象给 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-loaderjsscss 的通信方法,就可以生成:

  • variables.scss (全局scss变量文件)

  • extendColors.cjs (tailwindcss colors 配置文件)

// generator.js 生成器 import variables from '@/assets/scss/export.scss' // 简易的去除前缀 removeColorPrefix(str) {   return str.substring(8) } // 此时的 variables 是一个 object // 那么scss全局变量的模板生成为: scssFilterShadow(str) {   return `rgb(var(${str}))` } // scss模板为 ${{ removeColorPrefix(k) }}:{{ scssFilterShadow(k) }}; // 此时 原子化的 `tailwindcss colors` 文件生成为: jsFilterShadow(str) {   return `withOpacityValue('${str}')` } // tailwindcss模板为 '{{ removeColorPrefix(k) }}':{{ jsFilterShadow(k) }},

通过这种方式,我们把生成的结果写入 variables.scssextendColors.cjs 文件内,从而便捷把第一步中维护的如此之多的 css变量,全部快速方便的转化为同等的 scss变量tailwindcss 配置

3. 全局scss文件变量注入

生成 variables.scss后,我们可以配置一下 sass-loader 来让其中的变量无需显式引入,即可在全局生效:

// sass-loader {   additionalData: '@use "@/assets/scss/variables.scss"  *;', }

这样我们就可以在任意的 vue <style>, 或者 .scss 文件内使用到所有 variables.scss 中声明的变量了。

4. 原子化的 class 生成

生成 extendColors.cjs 后,我们在里面添加:

function withOpacityValue(variable) {   return ({ opacityValue }) => {     if (opacityValue === undefined) {       return `rgb(var(${variable}))`     }     return `rgb(var(${variable}) / ${opacityValue})`   } }

这是为了结合 jit引擎,来动态的调整所有颜色的透明度。有了它,我们就能编写出以下的代码:

h1{   @apply text-header-text;    // 等价于   // color: rgb(var(--color-header-text)) } h2{   @apply text-header-text/70;   // 等价于   // color: rgb(var(--color-header-text) / 0.7) }

这也是我们要给根元素中的 css变量 赋值为 R G B 格式的原因了!

本质上讲,是我们在利用原生 cssrgb(rgbargb的别名) 构造方法来创建颜色变量:

/* rgb的函数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)就是现在使用的方案。

当然我们也可以更改上述的 getRgbStringwithOpacityValue 这2个方法,把 , 这个分隔符加入进去,再把 / 去除,从而使用它 rgb(R,G,B,A) 这个构造方式。

这样我们在使用时就可以生成出这样的样式:

.neutral{   background-color: rgb(var(--color-neutral-muted));   &:hover{     background-color: rgb(var(--color-neutral-muted) / 0.4);   } }

是不是非常的灵活?

接下来只要把 extendColors.cjs 导入进 tailwind.config.js 配置中,就可以自动生成 classvscode 的智能提示了:

// 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,     },     // ...   }   // ...  }

这样,我们只需要把主题变更依赖的变量们,写进各种控件,layout,容器中去,所有的 css 变量就生效了,切换主题就非常的方便。

5. 动态修改根节点变量

很多场景下我们的应用主题,不是从前端维护的几套预设方案中进行选择,而是由用户自定义配置,保存在数据库中,每次请求后端才能获取到。

这种获取方式意味着前端这里,只保留一套默认的预设方案。所以我们通常会在获取到后端给的主题数据后,动态的修改 css变量 的值。

具体怎么做呢?本质上就是调用 CSSStyleDeclaration.setProperty(),来设置 document.documentElement 的变量值。

为了让它更好用,我们可以进行封装,并建立一套浏览器本地的缓存机制,这些在此不再叙述,条条大道通罗马。

兼容性

注意此方案是放弃 IE 的! (都上 tailwindcss 了),其余浏览器兼容良好。

总结

这种方式,实际上利用了很多的 css, sass, webpack,tailwindcss 的特性,笔者回过头来看,发现这个方案在实现后,好用是非常好用的。

变量,原子化class, 公共提取和智能提示一应俱全,就是要对上面一些技术点有比较充分的理解。

如果您对此篇文章有建议或者更好的方案,也欢迎联系笔者一起探讨。

笔者的联系方式

附录

源码

文来自 Advanced CSS Theming with Custom Properties and Javascript - (https://www.sitepoint.com/css-theming-custom-properties-javascript/)

在关于CSS主题的本教程中,我们将使用CSS自定义属性(也称为CSS变量)来为简单的HTML页面实现动态主题。 我们将创建暗色和亮色的示例主题,然后编写JavaScript在用户点击按钮时在这两者之间切换。

就像在典型的编程语言中一样,变量用于存储值。 在CSS中,它们通常用于存储颜色、字体名称、字体大小、长度单位等。它们可以在样式表中的多个位置重复使用。 大多数开发者都称呼为“CSS变量”,但官方名称是“自定义属性”。

CSS自定义属性可以修改在整个样式表中引用的变量。 以前,只有使用Sass等CSS预处理器才能实现这一点。

理解 :root 和 var()

在创建动态主题示例之前,让我们先来了解一下自定义属性的基础知识。

自定义属性是一个名称以两个连字符( - )开头的属性,如--foo。 它们定义了可以使用var()来引用的变量。 让我们看看下面的例子:

在 :root 选择器中定义自定义属性意味着它们可以在全局文档空间中应用于所有元素。 :root 是一个CSS伪类,它匹配文档的根元素 - <html>元素。 它类似于html选择器,但具有更高的特异性。

你可以在文档中的任何位置访问 :root 自定义属性的值:

你也可以预设一个备用值,例如

如果自定义属性没有定义的话,备用值将被使用。

在除了:root或html选择器之外的CSS选择器内定义定义属性可以使变量用于匹配元素及其子元素。

CSS自定义属性 VS 预处理器变量

诸如Sass之类的CSS预处理器通常用于辅助前端Web开发。 预处理器的有用功能中就包括了变量。 但是Sass变量和CSS自定义属性之间有什么区别呢?

  • CSS自定义属性在现代浏览器中能原生地被解析。 预处理器变量则需要编译进标准CSS文件里,并且所有变量都将转换为值。
  • 自定义属性能被JavaScript访问和修改。 预处理器变量编译一次之后,只有它们的最终值在客户端上使用。

写一个简单的HTML页面

让我们开始给项目新建一个文件夹:

接着,在文件夹中新建一个index.html:

然后写入以下代码:

我们添加了一个使用<nav>标签的导航栏,一个页脚和一个用<div>包裹着的按钮(用于在明暗主题之间切换)还有一些虚拟的Lorem Ipsum文本。

给HTML页面添加基本的CSS样式

现在让我们来写样式。在同一个文件的<head>里创建<style>标签并添加以下代码:

CSS3的HSL(色调,饱和度,亮度)表示法用于定义颜色。 色调是色环上的角度,示例所使用的350表示红色。 通过更改饱和度(颜色百分比)和亮度(百分比),所有页面的颜色都会出现不同的变化。

使用HSL能让我们只需更改色调值,即可轻松尝试主题的不同主色调。 我们还可以使用CSS变量作为色调值,并通过更改样式表中的单个值或使用JavaScript来切换颜色主题。

以下是这个页面的截图:

让我们使用CSS变量来保存页面中所有颜色的色调值。 在<style>标签的顶部添加一个:root选择器来添加一个全局CSS变量:

接下来,我们用-main-hue变量来替换掉所有hsl()中写死的350值。 例如,这是导航选择器:

现在,如果你要指定除红色以外的任何颜色,则只需将相应的值赋给--main-hue即可。 这是一些例子:

我们定义了红、蓝、绿3种自定义属性,然后把--red-hue赋值给--main-hue。

以下是3种不同--main-hue值的页面截图:

CSS的自定义属性提供了这几个好处:

  • 可以在单独一个地方定义值。
  • 可以适当地命名该值有助于将来维护。
  • 可以使用JavaScript动态更改该值。 例如, - main-hue可以被设置为0到360之间的任何值。

使用JavaScript从一组预定义值或用户提交的hue值(它应该在0到360之间)中来动态设置--main-hue的值,我们可以为用户提供许多彩色的主题。

例如以下的代码可以将--main-hue的值设置为240(蓝色):

添加一个CSS暗色主题

现在,让我们来为这个页面提供一个暗色的主题。 为了更好地控制不同实体的颜色,我们需要添加更多的变量。

通过页面的样式,我们可以在:root中定义相应颜色的自定义属性后,用变量替换不同选择器中的所有HSL颜色:

使用适当的自定义属性名称。 例如, - nav-bg-color是指导航背景的颜色,而--nav-text-color是指导航前景/文本的颜色。

现在复制粘贴:root选择器及其内容,然后添加一个暗色的主题属性:

如果将具有暗色值的主题属性添加到<html>元素,此主题就会被激活。

我们现在可以手动地通过降低HSL颜色的亮度值来提供暗色主题,或者我们也可以使用其他技巧,例如invert( )和brightness( )等这些常用的CSS滤镜来调整图像的渲染,也可以与其他任何元素一起使用。

将以下代码添加到:root [theme ='dark']:

invert( )滤镜会反转所选元素中的所有颜色(在例子中为每个元素)。 可以使用百分比或数字来指定反转值。 值为100%或1时将完全反转元素的色调、饱和度和亮度值。

brightness( )滤镜会使元素更亮或更暗。 值为0时会出现完全黑暗的元素。

invert( )滤镜会使一些元素非常明亮。 可以通过设置brightness(0.6)来调低亮度。

不同暗度的暗色主题截图:

使用JavaScript来切换主题

现在,当用户点击Dark / Light按钮时,我们来使用JavaScript在暗色和亮色主题之间切换。 在index.html中,在<body>标签的底部添加<script>内联脚本,然后加入以下代码:

Document.documentElement指向文档的根DOM元素 - 即<html>。 此代码使用.hasAttribute( )方法检查主题属性是否存在,如果该属性不存在则添加暗色值,然后就会切换到黑暗主题。 否则,它会删除该属性,从而切换到亮色主题。

使用JavaScript来改变CSS自定义属性

通过使用JavaScript,我们可以访问自定义属性并动态更改其值。 在我们的示例中,我们将亮度值写死了,但它可以被动态更改。 首先,在HTML中dart/light按钮的旁边添加滑块:

滑块的初始值为1,允许用户调到最低0.3。

接下来,在:root[theme='dark']中添加一个暗度的自定义属性,初始值为1:

在brightness滤镜中用此自定义属性替换掉原先的固定值:

最后,添加以下JavaScript代码控制滑块的值来动态地改变--theme-darkness的值:

我们监听滑块的事件变化,并使用setProperty( )方法相应地设置--theme-darkness的值。

我们还可以将brightness滤镜应用于亮色主题。 在:root选择器添加--theme-darkness自定义属性:

然后在同一个选择器内添加brightness滤镜:

以下是暗色主题最终结果的截图:

还有亮色主题最终结果的截图:

结语

在本教程中,我们已经了解了如何使用CSS自定义属性来创建主题并在它们之间动态切换。 我们使用了HSL配色方案,它允许我们指定具有色调、饱和度和亮度值的颜色以及CSS滤镜(invert和brightness)以创建亮色主题的暗色版本。