按钮点击效果(水波纹)

按钮点击效果(水波纹)

近来看到个不错的按钮点击效果,当点击时产生一次水波涟漪效果,挺好玩的,于是简单的实现了下(没考虑低版本浏览器兼容问题)

先看看效果吧,如下图(录制gif软件有点渣,看起来卡卡的…)

按钮点击效果(水波纹)

这种效果可以由元素内嵌套canves实现,也可以由css3实现。

Canves实现

网上摘了一份canves实现的代码,略微去掉了些重复定义的样式并且给出js注释,代码如下

html代码

按钮点击效果(水波纹)
按钮点击效果(水波纹)

<a class="btn color-1 material-design" data-color="#2f5398">Press me!</a>

View Code

css代码

按钮点击效果(水波纹)
按钮点击效果(水波纹)

* {
    
  box-sizing: border-box;
  outline: none;
}
body {
    
  font-family: 'Open Sans';
  font-size: 100%;
  font-weight: 300;
  line-height: 1.5em;
  text-align: center;
}
.btn {
    
  border: none;
  display: inline-block;
  color: white;
  overflow: hidden;
  margin: 1rem;
  padding: 0;
  width: 150px;
  height: 40px;
  text-align: center;
  line-height: 40px;
  border-radius: 5px;
}
.btn.color-1 {
    
  background-color: #426fc5;
}
.btn-border.color-1 {
    
  background-color: transparent;
  border: 2px solid #426fc5;
  color: #426fc5;
}
.material-design {
    
  position: relative;
}
.material-design canvas {
    
  opacity: 0.25;
  position: absolute;
  top: 0;
  left: 0;
}
.container {
    
  align-content: center;
  align-items: flex-start;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  margin: 0 auto;
  max-width: 46rem;
}

View Code

js代码

按钮点击效果(水波纹)
按钮点击效果(水波纹)

var canvas = {},
    centerX = 0,
    centerY = 0,
    color = '',
    containers = document.getElementsByClassName('material-design')
    context = {},
    element = {},
    radius = 0,
    // 根据callback生成requestAnimationFrame动画
    requestAnimFrame = function () {
      return (
        window.requestAnimationFrame       || 
        window.mozRequestAnimationFrame    || 
        window.oRequestAnimationFrame      || 
        window.msRequestAnimationFrame     || 
        function (callback) {
          window.setTimeout(callback, 1000 / 60);
        }
      );
    } (),
    // 为每个指定元素生成canves
    init = function () {
      containers = Array.prototype.slice.call(containers);
      for (var i = 0; i < containers.length; i += 1) {
        canvas = document.createElement('canvas');
        canvas.addEventListener('click', press, false);
        containers[i].appendChild(canvas);
        canvas.style.width ='100%';
        canvas.style.height='100%';
        canvas.width  = canvas.offsetWidth;
        canvas.height = canvas.offsetHeight;
      }
    },
    // 点击并且获取需要的数据,如点击坐标、元素大小、颜色
    press = function (event) {
      color = event.toElement.parentElement.dataset.color;
      element = event.toElement;
      context = element.getContext('2d');
      radius = 0;
      centerX = event.offsetX;
      centerY = event.offsetY;
      context.clearRect(0, 0, element.width, element.height);
      draw();
    },
    // 绘制圆形,并且执行动画
    draw = function () {
      context.beginPath();
      context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
      context.fillStyle = color;
      context.fill();
      radius += 2;
      // 通过判断半径小于元素宽度,不断绘制 radius += 2 的圆形
      if (radius < element.width) {
        requestAnimFrame(draw);
      }
    };

init();

View Code

CSS3实现

接下来就是纯手打的代码了…觉得还是css3实现的方便些,可能是css写习惯了…

html代码

<a class="waves ts-btn">Press me!</a>

css代码

.waves{
   
    position:relative;
    cursor:pointer;
    display:inline-block;
    overflow:hidden;
    text-align: center;
    -webkit-tap-highlight-color:transparent;
    z-index:1;
}
.waves .waves-animation{
   
    position:absolute;
    border-radius:50%;
    width:25px;
    height:25px;
    opacity:0;
    background:rgba(255,255,255,0.3);
    transition:all 0.7s ease-out;
    transition-property:transform, opacity, -webkit-transform;
    -webkit-transform:scale(0);
    transform:scale(0);
    pointer-events:none
}
.ts-btn{
   
    width: 200px;
    height: 56px;
    line-height: 56px;
    background: #f57035;
    color: #fff;
    border-radius: 5px;
}

