乐趣区

关于前端:一个炫酷的头像悬停效果-2

基于上次翻译的 🔥🔥一个炫酷的头像悬停成果 播种了不少同学的喜爱,原作者近期进行了优化降级。本文将降级后的外围实现过程进行梳理解说,如果没看过第一期的举荐先看看第一期的实现过程。降级后的成果如下图所示。

gif 动画成果如下:

绝对于上次的成果次要减少了背景的变动,减少了默认的旋转动画以及背景花瓣的成果。外围实现技术点如下:

  • 不须要额定的元素,仅应用 <img> 标签
  • 不应用伪元素
  • 应用 future CSS,mask,@property,三角函数和大量的数学函数
  • 应用 Sass 和 CSS 变量优化代码量
  • 小圆的大小和数量可配置

对于实现过程的相干三角函数及 Sass 相干函数不过多解析,有趣味的能够具体理解。

根底变量定义

为了不便前面操作与更改配置,首先定义几个变量不便调整配置和后续代码援用。

背景圆中的小圆数量 $n

$n: 15;

管制小圆半径和主体的尺寸大小:

--r: 50px; 

管制小圆放大比例基数,管制数值在 1.2 和 2 之间:

--f: 2;

主体背景色彩:

--c: #E4844A;

除此之外还通过 @property 定义了 2 个变量,管制旋转的角度及小圆之间的间距。

通过 @property 申明的变量能够定义其语法、继承性和初始值。这样做的益处是能够在文档中明确地申明变量,并指定其用处和限度条件。这种申明形式更适宜须要具体定义的场景,例如自定义属性。

@property --a {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: true;
}
@property --i {
  syntax: "<length>";
  initial-value: 0px;
  inherits: true;
}

背景绘制

背景图形上有多个小圆组成,小圆的数量是可配置的,所以背景的小圆须要基于所配置的数量动静生成,这里须要用到几个 Sass 的函数。

因为小圆的数量 $n 反对配置,所以整个元素的大小会随之影响发生变化。通过设置 aspect-ratio,咱们只须要管制width 的变动即可。宽度的最终值基于小圆的半径和小圆的数量计算得出。

width: calc(var(--r)*(1 + 1/tan(180deg/#{$n})));
aspect-ratio: 1;
border-radius: 50%;

接下来开始绘制从属在大圆下面的小圆。

$m: ();
@for $i from 1 through ($n) {
  $m: append($m, 
       radial-gradient(var(--c) 70%,#0000 72%) no-repeat
        calc(50% + (50% - var(--i,0px))*cos(360deg*#{$i/$n} + var(--a,0deg))) 
        calc(50% + (50% - var(--i,0px))*sin(360deg*#{$i/$n} + var(--a,0deg)))/
        var(--r) var(--r), 
      comma);
 }

首先,咱们定义一个变量 $m,并将其初始化为空。而后应用 @for 循环从 1 到 $n 小圆的数量进行遍历。

在循环外部,应用 Sassappend() 函数将新生成的 radial-gradient 款式追加到 $m 变量中。append() 函数用于在列表类型的变量前面增加一个新的元素,并返回新的列表。

radial-gradient 款式由以下几局部组成:

  • var(--c) 70%:示意突变的色彩和突变的地位,其中色彩应用 CSS 变量 --c
  • #0000 72%:示意突变的完结色彩和完结地位。
  • no-repeat:示意不反复突变。
  • calc(50% + (50% - var(--i,0px))*cos(360deg*#{$i/$n} + var(--a,0deg)))calc(50% + (50% - var(--i,0px))*sin(360deg*#{$i/$n} + var(--a,0deg))):计算突变的圆心地位,其中变量 --i--a是自定义变量,默认值别离为 0px0deg
  • / var(--r) var(--r):示意突变的尺寸,其中尺寸应用 CSS 变量 --r
  • comma:示意多个背景图像之间应用逗号分隔。

循环完结后,变量 $m 将蕴含所有生成的 radial-gradient 款式,能够在后续的款式中应用 $m 来利用这些背景图像。

基于下面的代码持续欠缺,将最终生成的图形绘制到背景中。

--_m: 
  radial-gradient(var(--c) calc(72% - var(--r)/2 - var(--i,0px)),#0000 0),
  #{$m};
-webkit-mask: 
  linear-gradient(#000 0 0) top/100% 50% no-repeat,
  var(--_m);
background: var(--_m);

在下面的代码中,定义了一个新的 CSS 变量 --_m。它的值由两局部组成:

  1. 一个 radial-gradient 背景图像款式,其中突变的色彩和地位应用 var(--c)calc(72% - var(--r)/2 - var(--i,0px)) 示意,这个突变的完结色彩是 #0000,完结地位是 0。这部分内容就是整个背景的核心大圆局部。
  2. 以插值的形式援用之前定义的变量 $m

接着应用 -webkit-mask 属性为元素设置背景遮罩成果。它蕴含两局部:

  1. 一个线性突变 linear-gradient,示意从顶部开始的彩色突变。其中突变的色彩为 #000,突变的起始地位、完结地位别离为 00。设置了 top/100% 50% 示意 linear-gradient 的尺寸是程度方向占满整个宽度,垂直方向占高度的一半。no-repeat 示意不反复突变。
  2. 援用之前定义的变量 --_m,将其作为元素的遮罩图像。

最初应用 background 属性将之前定义的变量 --_m 作为元素的背景图像。这样整个元素的背景就会显示之前生成的 radial-gradient 多个小圆的款式。

动画绘制

元素 hover 后动画细节拆分:

  • 背景圆旋转动画运行速度放慢
  • 大圆从属小圆放大配置比例
  • 核心人物放大

hover前后动画速度不一样是两段不同执行工夫的动画在切换,默认设置的动画如下:

--_a: rotate linear infinite;
animation: 
  var(--_a) 10s,
  var(--_a) 16s reverse;

@keyframes rotate {to{--a:360deg}
}

hover 时将第一段动画设置running,第二段动画设置paused

animation-play-state: running, paused;

下面绘制小圆的时候是基于 --r 半径绘制,咱们还定义了 --f 管制 hover 时小圆放大比例的基数。--i在绘制小圆的时候设置了默认值是 0pxhover 时基于设定的变量进行计算赋值到--i,即可对校园进行放大的动画管制。

--i: calc(var(--r)/var(--f));

对核心人物图像的放大应用如下代码,外围应用了小圆数量 $n,小圆半径 --r 进行计算最终放大的比例。

scale: calc((1 + 1/tan(180deg/#{$n}))/(1 - 2/var(--f) + 1/tan(180deg/#{$n})));

另外还对次要的动画减少了过渡的成果,针对 --iscale的切换减少 0.4s 的过渡工夫,使动画更加丝滑。

transition: --i .4s, scale .4s;

在线源码

https://code.juejin.cn/pen/7269700151160078348

最初

到此整体外围实现的逻辑就完结了,整个实现过程用到了不少 Sass 函数以及 CSS3 相干能力,定义了局部配置项使整个代码更加灵便可控,简洁高效。有趣味的能够本人尝试看看。

看完本文如果感觉有用,记得点个赞反对,珍藏起来说不定哪天就用上啦~

专一前端开发,分享前端相干技术干货,公众号:南城大前端(ID: nanchengfe)

参考

A Fancy Hover Effect For Your Avatar II: css-tip.com/avatar-hover-effect-2/

退出移动版