diff --git a/example/src/SelectablePig.js b/example/src/SelectablePig.js new file mode 100644 index 0000000..0e000ff --- /dev/null +++ b/example/src/SelectablePig.js @@ -0,0 +1,98 @@ +import React, { Component } from "react"; +import Pig from "pig-react"; +import imageData from "./imageData.json"; + +export default class SelectablePig extends Component { + constructor(props) { + super(props) + this.imageData = imageData + this.state = { + selectedItems: [] + } + } + + handleSelection = item => { + let newSelectedItems = this.state.selectedItems; + if (newSelectedItems.find(selectedItem => selectedItem.id === item.id)) { + newSelectedItems = newSelectedItems.filter(value => value.id !== item.id) + } else { + newSelectedItems = newSelectedItems.concat(item) + } + this.setState({ selectedItems: newSelectedItems }) + }; + + handleSelections = items => { + let newSelectedItems = this.state.selectedItems; + items.forEach(item => { + if (newSelectedItems.find(selectedItem => selectedItem.id === item.id)) { + newSelectedItems = newSelectedItems.filter(value => value.id !== item.id) + } else { + newSelectedItems = newSelectedItems.concat(item) + } + }); + this.setState({ selectedItems: newSelectedItems }) + }; + + handleClick = (event, item) => { + //if an image is selectabel, then handle shift click + if (event.shiftKey) { + let lastSelectedElement = this.state.selectedItems.slice(-1)[0] + if (lastSelectedElement === undefined) { + this.handleSelection(item) + return; + } + let indexOfCurrentlySelectedItem = this.imageData.findIndex(image => image.id === item.id) + let indexOfLastSelectedItem = this.imageData.findIndex(image => image.id === lastSelectedElement.id) + if (indexOfCurrentlySelectedItem > indexOfLastSelectedItem) { + this.handleSelections( + this.imageData.slice( + indexOfLastSelectedItem + 1, + indexOfCurrentlySelectedItem + 1 + ) + ); + return; + } else { + this.handleSelections( + this.imageData.slice( + indexOfCurrentlySelectedItem, + indexOfLastSelectedItem + ) + ) + return + } + } + // if an image is already selected, then we are in selection mode + if (this.state.selectedItems.length > 0) { + this.handleSelection(item) + return + } + + // if an image is already the width of the container, don't expand it on click + if (item.style.width >= this.containerWidth) { + this.setState({ activeTileUrl: null }) + return + } + + this.setState({ + // if Tile is already active, deactivate it + activeTileUrl: item.url !== this.state.activeTileUrl ? item.url : null + }) + } + + render() { + return ( + + ) + } +} diff --git a/example/src/index.js b/example/src/index.js index 13df94e..d48a166 100644 --- a/example/src/index.js +++ b/example/src/index.js @@ -1,22 +1,26 @@ import React from 'react' import ReactDOM from 'react-dom' import Pig from 'pig-react' +import SelectablePig from './SelectablePig' import imageData from './imageData.json' import './base.css' ReactDOM.render(
+ { + // + }
, document.getElementById('root')) diff --git a/src/components/Tile/Tile.js b/src/components/Tile/Tile.js index 7da6cd8..21a51f3 100644 --- a/src/components/Tile/Tile.js +++ b/src/components/Tile/Tile.js @@ -13,11 +13,15 @@ const Tile = React.memo(function Tile({ getUrl, activeTileUrl, handleClick, + handleSelection, + selected, + selectable, windowHeight, scrollSpeed, settings, }) { - + const isSelectable = selectable + const isSelected = selected const isExpanded = activeTileUrl === item.url const isVideo = item.url.includes('.mp4') || item.url.includes('.mov') const [isFullSizeLoaded, setFullSizeLoaded] = useState(isVideo ? true : false) @@ -29,12 +33,16 @@ const Tile = React.memo(function Tile({ // screenCenter is positioning logic for when the item is active and expanded const screenCenter = `translate3d(${offsetX}px, ${offsetY}px, 0)` - const { width, height, transform, zIndex } = useSpring({ + const { width, height, transform, zIndex, marginLeft, marginRight, marginTop, marginBottom } = useSpring({ transform: isExpanded ? screenCenter : gridPosition, zIndex: isExpanded ? 10 : 0, // 10 so that it takes a little longer before settling at 0 - width: isExpanded ? Math.ceil(calcWidth) + 'px' : item.style.width + 'px', - height: isExpanded ? Math.ceil(calcHeight) + 'px' : item.style.height + 'px', - config: { mass: 1.5, tension: 400, friction: 40 } + width: isExpanded ? Math.ceil(calcWidth) + 'px' : isSelected ? item.style.width - item.style.width * 0.1 + 'px' : item.style.width + 'px', + height: isExpanded ? Math.ceil(calcHeight) + 'px' : isSelected ? item.style.height - item.style.height * 0.1 + 'px' : item.style.height + 'px', + config: { mass: 1.5, tension: 400, friction: 40 }, + marginLeft: isSelected && !isExpanded ? item.style.width * 0.05 : 0, + marginRight: isSelected && !isExpanded ? item.style.width * 0.05 : 0, + marginTop: isSelected && !isExpanded ? item.style.height * 0.05 : 0, + marginBottom: isSelected && !isExpanded ? item.style.height * 0.05 : 0, }) return ( @@ -47,7 +55,11 @@ const Tile = React.memo(function Tile({ zIndex: zIndex.interpolate(t => Math.round(t)), width: width.interpolate(t => t), height: height.interpolate(t => t), - transform: transform.interpolate(t => t) + transform: transform.interpolate(t => t), + marginLeft: marginLeft.interpolate(t => t), + marginRight: marginRight.interpolate(t => t), + marginTop: marginTop.interpolate(t => t), + marginBottom: marginBottom.interpolate(t => t) }} > @@ -62,7 +74,7 @@ const Tile = React.memo(function Tile({ alt="" /> } - + {(scrollSpeed === 'slow' ) && !isVideo && // grid image )} - + {isExpanded && isVideo && ( // full size expanded video