From bdcc41176f09b4747887ad092ae49e836dd7f7da Mon Sep 17 00:00:00 2001 From: howard Date: Thu, 29 Apr 2021 20:29:02 -0700 Subject: [PATCH] consolidate carousel --- demo/user-guide.md | 2 + src/react/carousel.jsx | 141 +++++++++++++++++++---------------- src/react/help.jsx | 163 ++++++++++++++++++++++++++++++++++------- src/react/navBar.jsx | 6 +- src/react/reducer.js | 4 + 5 files changed, 225 insertions(+), 91 deletions(-) diff --git a/demo/user-guide.md b/demo/user-guide.md index 6a8c6d6..60be946 100644 --- a/demo/user-guide.md +++ b/demo/user-guide.md @@ -14,6 +14,8 @@ combine multiple solids to form the part you desire uplaod your design to a 3d printer +navigation tips + General Workflow for part creation diff --git a/src/react/carousel.jsx b/src/react/carousel.jsx index c6e8a37..a07f646 100644 --- a/src/react/carousel.jsx +++ b/src/react/carousel.jsx @@ -1,6 +1,7 @@ -import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'; +import React, { useCallback, useEffect, useReducer, useRef } from 'react'; +import { MdArrowBack, MdArrowForward } from 'react-icons/md' export function throttle(callback, limit) { let handler = null; // Initially, we're not waiting @@ -26,101 +27,97 @@ const transTime = 200 const elastic = `transform ${transTime}ms cubic-bezier(0.4, 0.0, 0.2, 1)`; +function reducer(state, action) { + switch (action.type) { + case 'set-rect': + return { + ...state, + rect: action.rect + }; + case 'resize': + return { + ...state, + rect: action.rect, + dragLeft: state.pg * action.rect.width, + dragging: true + }; + case 'move': + return { + ...state, + pg: state.pg + action.del, + dragging: false + }; + case 'drag-start': + return { + ...state, + dragLeft: state.pg * state.rect.width, + dragging: true + }; + case 'drag': + return { + ...state, + dragLeft: state.dragLeft - action.move + }; + case 'drag-end': + return { + ...state, + pg: Math.round(state.dragLeft / state.rect.width), + dragging: false + }; + default: + console.log('wtf') + console.error(action) + } +} export const Carousel = () => { const arr = [1, 2, 3] - const ref = useRef(null) - const [dragging, setDragging] = useState(false) - - // const dragging = useRef(false) - const [rect, setRect] = useState({}) - const [pg, setPg] = useState(0) - const [dragLeft, setDragLeft] = useState(0) - - + const [state, dispatch] = useReducer(reducer, { rect: {}, pg: 0, dragLeft: 0, dragging: false }) useEffect(() => { - setRect(ref.current.getBoundingClientRect()) + dispatch({ type: 'set-rect', rect: ref.current.getBoundingClientRect() }) }, [ref]) const updateSize = useCallback( debounce( - // throttle( () => { - setRect(ref.current.getBoundingClientRect()) + dispatch({ type: 'resize', rect: ref.current.getBoundingClientRect() }) } , 200 ) , [] ) - // const updateSize = () => setRect(ref.current.getBoundingClientRect()) - - - useEffect(() => { - // dragging.current = false - // console.log(dragging) - // setDragLeft(pg * rect.width) - // setDragging(false) - }, [rect]) useEffect(() => { window.addEventListener('resize', updateSize) - return () => window.removeEventListener('resize', updateSize) }, []) return <> -
setPg(pg + 1) - }>1
-
setPg(pg - 1) - } - >2
-
- {rect.width && -
{ - setDragging(true) - // dragging.current = true - setDragLeft(pg * rect.width) - }} - - onMouseMove={(e) => { - if (e.buttons != 1) return - setDragLeft(state => state + e.movementX) - }} - - onMouseUp={(e) => { - // dragging.current = false - setPg(Math.round(dragLeft / rect.width)) - setDragging(false) - }} + onMouseDown={() => dispatch({ type: 'drag-start' })} + onMouseMove={(e) => e.buttons == 1 && dispatch({ type: 'drag', move: e.movementX })} + onMouseUp={() => dispatch({ type: 'drag-end' })} style={{ - height: '80%', - width: 1 * rect.width, - top: 0, - // left: dragging ? dragLeft : pg * rect.width, - left: 0, - transform: `translateX(${dragging ? dragLeft : pg * rect.width}px)`, - transition: dragging ? null : elastic - }}> + width: 1 * state.rect.width, + transform: `translateX(${state.dragging ? -state.dragLeft : -state.pg * state.rect.width}px)`, + transition: state.dragging ? null : elastic + }} + > { arr.map((e, idx) => { @@ -132,6 +129,24 @@ export const Carousel = () => {
}
+ +
dispatch({ type: "move", del: -1 })} + > + +
+
dispatch({ type: "move", del: 1 })} + > + +
+ +
+ {arr.map((ele, idx) => ( +
+ ))} +
+ } diff --git a/src/react/help.jsx b/src/react/help.jsx index 7a4ee6b..be5182e 100644 --- a/src/react/help.jsx +++ b/src/react/help.jsx @@ -1,9 +1,10 @@ -import React, { useEffect, useRef, useState } from 'react'; + +import React, { useCallback, useEffect, useReducer, useRef } from 'react'; import { useDispatch, useSelector } from 'react-redux' -import { MdCancel, MdClose, MdHelpOutline } from 'react-icons/md' +import { MdCancel, MdArrowBack, MdArrowForward } from 'react-icons/md' import { Carousel } from './carousel' @@ -34,54 +35,162 @@ const exportTS = [ 10, 'result', ] +function debounce(callback, delay) { + let handler = null; + return (...args) => { + clearTimeout(handler); + handler = setTimeout(() => callback(...args), delay); + } +} +function reducer(state, action) { + switch (action.type) { + case 'resize': + return { + ...state, + rect: window.innerHeight * 0.6, + dragLeft: state.pg * window.innerHeight * 0.6, + dragging: true + }; + case 'move': + return { + ...state, + pg: state.pg + action.del, + dragging: false + }; + case 'drag-start': + return { + ...state, + dragLeft: state.pg * state.rect, + dragging: true + }; + case 'drag': + return { + ...state, + dragLeft: state.dragLeft - action.move + }; + case 'drag-end': + return { + ...state, + pg: Math.round(state.dragLeft / state.rect), + dragging: false + }; + default: + console.error(action) + // throw new Error(); + } +} +const transTime = 200 + +const elastic = `transform ${transTime}ms cubic-bezier(0.4, 0.0, 0.2, 1)`; export const Help = () => { + + const dispatch = useDispatch() + const status = useSelector(state => state.ui.help) + const handleClick = (e) => { - /* - this handles inside click as well due to bubbling, - sets the open/close state of drop down - */ - !e.composedPath().includes(ref.current) && dispatch({ type: 'set-help', status: false }) + if (!e.composedPath().includes(ref.current) + ) { + e.stopPropagation() // prevents mouse from immediately clicking nav button if over it + dispatch({ type: 'set-help', status: false }) + } } - const handleTimeUpdate = (e) => { - - } - - const ref = useRef() - const vidRef = useRef() - useEffect(() => { + if (!status) return + document.addEventListener( // handles click outside buttona & dropdown - 'pointerdown', + 'click', handleClick , { capture: true } // capture phase to allow for stopPropogation on others ) - return () => document.removeEventListener('pointerdown', handleClick) + return () => { + document.removeEventListener('click', handleClick, { capture: true }) // important to include options if it was specified + } + }, [status]) + + + + const arr = [1, 2, 3] + + const ref = useRef(null) + const [state, carouselDispatch] = useReducer(reducer, { rect: window.innerHeight * 0.6, pg: 0, dragLeft: 0, dragging: false }) + + + + + + const updateSize = useCallback( + debounce( + () => { + carouselDispatch({ type: 'resize' }) + } + , 200 + ) + , [] + ) + + + useEffect(() => { + window.addEventListener('resize', updateSize) }, []) - const dispatch = useDispatch() - const [open, setOpen] = useState(false) - - const status = useSelector(state => state.ui.help) - - if (status) { - return
- - +
carouselDispatch({ type: 'drag-start' })} + onMouseMove={(e) => e.buttons == 1 && carouselDispatch({ type: 'drag', move: e.movementX })} + onMouseUp={() => carouselDispatch({ type: 'drag-end' })} + + style={{ + width: 1 * state.rect, + transform: `translateX(${state.dragging ? -state.dragLeft : -state.pg * state.rect}px)`, + transition: state.dragging ? null : elastic + }} + > + { + arr.map((e, idx) => { + + return
+ hi {e} +
+ }) + } +
+ +
carouselDispatch({ type: "move", del: -1 })} + > + +
+
carouselDispatch({ type: "move", del: 1 })} + > + +
+ +
+ {arr.map((ele, idx) => ( +
+ ))} +
+ dispatch({ type: 'set-help', status: false })} + />
} else { return null diff --git a/src/react/navBar.jsx b/src/react/navBar.jsx index 2d6e455..0ab5eba 100644 --- a/src/react/navBar.jsx +++ b/src/react/navBar.jsx @@ -31,6 +31,7 @@ export const NavBar = () => { const modified = useSelector(state => state.ui.modified) const fileName = useSelector(state => state.ui.fileName) const mode = useSelector(state => state.ui.mode) + const help = useSelector(state => state.ui.help) const boolOp = (code) => { if (sce.selected.length != 2 || !sce.selected.every(e => e.userData.type == 'mesh')) { @@ -194,7 +195,10 @@ export const NavBar = () => { }
- dispatch({type:'set-help', status:true})}/> + { + dispatch({ type: 'set-help', status: true }) + } + } /> diff --git a/src/react/reducer.js b/src/react/reducer.js index aeb1562..57eb7cf 100644 --- a/src/react/reducer.js +++ b/src/react/reducer.js @@ -199,6 +199,10 @@ export function ui(state = defaultUIState, action) { return update(state, { help: { $set: action.status } }) + case 'toggle-help': + return update(state, { + help: { $set: !state.help } + }) default: return state