《好久没做》,龙年限定文本电影特效(上)

大家好,这里是大家的林语冰。坚持阅读,自律打卡,每天一次,进步一点

春节期间,我有一个朋友在狂追韩剧《Long time no sex》(好久没做),这部剧主要以无性婚姻和婚内出轨等社会现象作为核心创作背景,混入了若干悬疑、犯罪和伦理情节。《好久没做》虽然没有中年老师出轨未成年中二学生那么科幻,也没有老父亲出轨准儿媳全家当街互殴那么激情,但这部人间真实喜剧精准阐释了"艺术源于生活"的永恒真理,目前豆瓣狂砍 8.5 分,总之就是十分推荐。

春天到了,正是欣赏《好久没做》的最佳时机。虽然但是,语冰在沉浸式观看时,被该剧片头的一个"文本电影"特效惊艳到了!

如你所见,在剧名简写"LTNS"的文本中,插入了视频元素,吸睛的创意营造了炫酷的视差效果。

地球人都知道,一切可诉诸 TS 赋能的 App,终将诉诸 ES6 赋能。于是乎,我决定尝试只使用 Web 技术栈,神还原龙年限定版的"生龙活虎"同款文本电影特效,最终成果如下:

考虑到原生 CSS 近几年日新月异,颇有取代 SCSS/LESS 等预处理器的趋势,以及海外样式的多极化方案,我会伪科普新人友好的 CSS 原味版,也会共享语冰最近正在练习的 UnoCSS 重构版。

本期共享的是:

  1. 如何诉诸原生 CSS 实现"生龙活虎"的文本电影特效
  2. 如何诉诸 UnoCSS 重构优化

文本电影特效

首先,我们来设计 HTML 的基本骨架结构:

  • <main> 作为主区域容器
  • <video> 作为电影资源
  • <h1> 作为文本标题

语义化结构如下:

html 复制代码
<main>
  <video autoplay muted loop>
    <source src="/dragon.mp4" type="video/mp4" />
  </video>
  <h1 class="txt-video">生龙活虎</h1>
</main>

这里 <video> 的三个属性都是布尔属性,用于控制视频播放设置:

  • autoplay 控制视频自动播放
  • muted 控制音频静音或外放
  • loop 控制视频自动播放

我们需要搞一个高清无码的小视频作为静态资源,举个栗子,多人跨年活动"潮汕舞龙",视频如下:

大家可以按需集成自己喜欢的岛国动作片,比如《好久没做》等。

然后我们开始编写样式,我们定义一个绝对定位的全屏容器,样式如下:

css 复制代码
main {
  /* CSS 变量,方便后面复用 */
  --main-h: 100vh;
  position: absolute;
  height: var(--main-h);
  width: 100vw;
}

接着,我们需要让视频保持宽高比填充容器,作为标题的"动态内容",样式如下:

css 复制代码
main {
  /* main 样式如上 */

  & video {
    /* 原生 CSS 嵌套语法 */
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 100%;
    object-fit: cover;
  }
}

这里的 object-fit 属性用于指定 <video> 的内容填充容器的方式,object-fit: cover; 表示内容保持原来的宽高比填充,效果如下:

最后,我们添加 .txt-video 类来设置 <h1> 的文本,样式如下:

css 复制代码
main {
  /* main 和 video 样式如上 */
  .txt-video {
    font-size: 20rem;
    font-weight: bolder;
    text-align: center;
    color: black;
    background: white;
    mix-blend-mode: screen;
  }
}

我们尽量将标题字体设置得又粗又大,这样文本中的电影视差才更加明显,大家大胆复制、小心粘贴、按需微调即可。

这里的 mix-blend-mode 属性用于指定元素内容和元素的直系父元素内容和背景的混合模式。这样,我们的特效就初具雏形,但是还有 bug......

如你所见,有一部分视频内容露出来了,没有被完全覆盖。这可以使用 flex 布局或绝对定位等方案来修复,但是经过语冰亲自测评,这里使用行高最具性价比,修复如下:

diff 复制代码
.txt-video {
  font-size: 20rem;
  font-weight: bolder;
  text-align: center;
+ line-height: var(--main-h);
  color: black;
  background: white;
  mix-blend-mode: screen;
}

这里的 line-height 行高和容器等高,主要有两大作用:

  1. 可以使标题垂直居中;
  2. 可以让标题垂直铺满容器,覆盖绝对定位露出来的视频背景。

CSS 原味版最终的完整代码如下:

html 复制代码
<template>
  <main>
    <video autoplay muted loop>
      <source src="/dragon.mp4" type="video/mp4" />
    </video>
    <h1 class="txt-video">生龙活虎</h1>
  </main>
</template>

