You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

zoom.tsx 1.4KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { ZoomInIcon, ZoomOutIcon } from '@radix-ui/react-icons'
  2. import { IconButton } from 'components/shared'
  3. import state, { useSelector } from 'state'
  4. import styled from 'styles'
  5. const zoomIn = () => state.send('ZOOMED_IN')
  6. const zoomOut = () => state.send('ZOOMED_OUT')
  7. const zoomToFit = () => state.send('ZOOMED_TO_FIT')
  8. const zoomToActual = () => state.send('ZOOMED_TO_ACTUAL')
  9. export default function Zoom() {
  10. return (
  11. <Container size={{ '@sm': 'small' }}>
  12. <IconButton onClick={zoomOut}>
  13. <ZoomOutIcon />
  14. </IconButton>
  15. <IconButton onClick={zoomIn}>
  16. <ZoomInIcon />
  17. </IconButton>
  18. <ZoomCounter />
  19. </Container>
  20. )
  21. }
  22. function ZoomCounter() {
  23. const camera = useSelector((s) => s.data.camera)
  24. return (
  25. <ZoomButton onClick={zoomToActual} onDoubleClick={zoomToFit}>
  26. {Math.round(camera.zoom * 100)}%
  27. </ZoomButton>
  28. )
  29. }
  30. const Container = styled('div', {
  31. position: 'absolute',
  32. left: 12,
  33. bottom: 64,
  34. backgroundColor: '$panel',
  35. borderRadius: '4px',
  36. overflow: 'hidden',
  37. alignSelf: 'flex-end',
  38. border: '1px solid $border',
  39. pointerEvents: 'all',
  40. userSelect: 'none',
  41. zIndex: 200,
  42. boxShadow: '0px 2px 12px rgba(0,0,0,.08)',
  43. display: 'flex',
  44. padding: 4,
  45. '& svg': {
  46. strokeWidth: 0,
  47. },
  48. variants: {
  49. size: {
  50. small: {
  51. bottom: 12,
  52. },
  53. },
  54. },
  55. })
  56. const ZoomButton = styled(IconButton, {
  57. fontSize: '$0',
  58. padding: 8,
  59. width: 44,
  60. })