├── .eslintignore
├── src
├── plugins
│ ├── picker
│ │ ├── README.md
│ │ ├── picker.js
│ │ └── package.json
│ ├── fmover-slide-x
│ │ ├── README.md
│ │ ├── package.json
│ │ └── dist
│ │ │ └── fmover-slide-x.min.js
│ ├── fmover-slide-y
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── dist
│ │ │ └── fmover-slide-y.min.js
│ │ └── fmover-slide-y.js
│ ├── simulation-scroll-x
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── dist
│ │ │ ├── simulation-scroll-x.min.js
│ │ │ └── simulation-scroll-x.js
│ │ └── simulation-scroll-x.js
│ └── simulation-scroll-y
│ │ ├── README.md
│ │ ├── package.json
│ │ └── dist
│ │ └── simulation-scroll-y.min.js
├── moved
│ ├── README.md
│ ├── tw.js
│ ├── package.json
│ ├── animationframe.js
│ ├── moved.js
│ └── dist
│ │ ├── moved.min.js
│ │ └── moved.js
├── fingerd
│ ├── README.md
│ ├── package.json
│ ├── dist
│ │ ├── fingerd.min.js
│ │ └── fingerd.js
│ ├── fingerd.js
│ └── tevent.js
├── vue-component
│ └── simulation-scroll-y.vue
├── index.js
└── shared
│ └── util.js
├── .gitignore
├── .babelrc
├── circle.yml
├── test
├── index.unit.js
└── unit
│ ├── index.spec.js
│ ├── util.spec.js
│ └── moved.spec.js
├── demo
├── vue-component
│ └── simulation-scroll-y
│ │ ├── main.js
│ │ ├── index.html
│ │ └── app.vue
├── mover-easy-demo.html
├── fingerd-demo.html
├── simulation-y-demo.html
├── simulation-x-demo.html
├── 2d-scroll-demo.html
├── scroll-to-y.html
├── fingerd-scale-demo.html
├── scroll-to-x.html
├── fingerd-number.html
├── simulation-event-demo.html
├── load-more-demo.html
├── simulation-y-demo-vue.html
├── pull-down-demo.html
├── mover-demo.html
├── slide-with-scroll.html
├── contacts.html
├── fmover-slide-y.html
├── fmover-slide-x.html
└── index.html
├── .eslintrc.js
├── package.json
├── README.md
└── dist
└── finger-mover.min.js
/.eslintignore:
--------------------------------------------------------------------------------
1 | css*
2 | build
3 | dist
--------------------------------------------------------------------------------
/src/plugins/picker/README.md:
--------------------------------------------------------------------------------
1 | ## fmover-slide-y
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | *.log
4 | .history
5 | coverage
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015"],
3 | "ignore": [
4 | "dist/**/*.js"
5 | ]
6 | }
--------------------------------------------------------------------------------
/circle.yml:
--------------------------------------------------------------------------------
1 | machine:
2 | node:
3 | version: 6
4 |
5 | test:
6 | override:
7 | - bash build/ci.sh
8 |
--------------------------------------------------------------------------------
/test/index.unit.js:
--------------------------------------------------------------------------------
1 | const testsContext = require.context('./', true, /\.spec$/)
2 | testsContext.keys().forEach(testsContext)
--------------------------------------------------------------------------------
/src/moved/README.md:
--------------------------------------------------------------------------------
1 | ## Moved
2 |
3 | Document address: [https://fmover.hcysun.me/#/zh-cn/package/moved](https://fmover.hcysun.me/#/zh-cn/package/moved)
--------------------------------------------------------------------------------
/src/fingerd/README.md:
--------------------------------------------------------------------------------
1 | ## Fingerd
2 |
3 | Document address: [https://fmover.hcysun.me/#/zh-cn/package/fingerd](https://fmover.hcysun.me/#/zh-cn/package/fingerd)
--------------------------------------------------------------------------------
/src/plugins/fmover-slide-x/README.md:
--------------------------------------------------------------------------------
1 | ## fmover-slide-x
2 |
3 | Document address: [https://fmover.hcysun.me/#/zh-cn/plugins/fmover-slide-x](https://fmover.hcysun.me/#/zh-cn/plugins/fmover-slide-x)
--------------------------------------------------------------------------------
/src/plugins/fmover-slide-y/README.md:
--------------------------------------------------------------------------------
1 | ## fmover-slide-y
2 |
3 | Document address: [https://fmover.hcysun.me/#/zh-cn/plugins/fmover-slide-y](https://fmover.hcysun.me/#/zh-cn/plugins/fmover-slide-y)
--------------------------------------------------------------------------------
/src/plugins/simulation-scroll-x/README.md:
--------------------------------------------------------------------------------
1 | ## simulation-scroll-x
2 |
3 | Document address: [https://fmover.hcysun.me/#/zh-cn/plugins/simulation-scroll-x](https://fmover.hcysun.me/#/zh-cn/plugins/simulation-scroll-x)
--------------------------------------------------------------------------------
/src/plugins/simulation-scroll-y/README.md:
--------------------------------------------------------------------------------
1 | ## simulation-scroll-y
2 |
3 | Document address: [https://fmover.hcysun.me/#/zh-cn/plugins/simulation-scroll-y](https://fmover.hcysun.me/#/zh-cn/plugins/simulation-scroll-y)
--------------------------------------------------------------------------------
/demo/vue-component/simulation-scroll-y/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from 'demo/simulation-scroll-y/app'
3 |
4 | Vue.config.productionTip = false
5 |
6 | new Vue({
7 | el: '#main',
8 | template: '',
9 | components: {
10 | App
11 | }
12 | })
--------------------------------------------------------------------------------
/src/moved/tw.js:
--------------------------------------------------------------------------------
1 | const TW = {
2 | easeOutStrong: function (t, b, c, d) {
3 | return -c * ((t = t / d - 1) * t * t * t - 1) + b
4 | },
5 | backOut: function (t, b, c, d, s) {
6 | if (typeof s === 'undefined') {
7 | s = 0.7
8 | }
9 | return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b
10 | }
11 | }
12 |
13 | export default TW
--------------------------------------------------------------------------------
/demo/vue-component/simulation-scroll-y/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 | simulation-scroll-y & Vue component
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/moved/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "moved",
3 | "version": "1.4.3",
4 | "description": "Miniature motion solutions",
5 | "main": "dist/moved.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/HcySunYang/finger-mover.git"
9 | },
10 | "keywords": [
11 | "move",
12 | "moved",
13 | "Animation"
14 | ],
15 | "author": "HcySunYang",
16 | "license": "MIT",
17 | "bugs": {
18 | "url": "https://github.com/HcySunYang/finger-mover/issues"
19 | },
20 | "homepage": "https://github.com/HcySunYang/finger-mover/blob/master/src/moved/README.md"
21 | }
22 |
--------------------------------------------------------------------------------
/src/plugins/picker/picker.js:
--------------------------------------------------------------------------------
1 | export default function (options) {
2 |
3 | return function (Fmover) {
4 | const {
5 | Moved
6 | } = Fmover
7 |
8 | return {
9 | init (fmover) {
10 |
11 | },
12 | start (fingerd) {
13 |
14 | },
15 | move (fingerd) {
16 |
17 | },
18 | end (fingerd) {
19 |
20 | },
21 | cancel (fingerd) {
22 |
23 | }
24 |
25 | }
26 |
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/src/plugins/picker/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "picker",
3 | "version": "1.0.1",
4 | "description": "javascript picker inspired by ios UIPickerView",
5 | "main": "dist/picker.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/HcySunYang/finger-mover.git"
9 | },
10 | "keywords": [
11 | "plugin",
12 | "picker",
13 | "finger-mover"
14 | ],
15 | "author": "HcySunYang",
16 | "license": "MIT",
17 | "bugs": {
18 | "url": "https://github.com/HcySunYang/finger-mover/issues"
19 | },
20 | "homepage": "https://github.com/HcySunYang/finger-mover/blob/master/src/plugins/picker/README.md"
21 | }
22 |
--------------------------------------------------------------------------------
/src/fingerd/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fingerd",
3 | "version": "1.4.3",
4 | "description": "A development kit for finger unit event management in mobile development",
5 | "main": "dist/fingerd.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/HcySunYang/finger-mover.git"
9 | },
10 | "keywords": [
11 | "event",
12 | "finger",
13 | "fingerd"
14 | ],
15 | "author": "HcySunYang",
16 | "license": "MIT",
17 | "bugs": {
18 | "url": "https://github.com/HcySunYang/finger-mover/issues"
19 | },
20 | "homepage": "https://github.com/HcySunYang/finger-mover/blob/master/src/fingerd/README.md"
21 | }
22 |
--------------------------------------------------------------------------------
/src/plugins/fmover-slide-x/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fmover-slide-x",
3 | "version": "1.4.3",
4 | "description": "finger-mover horizontal slideshow plugin",
5 | "main": "dist/fmover-slide-x.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/HcySunYang/finger-mover.git"
9 | },
10 | "keywords": [
11 | "plugin",
12 | "slide",
13 | "swiper",
14 | "finger-mover"
15 | ],
16 | "author": "HcySunYang",
17 | "license": "MIT",
18 | "bugs": {
19 | "url": "https://github.com/HcySunYang/finger-mover/issues"
20 | },
21 | "homepage": "https://github.com/HcySunYang/finger-mover/blob/master/src/plugins/fmover-slide-x/README.md"
22 | }
23 |
--------------------------------------------------------------------------------
/src/plugins/fmover-slide-y/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fmover-slide-y",
3 | "version": "1.4.3",
4 | "description": "finger-mover vertical slideshow plugin",
5 | "main": "dist/fmover-slide-y.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/HcySunYang/finger-mover.git"
9 | },
10 | "keywords": [
11 | "plugin",
12 | "slide",
13 | "swiper",
14 | "finger-mover"
15 | ],
16 | "author": "HcySunYang",
17 | "license": "MIT",
18 | "bugs": {
19 | "url": "https://github.com/HcySunYang/finger-mover/issues"
20 | },
21 | "homepage": "https://github.com/HcySunYang/finger-mover/blob/master/src/plugins/fmover-slide-y/README.md"
22 | }
23 |
--------------------------------------------------------------------------------
/src/plugins/simulation-scroll-x/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "simulation-scroll-x",
3 | "version": "1.4.3",
4 | "description": "Horizontal scroll simulation solution on mobile device.",
5 | "main": "dist/simulation-scroll-x.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/HcySunYang/finger-mover.git"
9 | },
10 | "keywords": [
11 | "scroll",
12 | "simulation",
13 | "finger-mover"
14 | ],
15 | "author": "HcySunYang",
16 | "license": "MIT",
17 | "bugs": {
18 | "url": "https://github.com/HcySunYang/finger-mover/issues"
19 | },
20 | "homepage": "https://github.com/HcySunYang/finger-mover/blob/master/src/plugins/simulation-scroll-x/README.md"
21 | }
22 |
--------------------------------------------------------------------------------
/src/plugins/simulation-scroll-y/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "simulation-scroll-y",
3 | "version": "1.4.3",
4 | "description": "Vertical scroll simulation solution on mobile device.",
5 | "main": "dist/simulation-scroll-y.js",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/HcySunYang/finger-mover.git"
9 | },
10 | "keywords": [
11 | "scroll",
12 | "simulation",
13 | "finger-mover"
14 | ],
15 | "author": "HcySunYang",
16 | "license": "MIT",
17 | "bugs": {
18 | "url": "https://github.com/HcySunYang/finger-mover/issues"
19 | },
20 | "homepage": "https://github.com/HcySunYang/finger-mover/blob/master/src/plugins/simulation-scroll-y/README.md"
21 | }
22 |
--------------------------------------------------------------------------------
/src/moved/animationframe.js:
--------------------------------------------------------------------------------
1 | import {
2 | requestAnim,
3 | cancelAnim,
4 | now
5 | } from '../shared/util'
6 |
7 | export default class Animationframe {
8 | constructor (handle) {
9 | this.handle = handle
10 | this.id = 0
11 | this._init()
12 | }
13 |
14 | _init () {
15 | this.start = now()
16 | this.request()
17 | }
18 |
19 | _fakeHandle () {
20 | let times = now() - this.start
21 |
22 | this.handle(times)
23 | }
24 |
25 | _requestAnimFn (handle) {
26 | if (requestAnim) {
27 | return requestAnim(handle)
28 | } else {
29 | return setTimeout(handle, 1000 / 60)
30 | }
31 | }
32 |
33 | _cancelAnimFn (id) {
34 | if (cancelAnim) {
35 | cancelAnim(id)
36 | } else {
37 | clearTimeout(id)
38 | }
39 | }
40 |
41 | request () {
42 | this.id = this._requestAnimFn(this._fakeHandle.bind(this))
43 | }
44 |
45 | cancel () {
46 | this._cancelAnimFn(this.id)
47 | }
48 | }
--------------------------------------------------------------------------------
/demo/mover-easy-demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 | Moved Demo
8 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/demo/vue-component/simulation-scroll-y/app.vue:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
51 |
52 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/demo/fingerd-demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 | Finger Demo
8 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | parser: 'babel-eslint',
4 | // required to lint *.vue files
5 | plugins: [
6 | 'html'
7 | ],
8 | "env": {
9 | "browser": true,
10 | "es6": true
11 | },
12 | "parserOptions": {
13 | "sourceType": "module"
14 | },
15 | "rules": {
16 | "indent": [
17 | "error",
18 | 4,
19 | {
20 | "SwitchCase": 1
21 | }
22 | ],
23 | "quotes": [
24 | "error",
25 | "single"
26 | ],
27 | "semi": [
28 | "error",
29 | "never"
30 | ],
31 | "no-dupe-args": "error",
32 | "no-extra-semi": "error",
33 | "no-multi-spaces": "error",
34 | "no-redeclare": "error",
35 | "comma-spacing": [
36 | "error",
37 | {
38 | "before": false,
39 | "after": true
40 | }
41 | ],
42 | "func-call-spacing": "error",
43 | "key-spacing": [
44 | "error",
45 | {
46 | "beforeColon": false,
47 | "afterColon": true,
48 | "mode": "strict"
49 | }
50 | ],
51 | "keyword-spacing": [
52 | "error",
53 | ],
54 | "space-before-blocks": "error",
55 | "space-before-function-paren": [
56 | "error",
57 | {
58 | "anonymous": "always",
59 | "named": "always",
60 | "asyncArrow": "always"
61 | }
62 | ],
63 | "space-infix-ops": "error",
64 | "space-unary-ops": [
65 | "error",
66 | {
67 | "words": true,
68 | "nonwords": false
69 | }
70 | ],
71 | "arrow-spacing": "error",
72 | "constructor-super": "error",
73 | "no-const-assign": "error",
74 | "no-this-before-super": "error",
75 | "no-var": "error"
76 | }
77 | }
--------------------------------------------------------------------------------
/demo/simulation-y-demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 | simulation-scroll-y demo
8 |
33 |
34 |
35 |
36 |
37 |
38 |
43 |
44 |
45 |
46 |
63 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/demo/simulation-x-demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 | simulation-scroll-x demo
8 |
34 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
46 |
47 |
64 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/demo/2d-scroll-demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 | 2D scroll demo
8 |
34 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
46 |
47 |
48 |
65 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/demo/scroll-to-y.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 | scroll-to-y demo
8 |
33 |
34 |
35 |
36 |
37 |
38 |
43 |
44 |
45 |
46 |
64 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/demo/fingerd-scale-demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 | Scale Demo
8 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | Zoom gestures in the blue area
44 | (译:在蓝色区域进行缩放手势操作)
45 |
46 |
47 |
48 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/demo/scroll-to-x.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 | scroll-to-x demo
8 |
40 |
41 |
42 |
43 |
44 |
45 |
50 |
51 |
52 |
53 |
71 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/demo/fingerd-number.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 | fingerNumber Demo
8 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | Touch and slide out of the blue area, observe the difference between native event.touches.length and fingerNumber
36 | (译:手持触摸蓝色区域,并划出蓝色区域,观察原生 event.touches.length 与 fingerNumber 的区别)
37 |
38 |
39 |
40 |
41 |
42 |
43 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/test/unit/index.spec.js:
--------------------------------------------------------------------------------
1 | import Fmover from 'Fmover'
2 |
3 | describe('Initialization', () => {
4 | describe('Whether to use new', () => {
5 | it('Do not use new', () => {
6 | let isWarned = false
7 | try {
8 | Fmover()
9 | } catch (e) {
10 | if (e.toString() === 'TypeError: Cannot call a class as a function') {
11 | isWarned = true
12 | }
13 | }
14 | expect(isWarned).toBe(true)
15 | })
16 | describe('Use new', () => {
17 | describe('parameter:opt.el', () => {
18 | it('The opt.el parameter is not passed', () => {
19 | let isWarned = false
20 | try {
21 | new Fmover()
22 | } catch (e) {
23 | if (e.toString() === 'TypeError: This is an invalid selector: undefined') {
24 | isWarned = true
25 | }
26 | }
27 | expect(isWarned).toBe(true)
28 | })
29 |
30 | it('Pass the opt.el parameter', () => {
31 | let isWarned = false
32 | let dom = document.createElement('div')
33 | dom.id = 'test'
34 | document.body.appendChild(dom)
35 | try {
36 | new Fmover({
37 | el: '#test'
38 | })
39 | } catch (e) {
40 | isWarned = true
41 | }
42 | expect(isWarned).toBe(false)
43 | })
44 | })
45 |
46 | describe('parameter:opt.plugins', () => {
47 | it('Pass the opt.plugins parameter', () => {
48 | let testPlugin = function () {
49 | return function () {
50 | return {
51 | init: function (fmover) {
52 | expect(fmover instanceof Fmover).toBe(true)
53 | }
54 | }
55 | }
56 | }
57 | let isWarned = false
58 | let dom = document.createElement('div')
59 | dom.id = 'test2'
60 | document.body.appendChild(dom)
61 |
62 | new Fmover({
63 | el: '#test2',
64 | plugins: [
65 | testPlugin()
66 | ]
67 | })
68 |
69 | })
70 |
71 | })
72 | })
73 | })
74 |
75 | })
--------------------------------------------------------------------------------
/demo/simulation-event-demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 | event demo
8 |
33 |
34 |
35 |
36 |
37 |
38 |
43 |
44 |
45 |
46 |
63 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/test/unit/util.spec.js:
--------------------------------------------------------------------------------
1 | import * as util from 'util'
2 | let dom = null
3 | describe('Detection tool function', () => {
4 |
5 | beforeEach(() => {
6 | dom = document.createElement('div')
7 | document.body.appendChild(dom)
8 | })
9 |
10 | afterEach(() => {
11 | dom.parentNode.removeChild(dom)
12 | })
13 |
14 | describe('toArray', () => {
15 | it('If the argument is a array-like then the return value should also be an array', () => {
16 | let fakeArray = {
17 | 0: 'a',
18 | 1: 'b',
19 | 2: 'c',
20 | length: 3
21 | }
22 | let val = util.toArray(fakeArray)
23 | expect(Array.isArray(val)).toBe(true)
24 | })
25 |
26 | it('If the argument is an array, the array is returned directly', () => {
27 | let arr = [1, 2, 3]
28 | let val = util.toArray(arr)
29 | expect(Array.isArray(val)).toBe(true)
30 | })
31 | })
32 |
33 | describe('parentNode', () => {
34 | it('Gets the parent of the element', () => {
35 | let val = util.parentNode(dom)
36 | expect((dom === null || dom instanceof Element)).toBe(true)
37 | })
38 | })
39 |
40 | describe('getAbsMaxFromArray', () => {
41 | it('Gets the maximum value in the array', () => {
42 | let arr = [1, 2, 3, 4, 5]
43 | let val = util.getAbsMaxFromArray(arr)
44 | expect(val).toBe(5)
45 | })
46 | })
47 |
48 | describe('is3DMatrix', () => {
49 | it('Determines whether the element applies the 3d transform', () => {
50 | let val
51 |
52 | dom.style.webkitTransform = 'rotateX(30deg)'
53 | val = util.is3DMatrix(dom)
54 | expect(val).toBe(true)
55 |
56 | dom.style.webkitTransform = 'rotateZ(30deg)'
57 | val = util.is3DMatrix(dom)
58 | expect(val).toBe(false)
59 | })
60 | })
61 |
62 | describe('getRelativeRect', () => {
63 | it('The distance from the element to the positioning parent should match the expectation', () => {
64 | dom.style.cssText = 'margin: 100px; width: 50px; height: 50px;'
65 | document.body.style.cssText = 'position: absolute;'
66 | let val = util.getRelativeRect(document.body, dom)
67 | expect(val.top).toBe(100)
68 | expect(val.left).toBe(100)
69 | })
70 | })
71 |
72 | describe('isInElement', () => {
73 | it('The positional relationship between elements should be in line with expectations', () => {
74 | let val
75 |
76 | val = util.isInElement(document.body, dom)
77 | expect(val).toBe(true)
78 | val = util.isInElement(dom, document.body)
79 | expect(val).toBe(false)
80 | })
81 | })
82 | })
--------------------------------------------------------------------------------
/demo/load-more-demo.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 | Load more demo
8 |
39 |
40 |
41 |
42 |
43 |
44 |
51 |
52 |
53 |
54 |
71 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/src/vue-component/simulation-scroll-y.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
100 |
--------------------------------------------------------------------------------
/src/moved/moved.js:
--------------------------------------------------------------------------------
1 | import TW from './tw'
2 | import {
3 | getStyle,
4 | transform,
5 | getPropFromMatrix
6 | } from '../shared/util'
7 | import Animationframe from './animationframe'
8 |
9 | const MOVE_STATUS = {
10 | start: 'start',
11 | stop: 'stop'
12 | }
13 |
14 | let cid = 0
15 | export default class Moved {
16 | constructor () {
17 | this.moveStatus = MOVE_STATUS.stop
18 | this.isArrivals = false
19 | /* istanbul ignore if */
20 | if (!(this instanceof Moved)) {
21 | throwError('Moved is a constructor and should be called with the `new` keyword')
22 | }
23 | }
24 |
25 | start (options) {
26 | if (this.moveStatus === MOVE_STATUS.start) {
27 | return
28 | }
29 | options = options ? options : {}
30 | let {el, target, type, time, endCallBack, inCallBack, s} = options
31 | this.isArrivals = false
32 | this.id = cid++
33 | this.el = el
34 | this.target = target
35 | this.type = type || 'easeOutStrong'
36 | this.time = time <= 1 ? 1 : time
37 | this.endCallBack = endCallBack
38 | this.inCallBack = inCallBack
39 | this.currentPos = {}
40 | this.moveStatus = MOVE_STATUS.start
41 |
42 | this.b = {}
43 | this.c = {}
44 | this.d = this.time
45 | this.s = s
46 | for (let attr in this.target) {
47 | this.b[attr] = getPropFromMatrix(this.el)[attr]
48 | this.c[attr] = this.target[attr] - this.b[attr]
49 | if (this.c[attr] === 0) {
50 | this.isArrivals = true
51 | }
52 | }
53 | if (this.isArrivals) {
54 | this.endCallBack && this.endCallBack(this.b)
55 | this.moveStatus = MOVE_STATUS.stop
56 | return false
57 | }
58 |
59 | this.anim = new Animationframe(this._moveHandle.bind(this))
60 | }
61 |
62 | stop (callback) {
63 | if (this.moveStatus === MOVE_STATUS.stop || !this.anim) {
64 | return this
65 | }
66 | this.moveStatus = MOVE_STATUS.stop
67 | this.anim.cancel()
68 | for (let attr in this.target) {
69 | transform(this.el, attr, this.currentPos[attr])
70 | }
71 | callback && callback(this.currentPos)
72 | return this
73 | }
74 |
75 | transform (el, attr, val) {
76 | transform(el, attr, val)
77 | }
78 |
79 | getPropFromMatrix (el) {
80 | return getPropFromMatrix(el)
81 | }
82 |
83 | _moveHandle (t) {
84 | t = t >= this.d ? this.d : t
85 | for (let attr in this.target) {
86 | this.currentPos[attr] = Moved.Tween[this.type](t, this.b[attr], this.c[attr], this.d, this.s)
87 | transform(this.el, attr, this.currentPos[attr])
88 | }
89 | this.moveStatus = MOVE_STATUS.start
90 | this.inCallBack && this.inCallBack.call(this, this.currentPos)
91 |
92 | if (t >= this.d) {
93 | this.stop(this.endCallBack)
94 | } else {
95 | this.anim.request()
96 | }
97 | }
98 | }
99 |
100 | Moved.Tween = TW
101 |
--------------------------------------------------------------------------------
/demo/simulation-y-demo-vue.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Vue & simulation-scroll-y demo
7 |
32 |
33 |
34 |
35 |
36 |
37 |
44 |
45 |
46 |
47 |
48 |
67 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/src/plugins/simulation-scroll-x/dist/simulation-scroll-x.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * simulation-scroll-x.min.js v1.4.2
3 | * (c) 2018 HcySunYang
4 | * Released under the MIT License.
5 | */!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):n.simulationScrollX=t()}(this,function(){"use strict";return function(n){return function(t){function e(n,t){if(b)return void s(b,"width: "+t+"px;");b=document.createElement("span"),s(b,"\n position: absolute;\n z-index: 10000000;\n left:0;\n bottom: 3px;\n height: 3px; \n width: "+t+"px; \n background-color: #000;\n opacity: 0;\n border-radius: 1.5px;\n transition: opacity .2s;\n -webkit-transition: opacity .2s;\n "),"static"===a(n,"position")&&s(n,"position: relative;"),n.appendChild(b)}function o(n){var t=n,e=0;tM-S&&(e=M-S),t=X):t>T&&(e=4*(t-T),e>M-S&&(e=M-S),t=T+e);var o=M-e;b.style.width=o+"px",w.transform(b,"translateX",t)}var r=t.Moved,a=t.getStyle,i=t.extend,s=t.cssText,c=t.getRelativeRect,l=t.isInElement,u=t.throwError,f=function(){},p=i({scrollBar:!0,bounce:!0,onTouchMove:f,onTransMove:f,onTransMoveEnd:f,onMotionStop:f},n),d=null,m=null,h=0,v=0,g=0,b=null,M=0,S=7,x=0,y=0,X=0,T=0,w=new r,k=0,B=0,E=0,O="easeOutStrong",I=0,z=!1,C=!1;return{init:function(n){d=n.el,m=d.parentNode,"static"===a(d,"position")&&s(d,"position: relative; z-index: 10;"),this.refreshSize()},start:function(n){n.fingers[0];O="easeOutStrong",z=!1,C=!1,w.stop(function(n){k=n.translateX,p.onMotionStop(k)})},move:function(n){if("start"===w.moveStatus)return!1;var t=n.fingers[0],e=t.fingerInElement;if(B=k+t.distanceX,!e)return C||(C=!0,this.makeMove(t)),!1;B>x||y>0?B=p.bounce?.5*B:x:B2e3&&(o=2e3),o}var e;I=n.transTime,k=B,E=k+n.transDistanceX,k>x||y>0?(E=x,O="easeOutStrong",I=p.bounce?500:n.transTime,z=!0):kx&&(p.bounce?(E=x,O="backOut",I=t(x)):O="easeOutStrong"),Math.abs(n.transDistanceX)>100||z?this.wrapMove(E,I,O,e):p.scrollBar&&s(b,"opacity: 0;")},wrapMove:function(n,t,e,r){w.start({el:d,target:{translateX:n},type:e,time:t,s:r,inCallBack:function(n){k=n.translateX,p.bounce||(k>=x&&w.stop(function(n){k=x,w.transform(d,"translateX",k)}),k<=y&&w.stop(function(n){k=y,w.transform(d,"translateX",y)})),p.scrollBar&&o(-n.translateX*g),p.onTransMove.call(this,k)},endCallBack:function(n){k=n.translateX,p.onTransMoveEnd.call(this,k),p.onMotionStop(k),p.scrollBar&&s(b,"opacity: 0;")}})},scrollTo:function(n,t,e){var o;"string"==typeof n?o=document.querySelector(n):n instanceof Element&&(o=n),o&&(l(d,o)||u("ScrollTo function argument error, `child` must be a child of `parent`"),n=-c(d,o).left),e&&n>=x?n=x:e&&y<0&&n=0&&(n=x),k=n,this.wrapMove(n,t,"easeOutStrong")},refreshSize:function(){h=parseFloat(a(d,"width")),v=m.clientWidth,y=v-h,x=0,y>0&&(p.scrollBar=!1),p.scrollBar&&(g=v/h,M=v*g,S=M6;return n.translateX=i?r[12]:r[4],n.translateY=i?r[13]:r[5],n.translateZ=i?r[14]:0,n.scaleX=void 0!==e.transform.scaleX?e.transform.scaleX:1,n.scaleY=void 0!==e.transform.scaleY?e.transform.scaleY:1,n.scaleZ=void 0!==e.transform.scaleZ?e.transform.scaleZ:1,n.rotateX=void 0!==e.transform.rotateX?e.transform.rotateX:0,n.rotateY=void 0!==e.transform.rotateY?e.transform.rotateY:0,n.rotateZ=void 0!==e.transform.rotateZ?e.transform.rotateZ:0,n.skewX=void 0!==e.transform.skewX?e.transform.skewX:0,n.skewY=void 0!==e.transform.skewY?e.transform.skewY:0,n}var n={easeOutStrong:function(t,e,r,s){return-r*((t=t/s-1)*t*t*t-1)+e},backOut:function(t,e,r,s,a){return void 0===a&&(a=.7),r*((t=t/s-1)*t*((a+1)*t+a)+1)+e}},i=requestAnimationFrame||webkitRequestAnimationFrame,o=cancelAnimationFrame||webkitCancelAnimationFrame,c=function(t){this.handle=t,this.id=0,this._init()};c.prototype._init=function(){this.start=e(),this.request()},c.prototype._fakeHandle=function(){var t=e()-this.start;this.handle(t)},c.prototype._requestAnimFn=function(t){return i?i(t):setTimeout(t,1e3/60)},c.prototype._cancelAnimFn=function(t){o?o(t):clearTimeout(t)},c.prototype.request=function(){this.id=this._requestAnimFn(this._fakeHandle.bind(this))},c.prototype.cancel=function(){this._cancelAnimFn(this.id)};var l={start:"start",stop:"stop"},u=0,f=function t(){this.moveStatus=l.stop,this.isArrivals=!1,this instanceof t||throwError("Moved is a constructor and should be called with the `new` keyword")};return f.prototype.start=function(t){var e=this;if(this.moveStatus!==l.start){t=t||{};var r=t.el,s=t.target,n=t.type,i=t.time,o=t.endCallBack,f=t.inCallBack,h=t.s;this.isArrivals=!1,this.id=u++,this.el=r,this.target=s,this.type=n||"easeOutStrong",this.time=i<=1?1:i,this.endCallBack=o,this.inCallBack=f,this.currentPos={},this.moveStatus=l.start,this.b={},this.c={},this.d=this.time,this.s=h;for(var m in e.target)e.b[m]=a(e.el)[m],e.c[m]=e.target[m]-e.b[m],0===e.c[m]&&(e.isArrivals=!0);if(this.isArrivals)return this.endCallBack&&this.endCallBack(this.b),this.moveStatus=l.stop,!1;this.anim=new c(this._moveHandle.bind(this))}},f.prototype.stop=function(t){var e=this;if(this.moveStatus===l.stop||!this.anim)return this;this.moveStatus=l.stop,this.anim.cancel();for(var r in e.target)s(e.el,r,e.currentPos[r]);return t&&t(this.currentPos),this},f.prototype.transform=function(t,e,r){s(t,e,r)},f.prototype.getPropFromMatrix=function(t){return a(t)},f.prototype._moveHandle=function(t){var e=this;t=t>=this.d?this.d:t;for(var r in e.target)e.currentPos[r]=f.Tween[e.type](t,e.b[r],e.c[r],e.d,e.s),s(e.el,r,e.currentPos[r]);this.moveStatus=l.start,this.inCallBack&&this.inCallBack.call(this,this.currentPos),t>=this.d?this.stop(this.endCallBack):this.anim.request()},f.Tween=n,f});
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | 
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | ## Intro
13 |
14 | `finger-mover` is a motion effect library that integrates
15 | [Fingerd (a development kit for finger unit event management in mobile development)](https://fmover.hcysun.me/#/package/fingerd)
16 | and
17 | [Moved (a micro movement framework)](https://fmover.hcysun.me/#/package/moved). `finger-mover` provides many useful plugins, such as [Vertical scroll simulation (simulation-scroll-y.js)](https://fmover.hcysun.me/#/plugins/simulation-scroll-y), [Horizontal scroll simulation (simulation-scroll-x.js)](https://fmover.hcysun.me/#/plugins/simulation-scroll-x) and so on.
18 |
19 | ## Docs
20 |
21 | [English](https://fmover.hcysun.me/#/home) • [中文文档](https://fmover.hcysun.me/#/zh-cn/)
22 |
23 | ## Features
24 |
25 | * Just 11.12KB after compression
26 |
27 | * Plugin support, motion components are available as plug-ins, thsi is a plug-in list:
28 | * [Vertical scroll simulation](https://fmover.hcysun.me/#/plugins/simulation-scroll-y)
29 | * [Horizontal scroll simulation](https://fmover.hcysun.me/#/plugins/simulation-scroll-x)
30 | * [2D scrolling](https://fmover.hcysun.me/#/plugins/2d-scroll)
31 | * [Horizontal slide show](https://fmover.hcysun.me/#/plugins/fmover-slide-x)
32 | * [Vertical slide show](https://fmover.hcysun.me/#/plugins/fmover-slide-y)
33 |
34 | ## Install
35 |
36 | #### NPM
37 |
38 | ```
39 | npm install --save finger-mover
40 | ```
41 |
42 | #### yarn
43 |
44 | ```
45 | yarn add finger-mover
46 | ```
47 |
48 | `finger-mover` released as a `umd` module. You can use it in any way for your favorite. You can get global variable `Fmover` by serving as `
45 |
46 |
47 |
48 |
55 |
56 |
57 |
58 |
75 |
115 |
116 |
117 |