diff --git a/packages/taro-components/src/components/canvas/index.js b/packages/taro-components/src/components/canvas/index.js
index f7ec5e418787..0c1c0966fd85 100644
--- a/packages/taro-components/src/components/canvas/index.js
+++ b/packages/taro-components/src/components/canvas/index.js
@@ -1,14 +1,74 @@
-import Nerv from 'nervjs'
+import Nerv, { findDOMNode } from 'nervjs'
+import touchable from '../../utils/touchable'
+import classnames from 'classnames'
+import { isNumber } from '../../utils/index'
-class Canvas extends Nerv.Component {
+import './style/index.css'
+
+// canvas-id String canvas 组件的唯一标识符
+// disable-scroll Boolean false 当在 canvas 中移动时且有绑定手势事件时,禁止屏幕滚动以及下拉刷新
+// bindtouchstart EventHandle 手指触摸动作开始
+// bindtouchmove EventHandle 手指触摸后移动
+// bindtouchend EventHandle 手指触摸动作结束
+// bindtouchcancel EventHandle 手指触摸动作被打断,如来电提醒,弹窗
+// bindlongtap EventHandle 手指长按 500ms 之后触发,触发了长按事件后进行移动不会触发屏幕的滚动
+// binderror EventHandle 当发生错误时触发 error 事件,detail = {errMsg: 'something wrong'}
+
+@touchable()
+export default class Canvas extends Nerv.Component {
+ static defaultProps = {
+ canvasId: '',
+ disableScroll: false,
+ bindError: null
+ }
+ state = {
+ width: null,
+ height: null
+ }
+ getRef = ref => {
+ const dom = findDOMNode(ref)
+ this.canvasDom = dom
+ }
+ shouldComponentUpdate (nProps, nState) {
+ if (nState.width !== this.state.width
+ || nState.height !== this.state.height) {
+ return true
+ }
+ return false
+ }
componentDidMount () {
- console.error('H5 暂不支持 Canvas 组件!,请直接用 H5 原生 canvas')
+ if (!this.canvasDom) return
+ const { width, height } = this.canvasDom.getBoundingClientRect()
+ this.setState({
+ width,
+ height
+ })
}
-
render () {
- const { ...reset } = this.props
- return
{this.props.children}
+ const { canvasId, onTouchStart, onTouchMove, onTouchEnd, onTouchCancel, className } = this.props
+ const { width, height } = this.state
+ const props = {
+ canvasId,
+ onTouchStart,
+ onTouchMove,
+ onTouchEnd,
+ onTouchCancel
+ }
+ if (isNumber(width)) {
+ props.width = width
+ }
+ if (isNumber(height)) {
+ props.height = height
+ }
+ return (
+
+
+
+ )
}
}
-
-export default Canvas
diff --git a/packages/taro-components/src/components/canvas/style/index.css b/packages/taro-components/src/components/canvas/style/index.css
new file mode 100644
index 000000000000..41c077189e7e
--- /dev/null
+++ b/packages/taro-components/src/components/canvas/style/index.css
@@ -0,0 +1,5 @@
+.taro-canvas {
+ position: relative;
+ width: 300px;
+ height: 150px;
+}
diff --git a/packages/taro-components/src/components/navigator/index.js b/packages/taro-components/src/components/navigator/index.js
index 965a589bf5af..47735241be33 100644
--- a/packages/taro-components/src/components/navigator/index.js
+++ b/packages/taro-components/src/components/navigator/index.js
@@ -2,10 +2,12 @@ import Taro from '@tarojs/taro-h5'
import classNames from 'classnames'
import Nerv from 'nervjs'
-import touchable from '../../utils/touchable'
+import hoverable from '../../utils/hoverable'
import './navigator.css'
+/* eslint-disable prefer-promise-reject-errors */
+
/*
*target String self 在哪个目标上发生跳转,默认当前小程序,可选值self/miniProgram
*url String 当前小程序内的跳转链接
@@ -103,7 +105,7 @@ class Navigator extends Taro.Component {
}
}
-export default touchable({
+export default hoverable({
hoverClass: 'navigator-hover',
hoverStopPropergation: false,
hoverStartTime: 50,
diff --git a/packages/taro-components/src/utils/hoverable.js b/packages/taro-components/src/utils/hoverable.js
new file mode 100644
index 000000000000..f5134245486b
--- /dev/null
+++ b/packages/taro-components/src/utils/hoverable.js
@@ -0,0 +1,114 @@
+import Taro from '@tarojs/taro-h5'
+import Nerv from 'nervjs'
+import omit from 'omit.js'
+
+/**
+ * 添加touch能力
+ * @param {Object} Options hoverable的默认配置
+ * @param {String} [Options.hoverClass] 指定点击时的样式类,当hover-class="none"时,没有点击态效果
+ * @param {Boolean} [Options.hoverStopPropergation] 指定是否阻止本节点的祖先节点出现点击态
+ * @param {Number} [Options.hoverStartTime] 按住后多久出现点击态,单位毫秒
+ * @param {Number} [Options.hoverStayTime] 手指松开后点击态保留时间,单位毫秒
+ */
+const hoverable = ({
+ hoverClass,
+ hoverStopPropergation,
+ hoverStartTime,
+ hoverStayTime
+}) => {
+ return ComponentClass => {
+ return class HoverableComponent extends Taro.Component {
+ static defaultProps = {
+ hoverClass,
+ hoverStopPropergation,
+ hoverStartTime,
+ hoverStayTime
+ }
+ constructor (props, ctx) {
+ super(props, ctx)
+ this.state = this.getInitState(this.props)
+ }
+
+ touchStartTimer = null
+ touchEndTimer = null
+
+ state = {
+ isHover: false,
+ onTouchStart: null,
+ onTouchEnd: null
+ }
+
+ getInitState = ({ hoverClass, hoverStartTime, hoverStayTime, hoverStopPropergation, onTouchStart, onTouchEnd }) => {
+ if (hoverClass === 'none') return
+ return {
+ onTouchStart: this.getOnTouchStart({ hoverStartTime, hoverStopPropergation, onTouchStart }),
+ onTouchEnd: this.getOnTouchEnd({ hoverStayTime, hoverStopPropergation, onTouchEnd })
+ }
+ }
+ getOnTouchStart = ({ hoverStartTime, hoverStopPropergation, onTouchStart }) => {
+ return e => {
+ onTouchStart && onTouchStart(e)
+ hoverStopPropergation && e.stopPropergation()
+ this.touchStartTimer && clearTimeout(this.touchStartTimer)
+ this.touchEndTimer && clearTimeout(this.touchEndTimer)
+ this.touchStartTimer = setTimeout(() => {
+ this.setState({
+ isHover: true
+ })
+ }, hoverStartTime)
+ }
+ }
+ getOnTouchEnd = ({ hoverStayTime, hoverStopPropergation, onTouchEnd }) => {
+ return e => {
+ onTouchEnd && onTouchEnd(e)
+ hoverStopPropergation && e.stopPropergation()
+ this.touchStartTimer && clearTimeout(this.touchStartTimer)
+ this.touchEndTimer && clearTimeout(this.touchEndTimer)
+ this.touchEndTimer = setTimeout(() => {
+ this.setState({
+ isHover: false
+ })
+ }, hoverStayTime)
+ }
+ }
+ reset = () => {
+ this.setState({
+ isHover: false
+ })
+ }
+ componentWillMount () {
+ document.body.addEventListener('touchstart', this.reset)
+ }
+ componentWillReceiveProps (nProps, nCtx) {
+ if (
+ nProps.hoverClass !== this.props.hoverClass ||
+ nProps.hoverStopPropergation !== this.props.hoverStopPropergation ||
+ nProps.hoverStartTime !== this.props.hoverStartTime ||
+ nProps.hoverStayTime !== this.props.hoverStayTime
+ ) {
+ const stateObj = this.getInitState(nProps)
+ this.setState(stateObj)
+ }
+ }
+ componentWillUnmount () {
+ document.body.removeEventListener('touchstart', this.reset)
+ }
+ render () {
+ const { isHover, onTouchStart, onTouchEnd } = this.state
+ const props = {
+ ...omit(this.props, [
+ 'hoverStopPropergation',
+ 'hoverStartTime',
+ 'hoverStayTime'
+ ]),
+ isHover,
+ onTouchStart,
+ onTouchEnd
+ }
+ return
+ }
+ }
+ }
+}
+
+export default hoverable
diff --git a/packages/taro-components/src/utils/index.js b/packages/taro-components/src/utils/index.js
index a71b6d4a28d8..e3d2416f7805 100755
--- a/packages/taro-components/src/utils/index.js
+++ b/packages/taro-components/src/utils/index.js
@@ -98,3 +98,7 @@ export const splitUrl = _url => {
return res
}
+
+export const isNumber = obj => {
+ return typeof obj === 'number'
+}
diff --git a/packages/taro-components/src/utils/touchable.js b/packages/taro-components/src/utils/touchable.js
index 62267a87c58b..bcca25075e7b 100644
--- a/packages/taro-components/src/utils/touchable.js
+++ b/packages/taro-components/src/utils/touchable.js
@@ -1,110 +1,55 @@
import Taro from '@tarojs/taro-h5'
-import Nerv from 'nervjs'
import omit from 'omit.js'
+import Nerv from 'nervjs'
-/**
- * 添加touch能力
- * @param {Object} Options touchable的默认配置
- * @param {String} [Options.hoverClass] 指定点击时的样式类,当hover-class="none"时,没有点击态效果
- * @param {Boolean} [Options.hoverStopPropergation] 指定是否阻止本节点的祖先节点出现点击态
- * @param {Number} [Options.hoverStartTime] 按住后多久出现点击态,单位毫秒
- * @param {Number} [Options.hoverStayTime] 手指松开后点击态保留时间,单位毫秒
- */
-const touchable = ({
- hoverClass,
- hoverStopPropergation,
- hoverStartTime,
- hoverStayTime
+const touchable = (opt = {
+ longTapTime: 500
}) => {
return ComponentClass => {
return class TouchableComponent extends Taro.Component {
static defaultProps = {
- hoverClass,
- hoverStopPropergation,
- hoverStartTime,
- hoverStayTime
- }
- constructor (props, ctx) {
- super(props, ctx)
- this.state = this.getInitState(this.props)
- }
-
- touchStartTimer = null
- touchEndTimer = null
-
- state = {
- isHover: false,
- onTouchStart: null,
- onTouchEnd: null
+ bindTouchStart: null,
+ bindTouchMove: null,
+ bindTouchEnd: null,
+ bindTouchCancel: null,
+ bindLongTap: null
}
+ timer = null
- getInitState = ({ hoverClass, hoverStartTime, hoverStayTime, hoverStopPropergation, onTouchStart, onTouchEnd }) => {
- if (hoverClass === 'none') return
- return {
- onTouchStart: this.getOnTouchStart({ hoverStartTime, hoverStopPropergation, onTouchStart }),
- onTouchEnd: this.getOnTouchEnd({ hoverStayTime, hoverStopPropergation, onTouchEnd })
- }
- }
- getOnTouchStart = ({ hoverStartTime, hoverStopPropergation, onTouchStart }) => {
- return e => {
- onTouchStart && onTouchStart(e)
- hoverStopPropergation && e.stopPropergation()
- this.touchStartTimer && clearTimeout(this.touchStartTimer)
- this.touchEndTimer && clearTimeout(this.touchEndTimer)
- this.touchStartTimer = setTimeout(() => {
- this.setState({
- isHover: true
- })
- }, hoverStartTime)
- }
- }
- getOnTouchEnd = ({ hoverStayTime, hoverStopPropergation, onTouchEnd }) => {
- return e => {
- onTouchEnd && onTouchEnd(e)
- hoverStopPropergation && e.stopPropergation()
- this.touchStartTimer && clearTimeout(this.touchStartTimer)
- this.touchEndTimer && clearTimeout(this.touchEndTimer)
- this.touchEndTimer = setTimeout(() => {
- this.setState({
- isHover: false
- })
- }, hoverStayTime)
- }
- }
- reset = () => {
- this.setState({
- isHover: false
- })
- }
- componentWillMount () {
- document.body.addEventListener('touchstart', this.reset)
- }
- componentWillReceiveProps (nProps, nCtx) {
- super.componentWillReceiveProps && super.componentWillReceiveProps(nProps, nCtx)
- if (
- nProps.hoverClass !== this.props.hoverClass ||
- nProps.hoverStopPropergation !== this.props.hoverStopPropergation ||
- nProps.hoverStartTime !== this.props.hoverStartTime ||
- nProps.hoverStayTime !== this.props.hoverStayTime
- ) {
- const stateObj = this.getInitState(nProps)
- this.setState(stateObj)
- }
- }
- componentWillUnmount () {
- document.body.removeEventListener('touchstart', this.reset)
+ onTouchStart () {
+ const { bindTouchStart, bindLongTap } = this.props
+ bindTouchStart && bindTouchStart()
+ setTimeout(() => {
+ bindLongTap && bindLongTap()
+ }, opt.longTapTime)
+ }
+ onTouchMove () {
+ const { bindTouchMove } = this.props
+ bindTouchMove && bindTouchMove()
+ }
+ onTouchEnd () {
+ this.timer && clearTimeout(this.timer)
+ const { bindTouchEnd } = this.props
+ bindTouchEnd && bindTouchEnd()
+ }
+ onTouchCancel () {
+ this.timer && clearTimeout(this.timer)
+ const { bindTouchCancel } = this.props
+ bindTouchCancel && bindTouchCancel()
}
render () {
- const { isHover, onTouchStart, onTouchEnd } = this.state
const props = {
+ onTouchStart: this.onTouchStart,
+ onTouchMove: this.onTouchMove,
+ onTouchEnd: this.onTouchEnd,
+ onTouchCancel: this.onTouchCancel,
...omit(this.props, [
- 'hoverStopPropergation',
- 'hoverStartTime',
- 'hoverStayTime'
- ]),
- isHover,
- onTouchStart,
- onTouchEnd
+ 'bindTouchStart',
+ 'bindTouchMove',
+ 'bindTouchEnd',
+ 'bindTouchCancel',
+ 'bindLongTap'
+ ])
}
return
}