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

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 id="fish-box" className={`${item.class}`} key={index} style={{left:`${item.left}px`,right:`${item.right}px`,top:`${item.top}px`}}><img  src={item.src} /></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

 

posted @ 2019-04-16 17:35  知兮  阅读(4025)  评论(0编辑  收藏  举报