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

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

春节期间,我有一个朋友在狂追韩剧《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 点半》每日更新,坚持阅读,自律打卡,每天一次,进步一点

相关推荐
理想不理想v21 分钟前
vue经典前端面试题
前端·javascript·vue.js
不收藏找不到我22 分钟前
浏览器交互事件汇总
前端·交互
小阮的学习笔记35 分钟前
Vue3中使用LogicFlow实现简单流程图
javascript·vue.js·流程图
YBN娜36 分钟前
Vue实现登录功能
前端·javascript·vue.js
阳光开朗大男孩 = ̄ω ̄=36 分钟前
CSS——选择器、PxCook软件、盒子模型
前端·javascript·css
minDuck40 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!1 小时前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。1 小时前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax
花花鱼1 小时前
vue3 基于element-plus进行的一个可拖动改变导航与内容区域大小的简单方法
前端·javascript·elementui
k09331 小时前
sourceTree回滚版本到某次提交
开发语言·前端·javascript