Skip to content

Commit 03dcdde

Browse files
committed
Extract module
1 parent b11f2cf commit 03dcdde

File tree

2 files changed

+102
-106
lines changed

2 files changed

+102
-106
lines changed

modules/backends/HTML5.js

Lines changed: 7 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import { DragSource } from 'dnd-core';
22
import NativeTypes from '../NativeTypes';
33
import EnterLeaveCounter from '../utils/EnterLeaveCounter';
4+
import createMonotonicInterpolant from '../utils/createMonotonicInterpolant';
45
import shallowEqual from '../utils/shallowEqual';
56
import defaults from 'lodash/object/defaults';
7+
import memoize from 'lodash/function/memoize';
68
import invariant from 'react/lib/invariant';
79
import warning from 'react/lib/warning';
810

11+
const isSafari = memoize(() => Boolean(window.safari));
12+
const isFirefox = memoize(() => /firefox/i.test(navigator.userAgent));
13+
914
function isUrlDataTransfer(dataTransfer) {
1015
var types = Array.prototype.slice.call(dataTransfer.types);
1116
return types.indexOf('Url') > -1 || types.indexOf('text/uri-list') > -1;
@@ -40,110 +45,6 @@ function getMouseEventOffsets(e, sourceNode, dragPreview) {
4045
return { offsetFromClient, offsetFromSource, offsetFromDragPreview };
4146
}
4247

43-
function isDesktopSafari() {
44-
return !!window.safari;
45-
}
46-
47-
function isFirefox() {
48-
return /firefox/i.test(navigator.userAgent);
49-
}
50-
51-
/**
52-
* I took this straight from Wikipedia, it must be good!
53-
*/
54-
function createMonotonicInterpolant(xs, ys) {
55-
const length = xs.length;
56-
57-
// Rearrange xs and ys so that xs is sorted
58-
const indexes = [];
59-
for (let i = 0; i < length; i++) {
60-
indexes.push(i);
61-
}
62-
indexes.sort((a, b) => xs[a] < xs[b] ? -1 : 1);
63-
64-
const oldXs = xs, oldYs = ys;
65-
// Impl: Creating new arrays also prevents problems if the input arrays are mutated later
66-
xs = [];
67-
ys = [];
68-
// Impl: Unary plus properly converts values to numbers
69-
for (let i = 0; i < length; i++) {
70-
xs.push(+oldXs[indexes[i]]);
71-
ys.push(+oldYs[indexes[i]]);
72-
}
73-
74-
// Get consecutive differences and slopes
75-
const dys = [];
76-
const dxs = [];
77-
const ms = [];
78-
let dx, dy;
79-
for (let i = 0; i < length - 1; i++) {
80-
dx = xs[i + 1] - xs[i];
81-
dy = ys[i + 1] - ys[i];
82-
dxs.push(dx);
83-
dys.push(dy);
84-
ms.push(dy / dx);
85-
}
86-
87-
// Get degree-1 coefficients
88-
const c1s = [ms[0]];
89-
for (let i = 0; i < dxs.length - 1; i++) {
90-
const m = ms[i];
91-
const mNext = ms[i + 1];
92-
if (m * mNext <= 0) {
93-
c1s.push(0);
94-
} else {
95-
dx = dxs[i];
96-
const dxNext = dxs[i + 1];
97-
const common = dx + dxNext;
98-
c1s.push(3 * common / ((common + dxNext) / m + (common + dx) / mNext));
99-
}
100-
}
101-
c1s.push(ms[ms.length - 1]);
102-
103-
// Get degree-2 and degree-3 coefficients
104-
const c2s = [];
105-
const c3s = [];
106-
let m;
107-
for (let i = 0; i < c1s.length - 1; i++) {
108-
m = ms[i];
109-
const c1 = c1s[i];
110-
const invDx = 1 / dxs[i];
111-
const common = c1 + c1s[i + 1] - m - m;
112-
c2s.push((m - c1 - common) * invDx);
113-
c3s.push(common * invDx * invDx);
114-
}
115-
116-
// Return interpolant function
117-
return function (x) {
118-
// The rightmost point in the dataset should give an exact result
119-
let i = xs.length - 1;
120-
if (x === xs[i]) {
121-
return ys[i];
122-
}
123-
124-
// Search for the interval x is in, returning the corresponding y if x is one of the original xs
125-
let low = 0;
126-
let high = c3s.length - 1;
127-
let mid;
128-
while (low <= high) {
129-
mid = Math.floor(0.5 * (low + high));
130-
const xHere = xs[mid];
131-
if (xHere < x) {
132-
low = mid + 1;
133-
} else if (xHere > x) {
134-
high = mid - 1;
135-
} else {
136-
return ys[mid];
137-
}
138-
}
139-
i = Math.max(0, high);
140-
141-
// Interpolate
142-
const diff = x - xs[i], diffSq = diff * diff;
143-
return ys[i] + c1s[i] * diff + c2s[i] * diffSq + c3s[i] * diff * diffSq;
144-
};
145-
}
146-
14748
function getDragPreviewOffset(sourceNode, dragPreview, offsetFromDragPreview, anchorPoint) {
14849
const { offsetWidth: sourceWidth, offsetHeight: sourceHeight } = sourceNode;
14950
const { anchorX, anchorY } = anchorPoint;
@@ -153,7 +54,7 @@ function getDragPreviewOffset(sourceNode, dragPreview, offsetFromDragPreview, an
15354
let dragPreviewHeight = isImage ? dragPreview.height : sourceHeight;
15455

15556
// Work around @2x coordinate discrepancies in browsers
156-
if (isDesktopSafari() && isImage) {
57+
if (isSafari() && isImage) {
15758
dragPreviewHeight /= window.devicePixelRatio;
15859
dragPreviewWidth /= window.devicePixelRatio;
15960
} else if (isFirefox() && !isImage) {
@@ -183,7 +84,7 @@ function getDragPreviewOffset(sourceNode, dragPreview, offsetFromDragPreview, an
18384
let y = interpolateY(anchorY);
18485

18586
// Work around Safari 8 positioning bug
186-
if (isDesktopSafari() && isImage) {
87+
if (isSafari() && isImage) {
18788
// We'll have to wait for @3x to see if this is entirely correct
18889
y += (window.devicePixelRatio - 1) * dragPreviewHeight;
18990
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/**
2+
* I took this straight from Wikipedia, it must be good!
3+
*/
4+
export default function createMonotonicInterpolant(xs, ys) {
5+
const length = xs.length;
6+
7+
// Rearrange xs and ys so that xs is sorted
8+
const indexes = [];
9+
for (let i = 0; i < length; i++) {
10+
indexes.push(i);
11+
}
12+
indexes.sort((a, b) => xs[a] < xs[b] ? -1 : 1);
13+
14+
const oldXs = xs, oldYs = ys;
15+
// Impl: Creating new arrays also prevents problems if the input arrays are mutated later
16+
xs = [];
17+
ys = [];
18+
// Impl: Unary plus properly converts values to numbers
19+
for (let i = 0; i < length; i++) {
20+
xs.push(+oldXs[indexes[i]]);
21+
ys.push(+oldYs[indexes[i]]);
22+
}
23+
24+
// Get consecutive differences and slopes
25+
const dys = [];
26+
const dxs = [];
27+
const ms = [];
28+
let dx, dy;
29+
for (let i = 0; i < length - 1; i++) {
30+
dx = xs[i + 1] - xs[i];
31+
dy = ys[i + 1] - ys[i];
32+
dxs.push(dx);
33+
dys.push(dy);
34+
ms.push(dy / dx);
35+
}
36+
37+
// Get degree-1 coefficients
38+
const c1s = [ms[0]];
39+
for (let i = 0; i < dxs.length - 1; i++) {
40+
const m = ms[i];
41+
const mNext = ms[i + 1];
42+
if (m * mNext <= 0) {
43+
c1s.push(0);
44+
} else {
45+
dx = dxs[i];
46+
const dxNext = dxs[i + 1];
47+
const common = dx + dxNext;
48+
c1s.push(3 * common / ((common + dxNext) / m + (common + dx) / mNext));
49+
}
50+
}
51+
c1s.push(ms[ms.length - 1]);
52+
53+
// Get degree-2 and degree-3 coefficients
54+
const c2s = [];
55+
const c3s = [];
56+
let m;
57+
for (let i = 0; i < c1s.length - 1; i++) {
58+
m = ms[i];
59+
const c1 = c1s[i];
60+
const invDx = 1 / dxs[i];
61+
const common = c1 + c1s[i + 1] - m - m;
62+
c2s.push((m - c1 - common) * invDx);
63+
c3s.push(common * invDx * invDx);
64+
}
65+
66+
// Return interpolant function
67+
return function (x) {
68+
// The rightmost point in the dataset should give an exact result
69+
let i = xs.length - 1;
70+
if (x === xs[i]) {
71+
return ys[i];
72+
}
73+
74+
// Search for the interval x is in, returning the corresponding y if x is one of the original xs
75+
let low = 0;
76+
let high = c3s.length - 1;
77+
let mid;
78+
while (low <= high) {
79+
mid = Math.floor(0.5 * (low + high));
80+
const xHere = xs[mid];
81+
if (xHere < x) {
82+
low = mid + 1;
83+
} else if (xHere > x) {
84+
high = mid - 1;
85+
} else {
86+
return ys[mid];
87+
}
88+
}
89+
i = Math.max(0, high);
90+
91+
// Interpolate
92+
const diff = x - xs[i], diffSq = diff * diff;
93+
return ys[i] + c1s[i] * diff + c2s[i] * diffSq + c3s[i] * diff * diffSq;
94+
};
95+
}

0 commit comments

Comments
 (0)