three.cad/src/react/onboard.jsx

246 lines
6.6 KiB
React
Raw Normal View History

2021-04-29 18:42:52 +08:00
2021-04-30 11:29:02 +08:00
2021-05-03 07:44:54 +08:00
import React, { useCallback, useEffect, useReducer, useRef, useState } from 'react';
2021-04-29 18:42:52 +08:00
import { useDispatch, useSelector } from 'react-redux'
2021-05-03 07:44:54 +08:00
import { MdArrowBack, MdArrowForward } from 'react-icons/md'
2021-04-29 18:42:52 +08:00
2021-05-03 07:44:54 +08:00
import { QuickStart } from './quickStart'
2021-04-29 18:42:52 +08:00
// 10, 'Use the line tool',
// 10, 'Adding dimensions',
// 10, 'Adding vetical/horizontal constraints',
// 10, 'Drawing an arc',
// 10, 'Adding coincident constraints',
2021-04-30 11:29:02 +08:00
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':
2021-05-03 07:44:54 +08:00
2021-05-04 06:21:21 +08:00
const rect = Math.min(Math.min(window.innerHeight * 0.8, window.innerWidth * 0.7), 800)
2021-04-30 11:29:02 +08:00
return {
...state,
2021-05-03 07:44:54 +08:00
rect,
dragLeft: state.pg * rect,
2021-04-30 11:29:02 +08:00
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':
2021-05-04 06:21:21 +08:00
const dragLeft = state.dragLeft - action.move
2021-05-04 16:50:29 +08:00
if (dragLeft < 0 || dragLeft > state.rect * (arr.length - 1)) {
2021-05-04 06:21:21 +08:00
return state
} else {
return {
...state,
dragLeft
}
}
2021-04-30 11:29:02 +08:00
case 'drag-end':
return {
...state,
pg: Math.round(state.dragLeft / state.rect),
dragging: false
};
default:
console.error(action)
// throw new Error();
}
}
2021-04-29 18:42:52 +08:00
2021-05-03 07:44:54 +08:00
const transTime = 300
2021-04-29 18:42:52 +08:00
2021-04-30 11:29:02 +08:00
const elastic = `transform ${transTime}ms cubic-bezier(0.4, 0.0, 0.2, 1)`;
2021-04-29 18:42:52 +08:00
2021-05-03 07:44:54 +08:00
const arr = [
2021-05-04 16:50:29 +08:00
['Sketch out the 2D outline of your idea.', 'sketch.mp4'],
2021-05-04 12:53:50 +08:00
['Extrude the sketched shape into a 3D solid.', 'extrude.png'],
2021-05-04 06:21:21 +08:00
['Use additional sketches to sculpt or extend the model.', 'sculpt.gif'],
2021-05-04 12:53:50 +08:00
['Export your design to a 3D printer and turn into reality!', '3dprint.mp4'],
2021-05-03 07:44:54 +08:00
]
2021-05-04 17:46:05 +08:00
export const Onboard = ({ setModal, setQs }) => {
2021-04-29 18:42:52 +08:00
2021-04-30 11:29:02 +08:00
const ref = useRef(null)
2021-05-04 06:21:21 +08:00
const rect = Math.min(Math.min(window.innerHeight * 0.8, window.innerWidth * 0.7), 800)
2021-05-03 07:44:54 +08:00
const [state, carouselDispatch] = useReducer(reducer, { rect, pg: 0, dragLeft: 0, dragging: false })
2021-04-29 18:42:52 +08:00
2021-04-30 11:29:02 +08:00
const updateSize = useCallback(
debounce(
() => {
carouselDispatch({ type: 'resize' })
}
, 200
)
, []
)
2021-05-03 07:44:54 +08:00
const handleMouseDown = () => carouselDispatch({ type: 'drag-start' })
const handleMouseMove = (e) => e.buttons == 1 && carouselDispatch({ type: 'drag', move: e.movementX })
const handleMouseUp = () => carouselDispatch({ type: 'drag-end' })
2021-04-30 11:29:02 +08:00
useEffect(() => {
window.addEventListener('resize', updateSize)
2021-05-03 07:44:54 +08:00
document.addEventListener('mousedown', handleMouseDown)
document.addEventListener('mousemove', handleMouseMove)
document.addEventListener('mouseup', handleMouseUp)
2021-05-04 06:21:21 +08:00
return () => {
window.removeEventListener('resize', updateSize)
document.removeEventListener('mousedown', handleMouseDown)
document.removeEventListener('mousemove', handleMouseMove)
document.removeEventListener('mouseup', handleMouseUp)
}
2021-04-30 11:29:02 +08:00
}, [])
2021-05-03 07:44:54 +08:00
// if (status) {
2021-05-04 06:21:21 +08:00
return <div className="absolute left-0 right-0 mx-auto bg-gray-700 rounded-xl
2021-05-03 07:44:54 +08:00
flex flex-col items-center border-gray-500 border-2
2021-05-04 06:21:21 +08:00
text-sm lg:text-base xl:text-lg select-none
2021-04-29 18:42:52 +08:00
"
2021-05-03 07:44:54 +08:00
style={{
width: state.rect,
height: 1.1 * state.rect,
2021-05-04 06:21:21 +08:00
top: (window.innerHeight - 1.1 * state.rect) / 3
2021-05-03 07:44:54 +08:00
}}
ref={ref}
>
<div className='w-full overflow-hidden relative rounded-t-xl'
2021-04-30 11:29:02 +08:00
style={{
2021-05-03 07:44:54 +08:00
height: state.rect,
2021-05-04 06:21:21 +08:00
// height: '100%',
2021-04-30 11:29:02 +08:00
}}
2021-04-29 18:42:52 +08:00
>
2021-05-03 07:44:54 +08:00
<div className='bg-transparent h-full flex select-none'
2021-04-30 11:29:02 +08:00
style={{
2021-05-04 12:02:46 +08:00
width: state.rect * (arr.length),
2021-05-04 06:21:21 +08:00
transform: `translateX(${state.dragging ? -state.dragLeft - 4 : -state.pg * state.rect - 4}px)`,
2021-04-30 11:29:02 +08:00
transition: state.dragging ? null : elastic
}}
>
{
2021-05-03 07:44:54 +08:00
arr.map(
2021-05-04 12:02:46 +08:00
(e, idx) => {
const isVideo = e[1].match(/\.[0-9a-z]+$/i)[0] == '.mp4'
return <div className='flex flex-col items-center'
style={{ width: state.rect, height: '100%' }} key={idx}
>
{
isVideo ?
<video src={e[1]}
style={{
width: state.rect * 0.8,
height: state.rect * 0.8,
}}
autoPlay loop
muted type="video/mp4" />
:
<img
src={e[1]}
style={{
width: state.rect * 0.8,
height: state.rect * 0.8,
}}
2021-05-04 16:50:29 +08:00
draggable='false'
2021-05-04 12:02:46 +08:00
></img>
}
<div className='my-auto text-center text-gray-50 text-sm sm:text-base md:text-xl'>
{e[0]}
</div>
2021-05-03 07:44:54 +08:00
</div>
2021-05-04 12:02:46 +08:00
}
2021-05-03 07:44:54 +08:00
)
2021-04-30 11:29:02 +08:00
}
2021-05-04 12:02:46 +08:00
{/* <div className='flex flex-col items-center'
2021-05-03 07:44:54 +08:00
style={{ width: state.rect, height: '100%' }}
>
2021-05-04 06:21:21 +08:00
<QuickStart {...{ setModal }} />
2021-05-04 12:02:46 +08:00
</div> */}
2021-04-30 11:29:02 +08:00
</div>
2021-05-03 07:44:54 +08:00
</div>
<div
2021-05-04 16:50:29 +08:00
className="cursor-pointer text-gray-50 bg-green-500 rounded p-1.5 inline-block hover:bg-green-500"
2021-05-04 06:21:21 +08:00
// style={{
// position:'absolute'
// bottom: 0.1 * state.rect}}
2021-05-04 12:02:46 +08:00
onClick={() => {
setModal(false)
setQs(true)
}}
2021-05-03 07:44:54 +08:00
>
Get Started
</div>
2021-05-04 06:21:21 +08:00
<div className='cursor-pointer select-none absolute w-12 h-12 top-0 bottom-0 my-auto -left-24 fill-current bg-gray-100 hover:bg-gray-300 rounded-full'
2021-05-03 07:44:54 +08:00
onClick={() => carouselDispatch({ type: "move", del: -1 })}
2021-05-04 06:21:21 +08:00
style={{
visibility: state.pg == 0 ? 'hidden' : 'visible'
}}
2021-05-03 07:44:54 +08:00
>
<MdArrowBack className="w-full h-full text-gray-700 p-3" />
</div>
2021-05-04 06:21:21 +08:00
<div className='cursor-pointer select-none absolute w-12 h-12 top-0 bottom-0 my-auto -right-24 fill-current bg-gray-100 hover:bg-gray-300 rounded-full'
2021-05-03 07:44:54 +08:00
onClick={() => carouselDispatch({ type: "move", del: 1 })}
2021-05-04 06:21:21 +08:00
style={{
2021-05-04 12:02:46 +08:00
visibility: state.pg == arr.length - 1 ? 'hidden' : 'visible'
2021-05-04 06:21:21 +08:00
}}
2021-05-03 07:44:54 +08:00
>
<MdArrowForward className="w-full h-full text-gray-700 p-3" />
</div>
<div className="flex -bottom-8 absolute flex justify-center items-center">
2021-05-04 12:02:46 +08:00
{Array(arr.length).fill().map((ele, idx) => (
2021-05-03 07:44:54 +08:00
<div key={idx} className={`h-2 w-2 mx-1 rounded-full ${idx == state.pg ? 'bg-gray-50' : 'bg-gray-500'}`}></div>
))}
</div>
</div >
// } else {
// return null
// }
2021-04-29 18:42:52 +08:00
}