最近, 我从 Grover 网站 https://getgrover.com/de-en/products/iphone-x-64gb 上发现以一个好玩儿的悬停动画, 也有了些自己的灵感. 这个动画是将鼠标移动到订阅按钮上移动光标会显示相应的彩色渐变. 这个想法很简单, 但是它能使这个按钮脱颖而出, 人们一下子就注意到它了, 增加了点击的概率.
怎样才能达到这个效果, 使我们的网站脱颖而出呢? 其实, 它并不像你想象的那么难!
追踪位置
我们要做的第一件事就是获取到鼠标的位置.
- document.querySelector('.button').onmousemove = (e) => {
- const x = e.pageX - e.target.offsetLeft
- const y = e.pageY - e.target.offsetTop
- e.target.style.setProperty('--x', `${ x }px`)
- e.target.style.setProperty('--y', `${ y }px`)
- }
选择元素, 等待, 直到用户将鼠标移过它;
计算相对于元素的位置;
将坐标存在 CSS 的变量中.
是的, 仅仅 9 行代码就让你能获知用户放置鼠标的位置, 通过这个信息你能达到意想不到的效果, 但是我们还是先来完成 CSS 部分的代码.
动画渐变
我们先将坐标存储在 CSS 变量中, 以便能够随时使用它们.
- .button {
- position: relative;
- appearance: none;
- background: #f72359;
- padding: 1em 2em;
- border: none;
- color: white;
- font-size: 1.2em;
- cursor: pointer;
- outline: none;
- overflow: hidden;
- border-radius: 100px;
- span {
- position: relative;
- }
- &::before {
- --size: 0;
- content: '';
- position: absolute;
- left: var(--x);
- top: var(--y);
- width: var(--size);
- height: var(--size);
- background: radial-gradient(circle closest-side, #4405f7, transparent);
- transform: translate(-50%, -50%);
- transition: width .2s ease, height .2s ease;
- }
- &:hover::before {
- --size: 400px;
- }
- }
用 span 包裹文本, 以避免显示在按钮的上方.
将 width 和 height 初始化为 0px, 当用户悬停在按钮上时, 将其改为 400px. 不要忘了设置这种转换以使其像风一样瞬间出现;
利用坐标追踪鼠标位置;
在 background 属性上应用 radial-gradient, 使用 closest-side circle.Closest-side 能够覆盖整个面.
结果
成功啦! 将其加入到对于的 html 页面, 你炫酷的按钮就可以使用啦!
其他尝试
通过收集鼠标的位置并对其有相应的响应就能实现这么赞的效果. 太棒了, 在这个动手过程中我收获很多乐趣
这是我在名为 basicScroll https://basicscroll.electerious.com 的网站做的其他的类似的动画:
花哨些, 做了个 3D 效果的按钮:
The possibilities are endless. Let us know what you did with it in the comments below 可能的尝试是各种各样的, 让我们从下面的评论中看看你们都做了什么尝试
问与答
为什么要用 width 和 height 代替 transform: scale() 去制造动画效果?
通过调整 width 和 height 值以实现动画效果, 实际上的性能极差, 您应该尽可能尝试用 transform 去实现. 那我为什么仍然坚持呢? 原因就在于当浏览器在加速图层中呈现元素时 (即转换), 如果按钮具有非矩形边缘时, 该图层可能会出现意想不到的 bug.
编者有话说: 诚然, 有很多方式去使用 transform, 但是一些浏览器并不喜欢它. 不通过 transform 去实现转换功能也许是个不错的解决问题的方法. 这儿还有名为 解决 Safari 的方法 https://gist.github.com/ayamflow/b602ab436ac9f05660d9c15190f4fd7b 的网站也许可以解决这个问题.
为什么改变 top 和 left 属性的值而不使用
- transform: translate()
- ?
参见上面的解释
我能在推特上关注你吗?
当然可以呀~. https://twitter.com/electerious
来源: https://juejin.im/entry/5ae529366fb9a07aa43bf914