按钮实现水波纹效果(CSS3和Canves)

 

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

Canves实现 

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

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

css代码: 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

* {

 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;

}

js代码 :

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

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();

CSS3实现 

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

css代码 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

.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代码 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

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-transitio

 

n-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);

原理也简单,获取点击位置 ->  添加样式 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值