Skip to content
This repository was archived by the owner on Aug 13, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/MultiSlider/MultiSliderHandle.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';

import { noop } from '../util/functions';
import normalizeEvent from '../util/normalize-event';

import './MultiSliderHandle.css';

Expand All @@ -12,6 +13,7 @@ class MultiSliderHandle extends React.PureComponent {
}

startInteraction(e) {
e = normalizeEvent(e);
this.props.onStart(e, this.props.property);
}

Expand All @@ -26,6 +28,7 @@ class MultiSliderHandle extends React.PureComponent {
<div
className="uix-multislider__handle"
onMouseDown={this.startInteraction}
onTouchStart={this.startInteraction}
style={styles}
/>
);
Expand Down
2 changes: 1 addition & 1 deletion src/Pad/stories/index.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';

import { storiesOf } from '@storybook/react';
import { action } from '@storybook/addon-actions';
import State from '../../Husk/Husk';
import Husk from '../../Husk/Husk';

import Pad from '../Pad';
import PadGrid from '../PadGrid';
Expand Down
11 changes: 11 additions & 0 deletions src/Position/Position.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { noop } from '../util/functions';
import normalizeEvent, { isTouchEnabledDevice } from '../util/normalize-event';

/*
Component: Position
Expand All @@ -24,14 +25,23 @@ class Position extends React.PureComponent {
componentDidMount() {
document.addEventListener('mousemove', this.onChange);
document.addEventListener('mouseup', this.onEnd);
if (isTouchEnabledDevice()) {
document.addEventListener('touchmove', this.onChange);
document.addEventListener('touchend', this.onEnd);
}
}

componentWillUnmount() {
document.removeEventListener('mousemove', this.onChange);
document.removeEventListener('mouseup', this.onEnd);
if (isTouchEnabledDevice()) {
document.removeEventListener('touchmove', this.onChange);
document.removeEventListener('touchend', this.onEnd);
}
}

onChange(e) {
e = normalizeEvent(e);
this.props.onChange(
{
x: e.clientX,
Expand All @@ -44,6 +54,7 @@ class Position extends React.PureComponent {
}

onEnd(e) {
e = normalizeEvent(e);
this.props.onEnd(
{
x: e.clientX,
Expand Down
13 changes: 7 additions & 6 deletions src/Position/stories/index.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,17 @@ storiesOf('Position', module)
this.state = {
interacting: false
};
this.startInteraction = this.startInteraction.bind(this);
}

startInteraction(e) {
this.setState({ interacting: true });
e.preventDefault();
}

render() {
return (
<div
onMouseDown={e => {
this.setState({ interacting: true });
e.preventDefault();
}}
>
<div onMouseDown={this.startInteraction} onTouchStart={this.startInteraction}>
<p>
Hold down the mouse here and move it to read its coordinates:{' '}
{this.state.x}: {this.state.y}
Expand Down
7 changes: 6 additions & 1 deletion src/Surface/Surface.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { scaleLinear } from 'd3-scale';

import Position from '../Position/Position';
import { noop } from '../util/functions';
import normalizeEvent, { isTouchEnabledDevice } from '../util/normalize-event';

import './Surface.css';

Expand All @@ -22,7 +23,6 @@ const initial_state = {
for the X and Y coordinates in percentages (interval [0..100]).

*/

class Surface extends React.Component {
constructor(props) {
super(props);
Expand All @@ -42,6 +42,7 @@ class Surface extends React.Component {
}

start(e) {
e = normalizeEvent(e);
this.setState({
interacting: true
});
Expand All @@ -54,6 +55,7 @@ class Surface extends React.Component {
}

end(e) {
e = normalizeEvent(e);
this.setState({
interacting: false
});
Expand All @@ -75,6 +77,7 @@ class Surface extends React.Component {
}

insert(e) {
e = normalizeEvent(e);
this.props.onInsert(
this.scale({
x: e.clientX,
Expand All @@ -92,6 +95,8 @@ class Surface extends React.Component {
let events = {};
if (passive) {
events['onDoubleClick'] = this.insert;
} else if (isTouchEnabledDevice()) {
events['onTouchMove'] = this.start;
} else {
events['onMouseDownCapture'] = this.start;
}
Expand Down
85 changes: 85 additions & 0 deletions src/util/normalize-event.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
const proxiedValues = ['clientX', 'clientY', 'pageX', 'pageY', 'screenX', 'screenY'];

const proxiedFunctions = ['preventDefault', 'stopPropagation', 'stopImmediatePropagation'];

var EventProxy = {
apply: function(obj, thisArg, argumentList) {
return obj.apply(obj, argumentList);
},

get: function(obj, prop) {
if (obj.changedTouches && obj.changedTouches[0] && proxiedValues.indexOf(prop) > -1) {
return obj.changedTouches[0][prop];
}

if (
obj.detail &&
obj.detail.changedTouches &&
obj.detail.changedTouches[0] &&
proxiedValues.indexOf(prop) > -1
) {
return obj.detail.changedTouches[0][prop];
}

if (prop == 'original') {
if (obj.detail && obj.detail.original) {
return obj.detail.original;
}
return obj;
}

if (obj.type === 'touchend' && prop === 'target') {
let clientX, clientY;
if (obj.changedTouches && obj.changedTouches[0]) {
clientX = obj.changedTouches[0].clientX;
clientY = obj.changedTouches[0].clientY;
} else if (obj.detail && obj.detail.changedTouches && obj.detail.changedTouches[0]) {
clientX = obj.detail.changedTouches[0].clientX;
clientY = obj.detail.changedTouches[0].clientY;
}
return document.elementFromPoint(clientX, clientY);
}

if (proxiedFunctions.indexOf(prop) > -1) {
if (obj.detail && obj.detail.original && obj.detail.original[prop]) {
return obj.detail.original[prop].bind(obj);
}
return obj[prop].bind(obj);
}

return obj[prop];
}
};

let __isTouchEnabledDevice;
function isTouchEnabledDevice() {
return __isTouchEnabledDevice !== undefined
? __isTouchEnabledDevice
: (__isTouchEnabledDevice = (function() {
// we rely on Proxy for events that come from touch-enabled devices,
// so if we don't have it we need to assume this is not such a device.
if (!window.Proxy) {
return false;
}
try {
new CustomEvent('longtap');
} catch (e) {
return false;
}
/*
As per https://developer.mozilla.org/en-US/docs/Web/API/Navigator/maxTouchPoints
a device should expose how many touch points are supported; unfortunately
mobile Safari does not support it, so we have to also taste for ontouchstart for iPads.
*/
return (
window.ontouchstart !== undefined ||
navigator.maxTouchPoints ||
navigator.msMaxTouchPoints
);
})());
}

const normalizeEvent = e => (isTouchEnabledDevice() ? new Proxy(e, EventProxy) : e);

export default normalizeEvent;
export { isTouchEnabledDevice };