From a135aed1a8e63f5162efb93dcb86414f93b231ff Mon Sep 17 00:00:00 2001 From: jljsj Date: Tue, 21 Mar 2017 15:51:45 +0800 Subject: [PATCH 1/4] update 1.0.0 --- examples/link.js | 4 +--- examples/linkAsynchronous.js | 4 +--- examples/scrollScreen.js | 3 --- examples/simple.js | 21 +++++++++++++---- package.json | 4 ++-- src/EventDispatcher.js | 31 ++++++++++++++++--------- src/ScrollElement.jsx | 5 +++- src/ScrollOverPack.jsx | 44 +++++++++++++++++++----------------- 8 files changed, 68 insertions(+), 48 deletions(-) diff --git a/examples/link.js b/examples/link.js index 07dd9bc..15b3864 100644 --- a/examples/link.js +++ b/examples/link.js @@ -85,7 +85,7 @@ class Demo extends React.Component { - + 默认进入与出场 @@ -102,7 +102,6 @@ class Demo extends React.Component { style={{ backgroundColor: '#0098CE' }} always={false} id="page2" - hideProps={{ 1: { reverse: true } }} >
只进入一次
@@ -121,7 +120,6 @@ class Demo extends React.Component { style={{ backgroundColor: '#174270' }} playScale={0.8} id="page3" - hideProps={{ title: { reverse: true }, 1: { reverse: true } }} > , - + 默认进入与出场 @@ -107,7 +107,6 @@ class Demo extends React.Component { style={{ backgroundColor: '#0098CE' }} always={false} id="page2" - hideProps={{ 1: { reverse: true } }} key="2" >
只进入一次
@@ -127,7 +126,6 @@ class Demo extends React.Component { style={{ backgroundColor: '#174270' }} playScale={0.8} id="page3" - hideProps={{ title: { reverse: true }, 1: { reverse: true } }} key="3" > @@ -116,7 +115,6 @@ class Demo extends React.Component { style={{ backgroundColor: '#174270', height: 500 }} id="page2" playScale={1} - hideProps={{ t: { reverse: true }, 1: { reverse: true } }} > 只从上往下时播放 @@ -138,7 +136,6 @@ class Demo extends React.Component { always={false} id="page3" playScale={1} - hideProps={{ t: { reverse: true }, 1: { reverse: true } }} > - 默认进入与出场 + 默认进入与出场, 顶部出场 + + +
+
+
+
+
+
+ + + + 默认出场直接出现
@@ -48,7 +63,6 @@ class Demo extends React.Component { className="pack-page page2" style={{ backgroundColor: '#0098CE' }} always={false} id="page2" - hideProps={{ title: { reverse: true } }} > 只进入一次 @@ -66,7 +80,6 @@ class Demo extends React.Component { className="pack-page page3" style={{ backgroundColor: '#174270' }} playScale={0.8} id="page3" - hideProps={{ title: { reverse: true }, 1: { reverse: true } }} > -1) { if (list[i].c === callback && (_force || list[i].n === namespaces)) { - if (this._eventTarget.removeEventListener) { - this._eventTarget.removeEventListener(list[i].t, list[i].func); - } else if (this._eventTarget.detachEvent) { - this._eventTarget.detachEvent(`on${list[i].t}`, list[i].func); - } list.splice(i, 1); + if (!list.length) { + const func = this._listFun[_type]; + delete this._listeners[_type]; + delete this._listFun[_type]; + if (this._eventTarget.removeEventListener) { + this._eventTarget.removeEventListener(_type, func); + } else if (this._eventTarget.detachEvent) { + this._eventTarget.detachEvent(`on${_type}`, func); + } + } if (!_force) { return; } diff --git a/src/ScrollElement.jsx b/src/ScrollElement.jsx index 2425fe5..146ff9e 100644 --- a/src/ScrollElement.jsx +++ b/src/ScrollElement.jsx @@ -16,9 +16,12 @@ class ScrollElement extends React.Component { mapped.register(this.props.id, this.dom); } const date = Date.now(); + const scrollTop = currentScrollTop(); + if (!scrollTop) { + this.scrollEventListener(); + } const length = EventListener._listeners.scroll ? EventListener._listeners.scroll.length : 0; this.eventType = `scroll.scrollEvent${date}${length}`; - this.scrollEventListener(); EventListener.addEventListener(this.eventType, this.scrollEventListener); } diff --git a/src/ScrollOverPack.jsx b/src/ScrollOverPack.jsx index b19af18..0393d09 100644 --- a/src/ScrollOverPack.jsx +++ b/src/ScrollOverPack.jsx @@ -1,4 +1,5 @@ import React, { createElement } from 'react'; +import TweenOne from 'rc-tween-one'; import EventListener from './EventDispatcher'; import ScrollElement from './ScrollElement'; import { toArrayChildren } from './util'; @@ -9,18 +10,19 @@ function noop() { class ScrollOverPack extends ScrollElement { constructor(props) { super(props); - this.children = toArrayChildren(this.props.children); + this.children = toArrayChildren(props.children); this.oneEnter = false; this.enter = false; this.state = { show: false, - children: toArrayChildren(this.props.children), + children: toArrayChildren(props.children), }; } scrollEventListener = (e) => { this.getParam(e); - if (this.enter) { + const isTop = this.elementShowHeight > this.clientHeight + this.leavePlayHeight; + if (this.enter || !this.props.replay && isTop) { if (!this.state.show) { this.setState({ show: true, @@ -29,16 +31,16 @@ class ScrollOverPack extends ScrollElement { if (!this.props.always) { EventListener.removeEventListener(this.eventType, this.scrollEventListener); } - } - const bottomLeave = this.elementShowHeight < this.playHeight; - // 设置往上时的出场点... - const topLeave = this.props.replay ? - this.elementShowHeight > this.clientHeight + this.leavePlayHeight : null; - if (topLeave || bottomLeave) { - if (this.state.show) { - this.setState({ - show: false, - }); + } else { + const bottomLeave = this.elementShowHeight < this.playHeight; + // 设置往上时的出场点... + const topLeave = this.props.replay ? isTop : null; + if (topLeave || bottomLeave) { + if (this.state.show) { + this.setState({ + show: false, + }); + } } } } @@ -51,12 +53,13 @@ class ScrollOverPack extends ScrollElement { 'component', 'always', 'scrollEvent', - 'hideProps', + 'appear', 'location', ].forEach(key => delete placeholderProps[key]); let childToRender; - if (!this.oneEnter && !this.state.show) { - childToRender = createElement(this.props.component, { ...placeholderProps }, null); + if (!this.oneEnter) { + const children = !this.props.appear && this.props.children; + childToRender = createElement(this.props.component, { ...placeholderProps }, children); this.oneEnter = true; } else { if (!this.state.show) { @@ -65,9 +68,8 @@ class ScrollOverPack extends ScrollElement { return null; } let element; - const hideProps = this.props.hideProps[item.key]; - if (hideProps) { - element = React.cloneElement(item, { ...hideProps }); + if (item.type === TweenOne) { + element = React.cloneElement(item, { reverse: true }); return element; } element = React.cloneElement(item, {}, null); @@ -91,7 +93,7 @@ ScrollOverPack.propTypes = { style: React.PropTypes.any, replay: React.PropTypes.bool, onChange: React.PropTypes.func, - hideProps: React.PropTypes.object, + appear: React.PropTypes.bool, }; ScrollOverPack.defaultProps = { @@ -101,7 +103,7 @@ ScrollOverPack.defaultProps = { scrollEvent: noop, replay: false, onChange: noop, - hideProps: {}, + appear: true, }; export default ScrollOverPack; From 33a6f6ccb4b0c9c0a9c841aed887625b412f4b33 Mon Sep 17 00:00:00 2001 From: jljsj Date: Tue, 21 Mar 2017 16:21:29 +0800 Subject: [PATCH 2/4] update API --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 131dce0..43f40a1 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ var React = require('react'); // ScrollOverPack support rc-animate,rc-queue-anim,rc-tween-one; -React.render( +React.render(
enter
enter
@@ -128,11 +128,13 @@ ScrollAnim.scrollScreen.unMount(); OverPack inherit Element; `component` `playScale` `onChange` `location` refer to `Element`; +> 1.0.0 remove hideProps; + | name | type | default | description | |-----------|----------------|---------|----------------| | always | boolean | `true` | back to top, enter replay,as `false` will only play it again, leave does not play | | replay | boolean | `false` | play every enter, do you want to animate each time you show the current, `false` only scroll to down play animate | -| hideProps | object | `null` | v0.3.0 children hideProps move here. If the child does not have, default: { children: null }. children be `rc-tween-one` { 'userKey': { reverse: true }} | +| appear | boolean | `true` | whether support appear the operation | ### Parallax | name | type | default | description | From 47fa5245249576cd9874067662e83d975134f015 Mon Sep 17 00:00:00 2001 From: jljsj Date: Tue, 21 Mar 2017 17:41:21 +0800 Subject: [PATCH 3/4] add targetId --- README.md | 1 + examples/target.html | 1 + examples/target.js | 68 ++++++++++++++++++++++++++++++++++++++++++ src/EventDispatcher.js | 20 ++++++------- src/ScrollElement.jsx | 16 +++++----- src/ScrollOverPack.jsx | 3 +- 6 files changed, 91 insertions(+), 18 deletions(-) create mode 100644 examples/target.html create mode 100644 examples/target.js diff --git a/README.md b/README.md index 43f40a1..f9dc0c0 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,7 @@ ScrollAnim.scrollScreen.unMount(); |-----------|----------------|---------|----------------| | component | string | `div` | - | | id | string | null | need to location the id,parallax the `location` or link the `to`, need to use | +| targetId | string | null | scroll target id, if don't window scroll, parent element is `overflow: scroll`, use parent id to do scroll; [demo refs](http://react-component.github.io/scroll-anim/examples/target.html) | | playScale | number / array | `0.5` | percentage of screen to start play, screen center is 0.5, if replay is true : [bottomEnter, topLeave], topLeave >= bottomEnter | | onChange | func | null | change callback({ mode, scrollName }); mode: `enter` or `leave` | | location | string | null | v0.6.0 above have,location, the parent id; | diff --git a/examples/target.html b/examples/target.html new file mode 100644 index 0000000..b3a4252 --- /dev/null +++ b/examples/target.html @@ -0,0 +1 @@ +placeholder \ No newline at end of file diff --git a/examples/target.js b/examples/target.js new file mode 100644 index 0000000..b55c6db --- /dev/null +++ b/examples/target.js @@ -0,0 +1,68 @@ +// use jsx to render html, do not modify simple.html + +import 'rc-scroll-anim/assets/index.less'; +import ScrollAnim from 'rc-scroll-anim'; +import React from 'react'; +import ReactDOM from 'react-dom'; +import QueueAnim from 'rc-queue-anim'; +import TweenOne from 'rc-tween-one'; +const _package = require('../package.json'); +const ScrollOverPack = ScrollAnim.OverPack; + +class Demo extends React.Component { + constructor() { + super(...arguments); + } + + render() { + return (
+
+ +
+

{_package.name}@{_package.version}

+
+
+

The simple demo

+
+
+
+ + + 默认进入与出场, 顶部出场 + + +
+
+
+
+
+
+ + + + 默认出场直接出现 + + +
+
+
+
+
+
+ +
); + } +} + +ReactDOM.render(, document.getElementById('__react-content')); diff --git a/src/EventDispatcher.js b/src/EventDispatcher.js index 4086bc7..b5b4930 100644 --- a/src/EventDispatcher.js +++ b/src/EventDispatcher.js @@ -6,7 +6,7 @@ function EventDispatcher(target) { this._listFun = {}; } EventDispatcher.prototype = { - addEventListener(type, callback) { + addEventListener(type, callback, target) { const types = type.split('.'); const _type = types[0]; const namespaces = types[1]; @@ -32,14 +32,14 @@ EventDispatcher.prototype = { if (!this._listFun[_type]) { this._listFun[_type] = this._listFun[_type] || this.dispatchEvent.bind(this, _type); if (this._eventTarget.addEventListener) { - this._eventTarget.addEventListener(_type, this._listFun[_type], false); + (target || this._eventTarget).addEventListener(_type, this._listFun[_type], false); } else if (this._eventTarget.attachEvent) { - this._eventTarget.attachEvent(`on${_type}`, this._listFun[_type]); + (target || this._eventTarget).attachEvent(`on${_type}`, this._listFun[_type]); } } }, - removeEventListener(type, callback, force) { + removeEventListener(type, callback, target, force) { const types = type.split('.'); const _type = types[0]; const namespaces = types[1]; @@ -59,9 +59,9 @@ EventDispatcher.prototype = { delete this._listeners[_type]; delete this._listFun[_type]; if (this._eventTarget.removeEventListener) { - this._eventTarget.removeEventListener(_type, func); + (target || this._eventTarget).removeEventListener(_type, func); } else if (this._eventTarget.detachEvent) { - this._eventTarget.detachEvent(`on${_type}`, func); + (target || this._eventTarget).detachEvent(`on${_type}`, func); } } if (!_force) { @@ -89,7 +89,7 @@ EventDispatcher.prototype = { } } }, - removeAllType(type) { + removeAllType(type, target) { const types = type.split('.'); const _type = types[0]; const namespaces = types[1]; @@ -98,16 +98,16 @@ EventDispatcher.prototype = { item.n && item.n.match(namespaces) )); this.recoverLists.forEach(item => { - this.removeEventListener(`${item.t}.${item.n}`, item.c); + this.removeEventListener(`${item.t}.${item.n}`, item.c, target); }); }, - reAllType(type) { + reAllType(type, target) { const types = type.split('.'); const _type = types[0]; const namespaces = types[1]; this.recoverLists = this.recoverLists.map(item => { if (item.t === _type && item.n.match(namespaces)) { - this.addEventListener(`${item.t}.${item.n}`, item.c); + this.addEventListener(`${item.t}.${item.n}`, item.c, target); return null; } return item; diff --git a/src/ScrollElement.jsx b/src/ScrollElement.jsx index 146ff9e..7b5d253 100644 --- a/src/ScrollElement.jsx +++ b/src/ScrollElement.jsx @@ -22,7 +22,8 @@ class ScrollElement extends React.Component { } const length = EventListener._listeners.scroll ? EventListener._listeners.scroll.length : 0; this.eventType = `scroll.scrollEvent${date}${length}`; - EventListener.addEventListener(this.eventType, this.scrollEventListener); + this.target = this.props.targetId && document.getElementById(this.props.targetId); + EventListener.addEventListener(this.eventType, this.scrollEventListener, this.target); } componentWillReceiveProps(nextProps) { @@ -33,15 +34,15 @@ class ScrollElement extends React.Component { componentWillUnmount() { mapped.unRegister(this.props.id); - EventListener.removeEventListener(this.eventType, this.scrollEventListener); + EventListener.removeEventListener(this.eventType, this.scrollEventListener, this.target); } getParam = (e) => { - this.clientHeight = windowHeight(); - const scrollTop = currentScrollTop(); - // 屏幕缩放时的响应,所以放回这里,这个是pack,只处理子级里面的动画,所以marginTop无关系,所以不需减掉; + this.clientHeight = this.target ? this.target.getBoundingClientRect().height : windowHeight(); + const windowScrollTop = this.target ? currentScrollTop() : 0; + const scrollTop = this.target ? this.target.scrollTop : currentScrollTop(); const domRect = this.dom.getBoundingClientRect(); - const offsetTop = domRect.top + scrollTop; + const offsetTop = domRect.top + scrollTop + windowScrollTop; this.elementShowHeight = scrollTop - offsetTop + this.clientHeight; const playScale = transformArguments(this.props.playScale); this.playHeight = this.clientHeight * playScale[0]; @@ -63,7 +64,7 @@ class ScrollElement extends React.Component { render() { const { ...props } = this.props; - ['component', 'playScale', 'location'].forEach(key => delete props[key]); + ['component', 'playScale', 'location', 'targetId'].forEach(key => delete props[key]); return React.createElement(this.props.component, { ...props }); } } @@ -74,6 +75,7 @@ ScrollElement.propTypes = { id: React.PropTypes.string, onChange: React.PropTypes.func, location: React.PropTypes.string, + targetId: React.PropTypes.string, }; ScrollElement.defaultProps = { diff --git a/src/ScrollOverPack.jsx b/src/ScrollOverPack.jsx index 0393d09..43d3faa 100644 --- a/src/ScrollOverPack.jsx +++ b/src/ScrollOverPack.jsx @@ -29,7 +29,7 @@ class ScrollOverPack extends ScrollElement { }); } if (!this.props.always) { - EventListener.removeEventListener(this.eventType, this.scrollEventListener); + EventListener.removeEventListener(this.eventType, this.scrollEventListener, this.target); } } else { const bottomLeave = this.elementShowHeight < this.playHeight; @@ -55,6 +55,7 @@ class ScrollOverPack extends ScrollElement { 'scrollEvent', 'appear', 'location', + 'targetId', ].forEach(key => delete placeholderProps[key]); let childToRender; if (!this.oneEnter) { From 2841c08ea69a2503b907462f304b934922bf087b Mon Sep 17 00:00:00 2001 From: jljsj Date: Tue, 21 Mar 2017 17:44:33 +0800 Subject: [PATCH 4/4] update travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f9c7145..2d72e5f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ notifications: - yiminghe@gmail.com node_js: -- 4.0.0 +- 6.0.0 before_install: - |