js代码

    document.addEventListener('DOMContentLoaded',function(){

      var duration = 750;

      // 样式string拼凑
      var forStyle = function(position){
        var cssStr = '';
        for( var key in position){
          if(position.hasOwnProperty(key)) cssStr += key+':'+position[key]+';';
        };
        return cssStr;
      }

      // 获取鼠标点击位置
      var forRect = function(target){
        var position = {
          top:0,
          left:0
        }, ele = document.documentElement;
        'undefined' != typeof target.getBoundingClientRect && (position = target.getBoundingClientRect());
        return {
            top: position.top + window.pageYOffset - ele.clientTop,
            left: position.left + window.pageXOffset - ele.clientLeft
        }
      }

      var show = function(event){
        var pDiv = event.target,
          cDiv = document.createElement('div');
        pDiv.appendChild(cDiv);
        var rectObj = forRect(pDiv),
          _height = event.pageY - rectObj.top,
          _left = event.pageX - rectObj.left,
          _scale = 'scale(' + pDiv.clientWidth / 100 * 10 + ')';
        var position = {
          top: _height+'px',
          left: _left+'px'
        };
        cDiv.className = cDiv.className + " waves-animation",
        cDiv.setAttribute("style", forStyle(position)),
        position["-webkit-transform"] = _scale,
        position["-moz-transform"] = _scale,
        position["-ms-transform"] = _scale,
        position["-o-transform"] = _scale,
        position.transform = _scale,
        position.opacity = "1",
        position["-webkit-transition-duration"] = duration + "ms",
        position["-moz-transition-duration"] = duration + "ms",
        position["-o-transition-duration"] = duration + "ms",
        position["transition-duration"] = duration + "ms",
        position["-webkit-transition-timing-function"] = "cubic-bezier(0.250, 0.460, 0.450, 0.940)",
        position["-moz-transition-timing-function"] = "cubic-bezier(0.250, 0.460, 0.450, 0.940)",
        position["-o-transition-timing-function"] = "cubic-bezier(0.250, 0.460, 0.450, 0.940)",
        position["transition-timing-function"] = "cubic-bezier(0.250, 0.460, 0.450, 0.940)",
        cDiv.setAttribute("style", forStyle(position));
        var finishStyle = {
          opacity: 0,
          "-webkit-transition-duration": duration + "ms",
          "-moz-transition-duration": duration + "ms",
          "-o-transition-duration": duration + "ms",
          "transition-duration": duration + "ms",
          "-webkit-transform" : _scale,
          "-moz-transform" : _scale,
          "-ms-transform" : _scale,
          "-o-transform" : _scale,
          top: _height + "px",
          left: _left + "px",
        };
        setTimeout(function(){
          cDiv.setAttribute("style", forStyle(finishStyle));
          setTimeout(function(){
            pDiv.removeChild(cDiv);
          },duration);
        },100)
      }
      document.querySelector('.waves').addEventListener('click',function(e){
        show(e);
      },!1);
    },!1);

就这些,原理也简单,获取点击位置 >  添加样式   顺便,中秋快乐~

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/108879.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • tomcat修改http长度限制_解决浏览器与服务器请求url长度限制[通俗易懂]

    tomcat修改http长度限制_解决浏览器与服务器请求url长度限制[通俗易懂]一、前言Http中get与post本身是没有受到长度限制的,受到限制是浏览器与服务器对url长度限制。具体说明请阅读我的零一篇文章《关于HTTPGET/POST请求参数长度最大值的一个理解误区》。二、概述1、服务器限制我目前使用的服务器一般是tomcat+nginx,它们都是通过控制http请求头的长度来进行限制的,nginx的配置参数为large_client_header_buffer…

    2022年8月24日
    4
  • stat函数返回值_strcat函数

    stat函数返回值_strcat函数#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>//需包含头文件有如下三个函数的函数原型:intstat(constchar*path,structstat*buf);第一个形参:指出文件(文件路径);第二个形参:出参数(函数对该参数操作,然后…

    2022年8月21日
    4
  • JUnit中对Exception的判断

    JUnit中对Exception的判断

    2021年9月15日
    48
  • SiamFC 学习(论文、总结与分析)

    SiamFC 学习(论文、总结与分析)文章目录前言一、SiamFC论文学习1.介绍2.深度相似学习在跟踪中的应用2.1全卷积孪生结构3.引入库二、使用步骤1.引入库2.读入数据总结前言之前看了关于siamFC的论文、博客和代码,已经跑通了代码,但是,只是大概初步学习,没有认真的研究细节。为了后面更好的学习Siam系列的算法还是要重新认真的学习SiamFC。先附上论文和代码。论文:Fully-ConvolutionalSiameseNetworksforObjectTracking代码:基于pytorch框架的htt

    2022年10月1日
    0
  • provideoplayer2中文教程_potplayer vr

    provideoplayer2中文教程_potplayer vrPotplayer是高清影视常用的播放器,界面简洁,功能齐全,比MPC-HC和MPC-BE更人性化;但其默认方案十分糟糕,预设过多错误,无法正确播放10-bit视频,一直饱受诟病。VCB-Stuido以往发布的数篇高清教程大多偏重于madVR,在PotPlayer的设置方面有些错漏。为了广大观众能正确、便捷地用PotPlayer享受高清影视,我们为大家带来一篇基于Pot…

    2022年9月14日
    0
  • MMC卡和SD卡的区别「建议收藏」

    MMC卡和SD卡的区别「建议收藏」目前诸如MMC卡和SD卡等固态内存卡的快速发展,也引起了很多有时是误解的猜想。下面逐个解释一些问题,将会帮助您区分MMC卡和SD卡的关键特征和优点,协助您决定哪一个解决方案对您而言是最好的。 外形尺寸:从两种卡的正面看过去,除了SD卡侧面的的写保护开关,两者的外观是一样的(都是24mmx32mm)。因为这个原因,这两种闪存卡标准常常被混淆。首先,两者的厚度是不同的,…

    2022年6月11日
    40

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号