<style scoped>
  main {
    --main-h: 100vh;
    position: absolute;
    height: var(--main-h);
    width: 100vw;

    & video {
      position: absolute;
      top: 0;
      left: 0;
      height: 100%;
      width: 100%;
      object-fit: cover;
    }

    .txt-video {
      font-size: 20rem;
      font-weight: bolder;
      text-align: center;
      line-height: var(--main-h);
      color: black;
      background: white;
      mix-blend-mode: screen;
    }
  }
</style>

UnoCSS 重构优化

前文提及,语冰最近正好在练习 UnoCSS,UnoCSS 是"Vitest 之父" Antfu 的又一力作,一个即时按需的原子 CSS 引擎。简而言之,我们可以通过 UnoCSS DIY 自己的 CSS 架构,实现和 Tailwind CSS 等人气爆棚的 CSS 方案"图灵等价"的功能。

我们通过一个直观的"对照试验"来搭讪一下 UnoCSS,举个栗子,前文 <main> 的样式如下:

css 复制代码
/* CSS 原味版 */
main {
  --main-h: 100vh;
  position: absolute;
  height: var(--main-h);
  width: 100vw;
}

/* UnoCSS 重构版 */
main {
  /* 原生 CSS 变量 + Uno 应用指令  */
  --uno:absolute h-100vh w-100vh;
}

如你所见,UnoCSS 一行代码就能搞定,而且机智如你会发现 UnoCSS 有原生 CSS 似曾相识的既视感,顾名思义,一目了然。

这其实类似 Tailwind "原子类"方案,而且基本没有入门成本。但 UnoCSS 不像 Tailwind 那么我行我素,而是无拘无束的 CSS 引擎,这意味着,我们可以按需 DIY 自己的原子类,想怎么写就怎么写。

举个栗子,上述例子中绝对定位的 absolute,我们觉得还是太长了,那我们可以自定义一个"图灵等价"的 ab 原子类,UnoCSS 默认会提供内置的原子类,但不会限制我们的自定义行为,这对于大型项目的样式架构十分友好。

既然是原子"类",那自然是可以作为"类"来使用,UnoCSS 的原子类可以直接写在 HTML 模板里,代码如下:

html 复制代码
<main class="absolute h-100vh w-100vh"></main>

如你所见,UnoCSS 不仅给力,而且十分灵活。在面向对象编程中,类的作用之一是封装,而在 CSS 的原子类中,保留了单一属性细粒度的样式封装,方便到处复用。

最后,我们精简代码重构"生龙活虎"的文本电影特效,代码如下:

css 复制代码
main {
  --uno: absolute h-screen w-screen;

  & video {
    --uno: absolute top-0 left-0 h-full w-full object-cover;
  }

  .txt-video {
    --uno: font-size-20rem font-black text-center line-height-100vh color-black
      bg-white mix-blend-screen;
  }
}

如你所见,核心的样式代码有且仅有 3 行,都是由若干可读且可复用的原子类自由组合而成。

高潮总结

不管是原生 CSS,还是 SCSS/LESS,或者是诸如 UnoCSS 等其他样式方案,能实现功能的方案就是好方案。大家可以根据自己精通的样式方案刻意练习,重构"生龙活虎"文本电影特效。

另外,语冰在重构文本电影特效时,发现视频的性能并不乐观,而且颜色定义十分受限。

所以我们其实可以尝试使用 gif 动图,或者使用静态图片、但是让静态图片"动起来"的方式"曲线救国"。我会在下一篇博客中重点共享更多有趣又好玩的奇技淫巧,我们日后再说。

本期话题是 ------ 你目前最常用的 CSS 样式方案是什么,以及为什么?

欢迎在本文下方群聊自由言论,文明共享。谢谢大家的点赞,掰掰~

《前端 9 点半》每日更新,坚持阅读,自律打卡,每天一次,进步一点

相关推荐
我要让全世界知道我很低调4 分钟前
记一次 Vite 下的白屏优化
前端·css
threelab4 分钟前
three案例 Three.js波纹效果演示
开发语言·javascript·ecmascript
1undefined26 分钟前
element中的Table改造成虚拟列表,并封装成hooks
前端·javascript·vue.js
蓝倾41 分钟前
淘宝批量获取商品SKU实战案例
前端·后端·api
comelong1 小时前
Docker容器启动postgres端口映射失败问题
前端
花海如潮淹1 小时前
硬件产品研发管理工具实战指南
前端·python
用户3802258598241 小时前
vue3源码解析:依赖收集
前端·vue.js
用户7579419949701 小时前
基于JavaScript的简易Git
javascript
WaiterL1 小时前
一文读懂 MCP 与 Agent
前端·人工智能·cursor
gzzeason1 小时前
使用Vite创建React初始化项目
前端·javascript·react.js