Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[drag] add @vx/drag, add /drag-i demo + tile. fixes #8 #229

Merged
merged 1 commit into from
Jan 17, 2018
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
37 changes: 36 additions & 1 deletion packages/vx-demo/components/gallery.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import Pack from '../components/tiles/pack';
import Treemap from '../components/tiles/treemap';
import Radar from '../components/tiles/radar';
import Responsive from '../components/tiles/responsive';
import DragI from '../components/tiles/drag-i';

const items = [
'#242424',
Expand Down Expand Up @@ -875,7 +876,41 @@ export default class Gallery extends React.Component {
</div>
</Link>
</Tilt>
<div className="gallery-item placeholder" />
<Tilt className="tilt" options={{ max: 8, scale: 1 }}>
<Link prefetch href="/drag-i">
<div
className="gallery-item"
style={{
background: '#c4c3cb',
borderRadius: '14px',
}}
>
<div className="image">
<ParentSize>
{({ width, height }) => (
<DragI
width={543}
height={390}
events={false}
/>
)}
</ParentSize>
</div>
<div
className="details"
style={{
color: '#6437d6',
zIndex: 1,
}}
>
<div className="title">Drag</div>
<div className="description">
<pre>{`<Drag.Drag />`}</pre>
</div>
</div>
</div>
</Link>
</Tilt>
<div className="gallery-item placeholder" />
</div>

Expand Down
148 changes: 148 additions & 0 deletions packages/vx-demo/components/tiles/drag-i.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import React from 'react';
import { localPoint } from '@vx/event';
import { scaleOrdinal } from '@vx/scale';
import { withParentSize } from '@vx/responsive';
import { LinearGradient } from '@vx/gradient';
import { Drag, raise } from '@vx/drag';

const colors = [
'#025aac',
'#02cff9',
'#02efff',
'#03aeed',
'#0384d7',
`#edfdff`,
'#ab31ff',
'#5924d7',
'#d145ff',
'#1a02b1',
'#e582ff',
'#ff00d4',
'#270eff',
'#827ce2',
];

function genCircles({ num, width, height }) {
return Array(num)
.fill(1)
.map((d, i) => {
const radius = 25 - Math.random() * 20;
return {
id: i,
radius,
x: Math.round(Math.random() * (width - radius * 2) + radius),
y: Math.round(Math.random() * (height - radius * 2) + radius),
};
});
}

export default class DragI extends React.Component {
constructor(props) {
super(props);
this.state = {
items: genCircles({
num: 185,
width: props.width,
height: props.height,
}),
};
this.colorScale = scaleOrdinal({
range: colors,
domain: this.state.items.map(d => d.id),
});
}

render() {
const { width, height } = this.props;
return (
<div className="Drag">
<svg width={width} height={height} ref={s => (this.svg = s)}>
<LinearGradient id="stroke" from="#ff00a5" to="#ffc500" />
<rect
fill="#c4c3cb"
width={width}
height={height}
rx={14}
/>
{this.state.items.map((d, i) => (
<Drag
key={`${d.id}`}
svg={this.svg}
width={width}
height={height}
onDragStart={() => {
// svg follows the painter model
// so we need to move the data item
// to end of the array for it to be drawn
// "on top of" the other data items
this.setState((state, props) => {
return {
items: raise(state.items, i),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++ the util function 🎉

};
});
}}
>
{({
dragStart,
dragEnd,
dragMove,
isDragging,
dx,
dy,
}) => {
return (
<circle
key={`dot-${d.id}`}
cx={d.x}
cy={d.y}
r={isDragging ? d.radius + 4 : d.radius}
fill={
isDragging
? 'url(#stroke)'
: this.colorScale(d.id)
}
transform={`translate(${dx}, ${dy})`}
fillOpacity={0.9}
stroke={isDragging ? 'white' : 'transparent'}
strokeWidth={2}
onMouseMove={dragMove}
onMouseUp={dragEnd}
onMouseDown={dragStart}
/>
);
}}
</Drag>
))}
</svg>
<div className="deets">
<div>
Based on Mike Bostock's{' '}
<a href="https://bl.ocks.org/mbostock/c206c20294258c18832ff80d8fd395c3">
Circle Dragging II
</a>
</div>
</div>

<style jsx>{`
.Drag {
display: flex;
flex-direction: column;
user-select: none;
}

svg {
margin: 1rem 0;
}
.deets {
display: flex;
flex-direction: row;
font-size: 12px;
}
.deets > div {
margin: 0.25rem;
}
`}</style>
</div>
);
}
}
132 changes: 132 additions & 0 deletions packages/vx-demo/pages/drag-i.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import React from 'react';
import Show from '../components/show';
import DragI from '../components/tiles/drag-i';

export default () => {
return (
<Show component={DragI} title="Drag I">
{`import React from 'react';
import { localPoint } from '@vx/event';
import { scaleOrdinal } from '@vx/scale';
import { withParentSize } from '@vx/responsive';
import { LinearGradient } from '@vx/gradient';
import { Drag, raise } from '@vx/drag';

const colors = [
'#025aac',
'#02cff9',
'#02efff',
'#03aeed',
'#0384d7',
'#edfdff',
'#ab31ff',
'#5924d7',
'#d145ff',
'#1a02b1',
'#e582ff',
'#ff00d4',
'#270eff',
'#827ce2',
];

function genCircles({ num, width, height }) {
return Array(num)
.fill(1)
.map((d, i) => {
const radius = 25 - Math.random() * 20;
return {
id: i,
radius,
x: Math.round(Math.random() * (width - radius * 2) + radius),
y: Math.round(Math.random() * (height - radius * 2) + radius),
};
});
}

export default class DragI extends React.Component {
constructor(props) {
super(props);
this.state = {
items: genCircles({
num: 185,
width: props.width,
height: props.height,
}),
};
this.colorScale = scaleOrdinal({
range: colors,
domain: this.state.items.map(d => d.id),
});
}
componentDidMount() {
this.forceUpdate();
}
render() {
const { width, height } = this.props;
return (
<div className="Drag">
<svg width={width} height={height} ref={s => (this.svg = s)}>
<LinearGradient id="stroke" from="#ff00a5" to="#ffc500" />
<rect
fill="#c4c3cb"
width={width}
height={height}
rx={14}
/>
{this.state.items.map((d, i) => (
<Drag
key={\`\${d.id}\`}
svg={this.svg}
width={width}
height={height}
onDragStart={() => {
// svg follows the painter model
// so we need to move the data item
// to end of the array for it to be drawn
// "on top of" the other data items
this.setState((state, props) => {
return {
items: raise(state.items, i),
};
});
}}
>
{({
dragStart,
dragEnd,
dragMove,
isDragging,
dx,
dy,
}) => {
return (
<circle
key={\`dot-\${d.id}\`}
cx={d.x}
cy={d.y}
r={isDragging ? d.radius + 4 : d.radius}
transform={\`translate(\${dx}, \${dy})\`}
onMouseMove={dragMove}
onMouseUp={dragEnd}
onMouseDown={dragStart}
stroke={isDragging ? 'white' : 'transparent'}
strokeWidth={2}
fillOpacity={0.9}
fill={
isDragging
? 'url(#stroke)'
: this.colorScale(d.id)
}
/>
);
}}
</Drag>
))}
</svg>
</div>
);
}
}`}
</Show>
);
};
Loading