Skip to content

Commit

Permalink
优化点击效果
Browse files Browse the repository at this point in the history
  • Loading branch information
hys committed Feb 24, 2018
1 parent a47a576 commit f81543e
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 45 deletions.
17 changes: 7 additions & 10 deletions src/component/click-material/index.css
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
.ripple {
.fireworks {
position: absolute;
z-index: 99999999;
background: rgba(0, 0, 0, 0.15);
border-radius: 100%;
transform: scale(0);
top: 0;
left: 0;
widows: 100%;
height: 100%;
pointer-events: none;
animation: ripple 0.75s ease-out;
}

@keyframes ripple {
to {
transform: scale(2);
opacity: 0;
}
.click-material {
min-height: 100%;
}
183 changes: 148 additions & 35 deletions src/component/click-material/index.js
Original file line number Diff line number Diff line change
@@ -1,56 +1,169 @@
/**
* Created by axetroy on 17-4-6.
*/
import React, { Component } from 'react'
import anime from 'animejs'
import './index.css'
import debounce from 'lodash.debounce'

class Click extends Component {
componentWillMount() {
const width = 200
const height = 200
const ele = document.createElement('span')
ele.classList.add('ripple')
ele.style.width = `${width}px`
ele.style.height = `${height}px`
this.__ele__ = ele
export const clickColors = ['#FF1461', '#18FF92', '#5A87FF', '#FBF38C']

const numberOfParticules = 40
const tap =
'ontouchstart' in window || navigator.msMaxTouchPoints
? 'touchstart'
: 'mousedown'

class ClickComponents extends Component {
setCanvasSize = () => {
const container = this.refs.container
const height = container.clientHeight
const width = container.clientWidth
this.canvasEl.width = width
this.canvasEl.height = height
this.canvasEl.style.width = width + 'px'
this.canvasEl.style.height = height + 'px'
this.canvasEl.getContext('2d')
}

componentWillUnmount() {
;(this.__timer__ || []).forEach(timerId => {
clearTimeout(timerId)
})
updateCoords = e => {
this.pointerX = e.pageX || e.touches[0].pageX
this.pointerY = e.pageY || e.touches[0].pageY
}

onClick(event) {
const { pageX, pageY } = event
const width = 200
const height = 200
setParticuleDirection(p) {
const angle = anime.random(0, 360) * Math.PI / 180
const value = anime.random(50, 180)
const radius = [-1, 1][anime.random(0, 1)] * value
return {
x: p.x + radius * Math.cos(angle),
y: p.y + radius * Math.sin(angle),
}
}

if (!this.__ele__) return
createParticule = (x, y) => {
const p = {}
p.x = x
p.y = y
p.color = clickColors[anime.random(0, clickColors.length - 1)]
p.radius = anime.random(16, 32)
p.endPos = this.setParticuleDirection(p)
p.draw = () => {
this.ctx.beginPath()
this.ctx.arc(p.x, p.y, p.radius, 0, 2 * Math.PI, true)
this.ctx.fillStyle = p.color
this.ctx.fill()
}
return p
}

const ele = this.__ele__.cloneNode(true)
ele.style.left = `${pageX - width / 2}px`
ele.style.top = `${pageY - height / 2}px`
this.refs.container.appendChild(ele)
createCircle = (x, y) => {
const p = {}
p.x = x
p.y = y
p.color = '#FFF'
p.radius = 0.1
p.alpha = 0.5
p.lineWidth = 6
p.draw = () => {
this.ctx.globalAlpha = p.alpha
this.ctx.beginPath()
this.ctx.arc(p.x, p.y, p.radius, 0, 2 * Math.PI, true)
this.ctx.lineWidth = p.lineWidth
this.ctx.strokeStyle = p.color
this.ctx.stroke()
this.ctx.globalAlpha = 1
}
return p
}

this.__timer__ = this.__timer__ || []
this.__timer__ = this.__timer__.concat([
setTimeout(() => {
ele.remove()
}, 750),
])
renderParticule(anim) {
anim.animatables.forEach(item => {
item.target.draw()
})
}

componentDidMount() {}
animateParticules = (x, y) => {
const circle = this.createCircle(x, y)
const particules = []
for (let i = 0; i < numberOfParticules; i++) {
particules.push(this.createParticule(x, y))
}
anime
.timeline()
.add({
targets: particules,
x: function(p) {
return p.endPos.x
},
y: function(p) {
return p.endPos.y
},
radius: 0.1,
duration: anime.random(1200, 1800),
easing: 'easeOutExpo',
update: this.renderParticule,
})
.add({
targets: circle,
radius: anime.random(80, 160),
lineWidth: 0,
alpha: {
value: 0,
easing: 'linear',
duration: anime.random(600, 800),
},
duration: anime.random(1200, 1800),
easing: 'easeOutExpo',
update: this.renderParticule,
offset: 0,
})
}

render() {
return (
<div onClick={this.onClick.bind(this)} ref="container">
<div ref="container" className="click-material">
{this.props.children}
<canvas />
<canvas
className="fireworks"
height="100%"
ref={el => {
this.canvasEl = el
}}
/>
</div>
)
}

componentDidMount() {
this.pointerX = 0
this.pointerY = 0
this.ctx = this.canvasEl.getContext('2d')

const render = anime({
duration: Infinity,
update: () => {
this.ctx.clearRect(0, 0, this.canvasEl.width, this.canvasEl.height)
},
})
this.setCanvasSize()
document.addEventListener(
tap,
e => {
render.play()
this.updateCoords(e)
this.animateParticules(this.pointerX, this.pointerY)
},
false
)

window.addEventListener(
'resize',
debounce(this.setCanvasSize.bind(this), 300)
)

window.addEventListener(
'scroll',
debounce(this.setCanvasSize.bind(this), 300)
)
}
}
export default Click

export default ClickComponents
4 changes: 4 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@ body {
padding: 0;
font-family: sans-serif;
}

#root {
height: 100%;
}

0 comments on commit f81543e

Please sign in to comment.