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:;
transform:translateY(0px);
}
100% {
opacity:;
transform:translateY(-55px);
}
}
@keyframes mymove2
{
0% {
opacity:;
transform:translateY(0px);
}
100% {
opacity:;
transform:translateY(-65px);
}
}
@keyframes mymove3
{
0% {
opacity:;
transform:translateY(0px);
}
100% {
opacity:;
transform:translateY(-75px);
}
}
@keyframes mymove4
{
0% {
opacity:;
transform:translateY(0px);
}
100% {
opacity:;
transform:translateY(-95px);
}
}
@keyframes mymove5
{
0% {
opacity:;
transform:translateY(0px);
}
100% {
opacity:;
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); }
}
封装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)
}
}
react 利用react-hammerjs插件实现滑动特效和点击特效的更多相关文章
- 利用React/anu编写一个弹出层
本文将一步步介绍如何使用React或anu创建 一个弹出层. React时代,代码都是要经过编译的,我们很多时间都耗在babel与webpack上.因此本文也介绍如何玩webpack与babel. 我 ...
- 利用React Native 从0到1 开发一款兼容IOS和android的APP(仿造京东)
最近有一部电视剧叫做<微微一笑很傻逼>里面有个男猪脚,人们都叫他大神~我觉得吧~大神是相对的~所以~啥事都得谦虚! 好了 今天介绍的是如何从0到1利用React Native开发一款兼容I ...
- 在react里面使用jquery插件
在react里面使用jquery插件 背景: 虽然现在react,vue等框架开启了前端开发的新篇章, 但对于一些比较复杂的页面,比如想在项目里面生成 组织架构图,人员汇报关系等还是需要用到之前的 j ...
- React初步学习-利用React构建个人博客
React初步学习-利用React构建个人博客 用React和Webpack写了一个很简单的个人博客,主要是想要熟悉一下react中各种基本基本属性及方法的使用.在构建过程中碰到不少问题,通过阅读官方 ...
- 【React】react项目引入echarts插件 K线图
参考npm文档:https://www.npmjs.com/package/echarts-for-react 由于npm上已经有针对react项目出的echarts插件,所以在这里直接安装 第一步: ...
- 利用 React 高阶组件实现一个面包屑导航
什么是 React 高阶组件 React 高阶组件就是以高阶函数的方式包裹需要修饰的 React 组件,并返回处理完成后的 React 组件.React 高阶组件在 React 生态中使用的非常频繁, ...
- 如何利用 React Hooks 管理全局状态
如何利用 React Hooks 管理全局状态 本文写于 2020 年 1 月 6 日 React 社区最火的全局状态管理库必定是 Redux,但是 Redux 本身就是为了大型管理数据而妥协设计的- ...
- React利用Antd的Form组件实现表单功能(转载)
一.构造组件 1.表单一定会包含表单域,表单域可以是输入控件,标准表单域,标签,下拉菜单,文本域等. 这里先引用了封装的表单域 <Form.Item /> 2.使用Form.create处 ...
- React的React Native
React的React Native React无疑是今年最火的前端框架,github上的star直逼30,000,基于React的React Native的star也直逼20,000.有了React ...
随机推荐
- dubbo本地搭建实例
项目文件下载地址:http://download.csdn.net/detail/aqsunkai/9552711 概述 Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服 ...
- pip 代理设置,坑爹的代理继续
Linux ubuntu 3.2.0-23-generic-pae #36-Ubuntu SMP Tue Apr 10 22:19:09 UTC 2012 i686 i686 i386 GNU/Lin ...
- 《Cracking the Coding Interview》——第14章:Java——题目2
2014-04-26 18:44 题目:在java的try-catch-finally语句块里,如果catch里面有return语句的话,finally还会被执行吗? 解法:会. 代码: // 14. ...
- 天性 & 如水一般,遇强则强 —— 梦想、行为、性格
开篇声明,我博客中“小心情”这一系列,全都是日记啊随笔啊什么乱七八糟的.如果一不小心点进来了,不妨直接关掉.我自己曾经写过一段时间的日记,常常翻看,毫无疑问我的文笔是很差的,而且心情也是瞬息万变的.因 ...
- Dapper 学习笔记
一.基础 1.Dapper代码就一个SqlMapper.cs文件, 前人测试Dapper速度较快 的Orm,读取速度接近IDataReader,超过DataTable. 2.a.下载地址 https: ...
- HTTP响应码
更详细的内容参考:https://baike.baidu.com/item/HTTP状态码/5053660?fr=aladdin 转载CSDN作者:ddhsea 的文章 https://blog.cs ...
- CentOS6/7-防火墙管理
#CentOS6 #开放端口运行外部访问(不指定源IP) iptables -I INPUT -p tcp --dport -j ACCEPT iptables -I INPUT -p tcp --d ...
- ExtJs学习之MessAgeBox的使用
1.Ext.MessageBox.alert() 调用格式: alert( String title, String msg, [Function fn], [Object scope] ) 参数说明 ...
- P3153 [CQOI2009]跳舞
题目描述 一次舞会有n个男孩和n个女孩.每首曲子开始时,所有男孩和女孩恰好配成n对跳交谊舞.每个男孩都不会和同一个女孩跳两首(或更多)舞曲.有一些男孩女孩相互喜欢,而其他相互不喜欢(不会”单向喜欢“) ...
- Lettcode Kth Largest Element in an Array
Lettcode Kth Largest Element in an Array 题意:在无序数组中,寻找第k大的数字,注意这里考虑是重复的. 一直只会简单的O(nlogn)的做法,听说这题有O(n) ...