react 利用react-hammerjs插件实现滑动特效和点击特效

react

react-hammerjs是一款由hammer.js的JS插件来实现在react中实现手势滑动的事件插件,

它有各种各样的手势支持效果,这里我们就使用下它最简单的3种效果来实现我们要的动画

分别是点击(onTap)、滑动(onPan)、滑动结束(onPanEnd)

具体事件参数和其它事件可以参考官网

动画效果

上代码

import React from 'react'

import {draw} from './canvas'

import Hammer from 'react-hammerjs'

import axios from './../axios'

import "./index.css"

export default class Index extends React.Component{

state = {

bubble:[],

bubbleState:true,

bubbleClass:[

{

class:'bubble-1',

},

{

class:'bubble-2',

},

{

class:'bubble-3',

},

{

class:'bubble-4',

},

{

class:'bubble-5',

}

],

fishList:[],

param:[

{

version:'v1',

cityid:'101020100'

}

]

}

componentWillMount() {

this.tem()

let num = Math.floor(Math.random()*5);

console.log("num----->",num)

}

tem=()=>{ //天气温度

axios.get("api/",this.state.param,

result=> {

console.log("--------->",result)

this.setState({listData:result.data ||[]})

},

result=> {

}

);

}

handleClick=(e)=>{ //点击

let fishList = this.state.fishList;

let leftX = e.center.y

let topY = e.center.y

let fish = {}

if(1080/2>e.center.x){ //左

console.log("点击-1-》",e,topY,1080/2>e.center.x);

fish.left = '-30'

fish.right = ''

fish.top = topY

fish.class='fishClassL-1'

fish.src='./video/fish-1.jpg'

}else { //右

fish.left = ''

fish.right = '-30'

fish.top = topY

fish.class='fishClassR-1'

fish.src='./video/fish-2.jpg'

console.log("点击-2-》",e,topY,1080/2>e.center.x);

}

console.log("fish----->",fish)

fishList.push(fish)

this.setState({

fishList:fishList

})

}

onPan=(e)=>{ //划动

let bubbleState = this.state.bubbleState

if(bubbleState){

let num = Math.floor(Math.random()*5);

let bubbleClass = this.state.bubbleClass

let bubble = {}

bubble.left = e.center.x

bubble.top = e.center.y

bubble.src = './video/bubble-1.png'

bubble.class = bubbleClass[num].class

// bubble.class = 'bubble-3'

let bubbleList = this.state.bubble

bubbleList.push(bubble)

// console.log("划动--》",e);

this.setState({

bubble:bubbleList,

// bubbleState:false

})

}

}

onPanEnd =()=>{

this.setState({

bubbleState:false

})

console.log("划动结束--》");

setTimeout(()=> {

this.setState({

bubble:[],

bubbleState:true

})

},3000)

}

componentDidMount() {

if (this.canvas) {

draw(this.canvas)

}

}

render() {

const { percent,tops } = this.state;

return(

<Hammer onTap={this.handleClick} onPan={this.onPan} onPanEnd={this.onPanEnd} >

<div id={'scrollBox'} className="video-box">

{/*<div className="fish" style={{left:`${percent}%`,top:`${tops}px`}}></div>*/}

{

this.state.bubble && this.state.bubble.map((item,index)=>{

return (

<div className="bubble-box" key={index} style={{left:`${item.left}px`,top:`${item.top}px`}}><img className={`${item.class}`} src={item.src} /></div>

)

})

}

{

this.state.fishList && this.state.fishList.map((item,index)=>{

return (

<div >

)

})

}

<canvas width='1080' height='1920' ref={node => this.canvas = node} style={{width: '100%',height: 'auto',}}></canvas>

</div>

</Hammer>

)

}

}

.video-box{

/*background-color: #0BB20C;*/

height: auto;

width: 100%;

position: relative;

}

.bubble-box{

position: absolute;

}

.bubble-box img{

}

.bubble-box img.bubble-1{

width: 20px;

height: 20px;

animation:mymove1 5s normal;

}

.bubble-box img.bubble-2{

width: 10px;

height: 10px;

animation:mymove2 4s normal;

}

.bubble-box img.bubble-3{

width: 15px;

height: 15px;

animation:mymove3 5s normal;

}

.bubble-box img.bubble-4{

width: 18px;

height: 18px;

animation:mymove4 4s normal;

}

.bubble-box img.bubble-5{

width: 12px;

height: 12px;

animation:mymove5 5s normal;

}

.fish{

position: absolute;

/*left: 0;*/

width: 20px;

height: 20px;

background-color: #0CD0C0;

}

@keyframes mymove1

{

0% {

opacity: 1;

transform:translateY(0px);

}

100% {

opacity: 0;

transform:translateY(-55px);

}

}

@keyframes mymove2

{

0% {

opacity: 1;

transform:translateY(0px);

}

100% {

opacity: 0;

transform:translateY(-65px);

}

}

