PencilShape.tsx 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /* eslint-disable @typescript-eslint/no-explicit-any */
  2. import * as React from 'react'
  3. import { SvgPathUtils, TLDrawShape, TLDrawShapeProps } from '@tldraw/core'
  4. import { SVGContainer, TLComponentProps } from '@tldraw/react'
  5. import { observer } from 'mobx-react-lite'
  6. import { computed, makeObservable } from 'mobx'
  7. import { CustomStyleProps, withClampedStyles } from './style-props'
  8. export interface PencilShapeProps extends TLDrawShapeProps, CustomStyleProps {
  9. type: 'pencil'
  10. }
  11. export class PencilShape extends TLDrawShape<PencilShapeProps> {
  12. constructor(props = {} as Partial<PencilShapeProps>) {
  13. super(props)
  14. makeObservable(this)
  15. }
  16. static id = 'pencil'
  17. static defaultProps: PencilShapeProps = {
  18. id: 'pencil',
  19. parentId: 'page',
  20. type: 'pencil',
  21. point: [0, 0],
  22. points: [],
  23. isComplete: false,
  24. stroke: '#000000',
  25. fill: '#ffffff',
  26. strokeWidth: 2,
  27. opacity: 1,
  28. }
  29. @computed get pointsPath() {
  30. const { points } = this.props
  31. return SvgPathUtils.getCurvedPathForPoints(points)
  32. }
  33. ReactComponent = observer(({ events, isErasing }: TLComponentProps) => {
  34. const {
  35. pointsPath,
  36. props: { stroke, fill, strokeWidth, opacity },
  37. } = this
  38. return (
  39. <SVGContainer {...events} opacity={isErasing ? 0.2 : opacity}>
  40. <polyline
  41. points={pointsPath}
  42. stroke={stroke}
  43. fill={fill}
  44. strokeWidth={strokeWidth}
  45. pointerEvents="all"
  46. />
  47. </SVGContainer>
  48. )
  49. })
  50. ReactIndicator = observer(() => {
  51. const { pointsPath } = this
  52. return <path d={pointsPath} fill="none" />
  53. })
  54. validateProps = (props: Partial<PencilShapeProps>) => {
  55. return withClampedStyles(props)
  56. }
  57. }