domRipple.mjs

  1. import get from 'lodash-es/get.js'
  2. import ispint from './ispint.mjs'
  3. import isestr from './isestr.mjs'
  4. import isEle from './isEle.mjs'
  5. import domRemove from './domRemove.mjs'
  6. /**
  7. * 前端DOM元素點擊Ripple效果
  8. *
  9. * Unit Test: {@link https://github.com/yuda-lyu/wsemi/blob/master/test/domRipple.test.mjs Github}
  10. * @memberOf wsemi
  11. * @param {HTMLElement} ele 輸入dom
  12. * @param {Object} event 輸入dom點擊事件
  13. * @param {Integer} [opt.timeDuration=1000] 輸入Ripple效果持續時間整數,單位為毫秒ms,預設1000
  14. * @param {String} [opt.color='rgba(255, 255, 255, 0.5)'] 輸入Ripple顏色字串,預設'rgba(255, 255, 255, 0.5)'
  15. * @example
  16. * need test in browser
  17. *
  18. * let ele = document.querySelector('#id')
  19. * ele.addEventListener('click', (e)=>{
  20. * domRipple(e.currentTarget,e)
  21. * })
  22. *
  23. */
  24. function domRipple(ele, event, opt = {}) {
  25. //timeDuration
  26. let timeDuration = get(opt, 'timeDuration', null)
  27. if (!ispint(timeDuration)) {
  28. timeDuration = 1000
  29. }
  30. //color
  31. let color = get(opt, 'color', null)
  32. if (!isestr(color)) {
  33. color = 'rgba(255, 255, 255, 0.5)'
  34. }
  35. //check
  36. if (!isEle(ele)) {
  37. return
  38. }
  39. //更改元素style
  40. ele.style.position = 'relative' //得要讓ripple的absolute能生效
  41. ele.style.overflow = 'hidden' //讓ripple的效果不會溢出dom範圍
  42. //let
  43. let rect = ele.getBoundingClientRect()
  44. let left = event.clientX - rect.left
  45. let top = event.clientY - rect.top
  46. //diameter
  47. let diameter = Math.max(ele.clientWidth, ele.clientHeight) * 2 //半徑為最大長寬, 直徑為半徑*2
  48. //eleRipple
  49. let eleRipple = document.createElement('div')
  50. eleRipple.style.width = `${diameter}px`
  51. eleRipple.style.height = `${diameter}px`
  52. eleRipple.style.transition = `all ${timeDuration / 1000}s linear`
  53. eleRipple.style.position = 'absolute'
  54. eleRipple.style.zIndex = 1
  55. eleRipple.style.left = `${left}px`
  56. eleRipple.style.top = `${top}px`
  57. eleRipple.style.borderRadius = '50%'
  58. eleRipple.style.transformOrigin = 'center'
  59. eleRipple.style.transform = 'translate(-50%,-50%) scale(0)'
  60. eleRipple.style.background = color
  61. eleRipple.style.userSelect = 'none'
  62. eleRipple.style.pointerEvents = 'none'
  63. ele.appendChild(eleRipple)
  64. // console.log('eleRipple',eleRipple)
  65. //add effect
  66. setTimeout(() => {
  67. eleRipple.style.transform = 'translate(-50%,-50%) scale(2)'
  68. eleRipple.style.opacity = 0
  69. }, 1)
  70. //remove
  71. setTimeout(() => {
  72. domRemove(eleRipple)
  73. }, timeDuration)
  74. }
  75. export default domRipple