53

CSS 在按钮上做个涟漪效果(Ripple Animation) - CodeSky 代码之空

 5 years ago
source link: https://codesky.me/archives/css-do-a-ripple-animation.wind
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

CSS 在按钮上做个涟漪效果(Ripple Animation)

作为一个 CSS 渣,这次在看到一个 Vue 组件库的按钮里有个点按之后的效果之后跃跃欲试。

效果大概长这样:

2018-08-26 13.20.35.gif

首先先观察了一番,大概得到以下特征:

  1. 以鼠标按下的位置为原点,以某个值为半径进行扩散
  2. 在长宽、以及透明度上,均有渐变

原本是 Vue 实现的,但剥离框架实现,就还得在 JavaScript 上哲学一番,为此,我实现了一个较为简单的效果,这篇文章基本上是逐行总结解读:

HTML 结构:



  1. <button>
  2. <span class="background"></span>
  3. <span class="content">涟漪效果</span>
  4. </button>

勿用说明,这个按钮是由内容和涟漪效果的背景组成的,内容在 Vue 中也就是 <slot> 进来的文本。

之后,大致写一些基本样式,和动画核心代码没有太大关系:



  1. button {
  2. overflow: hidden;
  3. border: 1px solid #000;
  4. padding: 12px;
  5. cursor: pointer;
  6. position: relative;
  7. margin: 10px;
  8. }
  9. .content {
  10. position: relative;
  11. display: inline-block;
  12. }

要实现这个效果,我们主要考虑的就是上述总结的两点,首先,如何以一个地方为中心点,向两边扩散。

为了获取鼠标位置,我们使用的是 event.offsetXevent.offsetY,但是如果光这样对 background 进行绝对定位,达到的效果是以起始点为左上角开始的动画,为了变成中心点,我们自然想到了 transform: translate(-50%, -50%),成功把左上角转成了中心点。

接下来,我们需要确定动画中圆的半径,考虑到 button 通常都是宽 > 长的,所以取宽(button.clientWidth)为半径做圆。

另外,我们要保证鼠标点击在任一按钮区域都可以填充满,所以宽度至少需要为本身的 3 倍。

最终,我们的样式是:



  1. {
  2. left: event.offsetX + 'px',
  3. top: event.offsetY + 'px',
  4. width: button.clientWidth * 3 + 'px',
  5. height: button.clientWidth * 3 + 'px'
  6. }

全部准备完成之后,使用 transition 对我们的动画进行补间:



  1. transition: width 3s ease, height 3s ease, opacity 1s ease;

全部的代码和效果见下方 jsfiddle 的演示:

但是,如果我们使用 CSS Houdini,整个动画的实现将会是非常容易的:



  1. .ripple {
  2. --gradient: linear-gradient(to bottom right, deeppink, orangered);
  3. background: var(--gradient);
  4. }
  5. .ripple.animating {
  6. background: paint(ripple), var(--gradient);
  7. }

效果可见:https://css-houdini.rocks/ripple/


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK