import React, { useState, useEffect, useRef, useCallback, useReducer } from "react" import { useDispatch, useSelector } from "react-redux" import { Clip } from './clip' import { Modal } from './modal' import { MdZoomIn, MdSave, MdFolder, MdInsertDriveFile, MdCancel } from 'react-icons/md' import { FaRegPlayCircle, FaEdit, FaCubes } from 'react-icons/fa' import * as Icon from "./icons"; const navArr = [ '\u00A0', 'Mouse Navigation', [['Select', Icon.Select], [Icon.MouseLeft, 'left-click + drag']], [['Rotate', Icon.Rotate], [Icon.MouseRight, 'right-click']], [['Zoom', MdZoomIn], [Icon.MouseScroll, 'scroll up / down']], [['Pan', Icon.Pan], [Icon.MouseMiddle, 'middle-click (or', () =>
Ctrl
, ' + ', Icon.MouseRight, ' right-click) + drag']], '\u00A0', 'Model Toolbar', [['Sketch', FaEdit], ['Initiates a new sketch on the selected plane, or on the plane defined by the three selected points in the existing model.']], [['Extrude', Icon.Extrude], ['Intiates a new extrusion dialog. before clicking this button. The user must first select a sketch to extrude from']], [['Union', Icon.Union], ['Creates a new solid that is a boolean union of two selected solids.']], [['Substract', Icon.Subtract], ['Creates a new solid that is a boolean subtraction of the second selected solid from the first']], [['Intersect', Icon.Intersect], ['Creates a new solid that is a boolean intersection or two selected solids.']], [['New Document', MdInsertDriveFile], ['Wipes the current workspace and starts a fresh document']], [['Save', MdSave], ['Saves current document. On the inital save, the user can specify save location and file name']], [['Open', MdFolder], ['Loads an existing document from the local disk.']], [['Export to STL', Icon.Stl], ['Exports selected solid to the 3d printer friendly STL format']], '\u00A0', 'Sketch Toolbar', [['Extrude', Icon.Extrude], ['Creates a new extrusion from the current sketch']], [['Line', Icon.Line], ['Starts a line segment chain. Subsequent clicks on the canvas define the vertices of the line segment chain.']], [['Arc', Icon.Arc], ['In the 3 subsequent mouse clicks, the first sets the start point, the seconds the endpoint, and the third the radius.']], [['Dimension', Icon.Dimension], ['Adds a distance between 2 points, or 1 point and 1 line. Adds an angle when two lines are selected.']], [['Coincident', Icon.Coincident], ['Adds a coincident contraint between two points, or a line and a point.']], [['Vertical', Icon.Vertical], ['Aligns the the selected line, or two selected points with the y-axis']], [['Horizontal', Icon.Horizontal], ['Aligns the the selected line, or two selected points with the x-axis']], [['Tangent', Icon.Tangent], ['Adds tangency between two selected arcs, or a line and a arc. Entities must be coincident with one another via 1 endpoint']], ] const clipArr = [ ['basic-workflow.mp4', 'Basic part creation workflow'], ['load-file-and-edit.mp4', 'Loading and editing a part'], ['export-to-3dprint.mp4', 'Exporting a part for 3D printing'], ['headphone-stand.json.gz', 'Example model: Headphone stand'], ] const utf8decoder = new TextDecoder(); export const QuickStart = ({ setModal }) => { const dispatch = useDispatch() const [clip, setClip] = useState(null) return
Demos
{ clipArr.map((ele, idx) => { const isGz = ele[0].match(/\.[0-9a-z]+$/i)[0] == '.gz' return
{ if (isGz) { const state = sce.loadState( utf8decoder.decode( new Zlib.Gunzip( new Uint8Array( await ( await ( await fetch(ele[0]) ).blob() ).arrayBuffer() ) ).decompress() ) ) setModal(false) dispatch({ type: 'restore-state', state, fileName: ele[0].replace(/\.[^/.]+$/, "") }) sce.render() } else { setClip(ele) } } } key={idx} > {isGz ? : } {ele[1]}
}) }
{ navArr.map((row, i) => ( typeof row === 'string' ?
{row}
:
{row[0][0]} {React.createElement(row[0][1], { className: "fill-current text-gray-100 flex-shrink-0", width: '2.5em', height: '2.5em', size: '2.5em', style: { padding: '0.5em' }, } )}
{ row[1].map( (Col, key) => typeof Col === 'string' ? Col : ) }
)) }
Quick Start
setModal(null)} />
{ clip && }
}