@keyframes mymove3

{

0% {

opacity: 1;

transform:translateY(0px);

}

100% {

opacity: 0;

transform:translateY(-75px);

}

}

@keyframes mymove4

{

0% {

opacity: 1;

transform:translateY(0px);

}

100% {

opacity: 0;

transform:translateY(-95px);

}

}

@keyframes mymove5

{

0% {

opacity: 1;

transform:translateY(0px);

}

100% {

opacity: 0;

transform:translateY(-85px);

}

}

#fish-box{

position: absolute;

}

#fish-box img{

width: 30px;

height: 30px;

}

.fishClassL-1{

animation:fishmovel1 10s normal;

}

@keyframes fishmovel1

{

0% {

left: -30px;

}

100% {

left: 1100px;

}

}

.fishClassR-1{

animation:fishmover1 10s normal;

}

@keyframes fishmover1

{

0% {

right: -30px;

}

100% {

right: 1100px;

}

}

/*1920*1080*/

利用canvas将视频渲染成动画背景

export const draw = (canvas) => {

if (canvas) {

//获取canvas上下文

let ctx = canvas.getContext('2d');

let videoState = true;

//创建video标签,并且设置相关属性

let video = document.createElement('video');

let videoSrc1 = './video/video-2.mp4'

let videoSrc2 = './video/video-3.mp4'

video.preload = true;

video.autoplay = true;

video.loop = true;

video.src = videoSrc1;

// video.className = 'aaaaaaaaa'

//document.body.appendChild(video);

//监听video的play事件,一旦开始,就把video逐帧绘制到canvas上

video.addEventListener('play',() => {

let play = () => {

ctx.drawImage(video,0,0);

requestAnimationFrame(play);

};

play();

},false)

//暂停/播放视频

canvas.addEventListener('click',() => {

// if (!video.paused) {

// video.pause();

// console.log("暂停视频!")

// } else {

// video.play();

// console.log("开始视频!")

// }

if (videoState) {

// video.src = videoSrc2;

// videoState = false;

// canvasBg = canvas

} else {

// video.src = videoSrc1;

// videoState = true;

}

},false);

}

}

View Code

封装axios插件

// import JsonP from 'jsonp'

import axios from 'axios'

// import showMsg from '../components/notification'

// 配置API接口地址

var root = 'https://www.tianqiapi.com/'

// var root = '/prefix'

// 自定义判断元素类型JS

function toType (obj) {

return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()

}

// 参数过滤函数

function filterNull (o) {

for (var key in o) {

if (o[key] === null) {

delete o[key]

}

if (toType(o[key]) === 'string') {

o[key] = o[key].trim()

} else if (toType(o[key]) === 'object') {

o[key] = filterNull(o[key])

} else if (toType(o[key]) === 'array') {

o[key] = filterNull(o[key])

}

}

return o

}

/*

接口处理函数

这个函数每个项目都是不一样的,我现在调整的是适用于

https://cnodejs.org/api/v1 的接口,如果是其他接口

需要根据接口的参数进行调整。参考说明文档地址:

https://cnodejs.org/topic/5378720ed6e2d16149fa16bd

主要是,不同的接口的成功标识和失败提示是不一致的。

另外,不同的项目的处理方法也是不一致的,这里出错就是简单的alert

*/

function apiAxios (method, url, params, success, failure) {

if (params) {

params = filterNull(params)

}

axios({

method: method,

url: url,

data: method === 'POST' || method === 'PUT' ? params : null,

params: method === 'GET' || method === 'DELETE' ? params : null,

baseURL: root,

withCredentials: false

}).then(function (res) {

// if (res.data.success === true) {

// if (success) {

// success(res.data)

// }

// } else {

// if (failure) {

// failure(res.data)

// } else {

// // window.alert('error: ' + JSON.stringify(res.data))

// console.log('error: 222' + JSON.stringify(res.data));

// }

// }

success(res.data);

// success(JSON.stringify(res.data));

}).catch(function (err) {

// let res = err.response

// if (err) {

// // window.alert('api error, HTTP CODE: ' + res.status)

console.log('api error333, HTTP CODE: ' + err.status);

// }

// showMsg.error('api error, HTTP CODE: ' +err.status);

})

}

// 返回在react模板中的调用接口

export default {

get: function (url, params, success, failure) {

return apiAxios('GET', url, params, success, failure)

},

post: function (url, params, success, failure) {

return apiAxios('POST', url, params, success, failure)

},

put: function (url, params, success, failure) {

return apiAxios('PUT', url, params, success, failure)

},

delete: function (url, params, success, failure) {

return apiAxios('DELETE', url, params, success, failure)

}

}

View Code

以上是 react 利用react-hammerjs插件实现滑动特效和点击特效 的全部内容, 来源链接: utcz.com/z/381711.html

回到顶部