@tscircuit/schematic-viewer 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/.prettierrc +1 -0
  2. package/.storybook/main.js +15 -0
  3. package/.storybook/preview.js +9 -0
  4. package/README.md +26 -0
  5. package/ava.config.js +7 -0
  6. package/dist/Schematic.js +8606 -0
  7. package/dist/Schematic.js.map +1 -0
  8. package/dist/lib/hooks/index.js +2170 -0
  9. package/dist/lib/hooks/index.js.map +1 -0
  10. package/dist/lib/hooks/use-maybe-promise.js +2170 -0
  11. package/dist/lib/hooks/use-maybe-promise.js.map +1 -0
  12. package/dist/lib/render-context/index.js +45 -0
  13. package/dist/lib/render-context/index.js.map +1 -0
  14. package/dist/lib/types/core.js +18 -0
  15. package/dist/lib/types/core.js.map +1 -0
  16. package/dist/lib/types/index.js +18 -0
  17. package/dist/lib/types/index.js.map +1 -0
  18. package/dist/lib/types/route-solver.js +18 -0
  19. package/dist/lib/types/route-solver.js.map +1 -0
  20. package/dist/lib/types/source-component.js +18 -0
  21. package/dist/lib/types/source-component.js.map +1 -0
  22. package/dist/lib/types/util.js +18 -0
  23. package/dist/lib/types/util.js.map +1 -0
  24. package/dist/lib/utils/direction-to-vec.js +96 -0
  25. package/dist/lib/utils/direction-to-vec.js.map +1 -0
  26. package/dist/lib/utils/get-svg-path-bounds.js +51 -0
  27. package/dist/lib/utils/get-svg-path-bounds.js.map +1 -0
  28. package/dist/lib/utils/point-math.js +57 -0
  29. package/dist/lib/utils/point-math.js.map +1 -0
  30. package/dist/pages/_app.js +2714 -0
  31. package/dist/pages/_app.js.map +1 -0
  32. package/dist/pages/index.js +8612 -0
  33. package/dist/pages/index.js.map +1 -0
  34. package/dist/pages/led-circuit-react.js +2185 -0
  35. package/dist/pages/led-circuit-react.js.map +1 -0
  36. package/dist/pages/led-circuit.js +8656 -0
  37. package/dist/pages/led-circuit.js.map +1 -0
  38. package/dist/schematic-components/MovableGrid/MovableGrid.stories.js +47 -0
  39. package/dist/schematic-components/MovableGrid/MovableGrid.stories.js.map +1 -0
  40. package/dist/schematic-components/MovableGrid/index.js +34 -0
  41. package/dist/schematic-components/MovableGrid/index.js.map +1 -0
  42. package/dist/schematic-components/ProjectComponent.js +8584 -0
  43. package/dist/schematic-components/ProjectComponent.js.map +1 -0
  44. package/dist/schematic-components/RenderError.js +40 -0
  45. package/dist/schematic-components/RenderError.js.map +1 -0
  46. package/dist/schematic-components/SVGPathComponent.js +90 -0
  47. package/dist/schematic-components/SVGPathComponent.js.map +1 -0
  48. package/dist/schematic-components/SchematicBug.js +468 -0
  49. package/dist/schematic-components/SchematicBug.js.map +1 -0
  50. package/dist/schematic-components/SchematicComponent.js +8451 -0
  51. package/dist/schematic-components/SchematicComponent.js.map +1 -0
  52. package/dist/schematic-components/SchematicGroup.js +32 -0
  53. package/dist/schematic-components/SchematicGroup.js.map +1 -0
  54. package/dist/schematic-components/SchematicPort.js +8348 -0
  55. package/dist/schematic-components/SchematicPort.js.map +1 -0
  56. package/dist/schematic-components/SchematicText.js +71 -0
  57. package/dist/schematic-components/SchematicText.js.map +1 -0
  58. package/dist/schematic-components/SchematicTrace.js +137 -0
  59. package/dist/schematic-components/SchematicTrace.js.map +1 -0
  60. package/dist/schematic-components/SimpleCapacitor.js +103 -0
  61. package/dist/schematic-components/SimpleCapacitor.js.map +1 -0
  62. package/dist/schematic-components/SimpleDiode.js +101 -0
  63. package/dist/schematic-components/SimpleDiode.js.map +1 -0
  64. package/dist/schematic-components/SimpleGround.js +102 -0
  65. package/dist/schematic-components/SimpleGround.js.map +1 -0
  66. package/dist/schematic-components/SimpleInductor.js +102 -0
  67. package/dist/schematic-components/SimpleInductor.js.map +1 -0
  68. package/dist/schematic-components/SimplePowerSource.js +104 -0
  69. package/dist/schematic-components/SimplePowerSource.js.map +1 -0
  70. package/dist/schematic-components/SimpleResistor.js +102 -0
  71. package/dist/schematic-components/SimpleResistor.js.map +1 -0
  72. package/dist/schematic-components/index.js +8618 -0
  73. package/dist/schematic-components/index.js.map +1 -0
  74. package/next-env.d.ts +5 -0
  75. package/package.json +52 -0
  76. package/parsel.d.ts +81 -0
  77. package/src/Schematic.tsx +40 -0
  78. package/src/lib/hooks/index.ts +1 -0
  79. package/src/lib/hooks/use-maybe-promise.ts +14 -0
  80. package/src/lib/render-context/index.ts +15 -0
  81. package/src/lib/types/core.ts +179 -0
  82. package/src/lib/types/index.ts +4 -0
  83. package/src/lib/types/route-solver.ts +10 -0
  84. package/src/lib/types/source-component.ts +63 -0
  85. package/src/lib/types/util.ts +52 -0
  86. package/src/lib/utils/direction-to-vec.ts +50 -0
  87. package/src/lib/utils/get-svg-path-bounds.ts +22 -0
  88. package/src/lib/utils/point-math.ts +26 -0
  89. package/src/pages/_app.tsx +23 -0
  90. package/src/pages/index.tsx +10 -0
  91. package/src/pages/led-circuit-react.tsx +51 -0
  92. package/src/pages/led-circuit.tsx +91 -0
  93. package/src/schematic-components/MovableGrid/MovableGrid.stories.tsx +23 -0
  94. package/src/schematic-components/MovableGrid/index.tsx +4 -0
  95. package/src/schematic-components/ProjectComponent.tsx +62 -0
  96. package/src/schematic-components/RenderError.tsx +23 -0
  97. package/src/schematic-components/SVGPathComponent.tsx +64 -0
  98. package/src/schematic-components/SchematicBug.tsx +52 -0
  99. package/src/schematic-components/SchematicComponent.tsx +42 -0
  100. package/src/schematic-components/SchematicGroup.tsx +3 -0
  101. package/src/schematic-components/SchematicPort.tsx +39 -0
  102. package/src/schematic-components/SchematicText.tsx +41 -0
  103. package/src/schematic-components/SchematicTrace.tsx +48 -0
  104. package/src/schematic-components/SimpleCapacitor.tsx +29 -0
  105. package/src/schematic-components/SimpleDiode.tsx +38 -0
  106. package/src/schematic-components/SimpleGround.tsx +28 -0
  107. package/src/schematic-components/SimpleInductor.tsx +29 -0
  108. package/src/schematic-components/SimplePowerSource.tsx +30 -0
  109. package/src/schematic-components/SimpleResistor.tsx +28 -0
  110. package/src/schematic-components/index.tsx +17 -0
  111. package/tsconfig.json +31 -0
  112. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,51 @@
1
+ import React, { Fragment } from "react"
2
+ import { Schematic } from "Schematic"
3
+
4
+ export const ExampleCircuit = () => {
5
+ return (
6
+ <Schematic>
7
+ <resistor name="R1" resistance="10 ohm" center={[2, 1]} />
8
+ <capacitor
9
+ name="C1"
10
+ capacitance="10 uF"
11
+ center={[4, 2]}
12
+ rotation="90deg"
13
+ />
14
+ <resistor
15
+ name="R2"
16
+ resistance="10 ohm"
17
+ center={[6, 1]}
18
+ rotation="90deg"
19
+ />
20
+ <trace
21
+ path={[".R1 > port.right", ".C1 > port.left", ".R2 > port.left"]}
22
+ />
23
+ <powersource voltage="5V" center={[1, 2]} name="main_power" />
24
+ <trace path={[".main_power > port.positive", ".R1 > port.left"]} />
25
+ <trace
26
+ path={["power > port.negative", ".C1 > port.right", ".R2 > port.right"]}
27
+ />
28
+ <bug
29
+ name="B1"
30
+ port_arrangement={{ left_size: 3, right_size: 3 }}
31
+ center={[8, 3]}
32
+ port_labels={{
33
+ 1: "PWR",
34
+ 2: "NC",
35
+ 3: "RG",
36
+ 4: "D0",
37
+ 5: "D1",
38
+ 6: "GND",
39
+ }}
40
+ />
41
+ <trace path={[".B1 > port.PWR", ".R2 > port.left"]} />
42
+ <ground name="GND" center={[11, 3]} />
43
+ <trace from=".B1 > port.GND" to=".GND" />
44
+ <diode name="D1" center={[6, 3.5]} rotation="180deg" />
45
+ <trace from=".D1 > .left" to=".B1 > .RG" />
46
+ <trace from=".D1 > .right" to=".C1> .right" />
47
+ </Schematic>
48
+ )
49
+ }
50
+
51
+ export default ExampleCircuit
@@ -0,0 +1,91 @@
1
+ import { createProjectBuilder } from "@tscircuit/builder"
2
+ import { useMaybePromise } from "lib/hooks"
3
+ import { Schematic } from "../Schematic"
4
+
5
+ const pb = createProjectBuilder()
6
+ const $elements = pb
7
+ .addGroup((gb) =>
8
+ gb
9
+ .addResistor((rb) =>
10
+ rb
11
+ .setSourceProperties({
12
+ resistance: "10 ohm",
13
+ name: "R1",
14
+ })
15
+ .setSchematicCenter(2, 1)
16
+ )
17
+ .addCapacitor((cb) =>
18
+ cb
19
+ .setSourceProperties({
20
+ name: "C1",
21
+ capacitance: "10 uF",
22
+ })
23
+ .setSchematicCenter(4, 2)
24
+ .setSchematicRotation("90deg")
25
+ )
26
+ .addResistor((cb) =>
27
+ cb
28
+ .setSourceProperties({
29
+ resistance: "10 ohm",
30
+ name: "R2",
31
+ })
32
+ .setSchematicCenter(6, 1)
33
+ .setSchematicRotation("90deg")
34
+ )
35
+ .addTrace([".R1 > port.right", ".C1 > port.left", ".R2 > port.left"])
36
+ .addPowerSource((cb) =>
37
+ cb
38
+ .setSourceProperties({
39
+ voltage: "5V",
40
+ name: "main_power",
41
+ })
42
+ .setSchematicCenter(1, 2)
43
+ )
44
+ .addTrace(["power > port.positive", ".R1 > port.left"])
45
+ .addTrace([
46
+ "power > port.negative",
47
+ ".C1 > port.right",
48
+ ".R2 > port.right",
49
+ ])
50
+ .addBug((cb) =>
51
+ cb
52
+ .setSourceProperties({ name: "B1" })
53
+ .setSchematicProperties({
54
+ port_arrangement: {
55
+ left_size: 3,
56
+ right_size: 3,
57
+ },
58
+ })
59
+ .labelPort(1, "PWR")
60
+ .labelPort(2, "NC")
61
+ .labelPort(3, "RG")
62
+ .labelPort(4, "D0")
63
+ .labelPort(5, "D1")
64
+ .labelPort(6, "GND")
65
+ .setSchematicCenter(8, 3)
66
+ )
67
+ .addTrace([".B1 > port.PWR", ".R2 > port.left"])
68
+ .addGround((cb) =>
69
+ cb
70
+ .setSourceProperties({
71
+ name: "GND",
72
+ })
73
+ .setSchematicCenter(11, 3)
74
+ )
75
+ .addTrace([".B1 > port.GND", ".gnd"])
76
+ .addDiode((db) =>
77
+ db
78
+ .setSourceProperties({ name: "D1" })
79
+ .setSchematicCenter(6, 3.5)
80
+ .setSchematicRotation("180deg")
81
+ )
82
+ .addTrace([".D1 > .left", ".B1 > .RG"])
83
+ .addTrace([".D1 > .right", ".C1 > .right"])
84
+ )
85
+ .build(pb.createBuildContext())
86
+
87
+ export default () => {
88
+ const elements = useMaybePromise($elements)
89
+ if (!elements) return null
90
+ return <Schematic elements={elements} />
91
+ }
@@ -0,0 +1,23 @@
1
+ import React from "react"
2
+ import { ComponentStory, ComponentMeta } from "@storybook/react"
3
+
4
+ import { MovableGrid } from "./"
5
+
6
+ // More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
7
+ export default {
8
+ title: "MovableGrid",
9
+ component: MovableGrid,
10
+ // More on argTypes: https://storybook.js.org/docs/react/api/argtypes
11
+ } as ComponentMeta<typeof MovableGrid>
12
+
13
+ // More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
14
+ const Template: ComponentStory<typeof MovableGrid> = (args: any) => (
15
+ <MovableGrid {...args} />
16
+ )
17
+
18
+ export const Primary = Template.bind({})
19
+ // More on args: https://storybook.js.org/docs/react/writing-stories/args
20
+ Primary.args = {
21
+ primary: true,
22
+ label: "MovableGrid",
23
+ }
@@ -0,0 +1,4 @@
1
+ export const MovableGrid = () => {
2
+ return <div>{`asd`}</div>
3
+ }
4
+ export default MovableGrid
@@ -0,0 +1,62 @@
1
+ import { useMaybePromise } from "lib/hooks"
2
+ import { ProjectClass } from "@tscircuit/builder"
3
+ import * as Types from "lib/types"
4
+ import * as Components from "./"
5
+
6
+ interface Props {
7
+ project: Types.Project | Promise<Types.Project>
8
+ }
9
+
10
+ export const ProjectComponent = ({ project: $project }: Props) => {
11
+ const project = useMaybePromise($project)
12
+
13
+ if (!project) return <span>loading</span>
14
+
15
+ const projectClass = new ProjectClass(project as any)
16
+
17
+ return (
18
+ <>
19
+ {project.schematic_components.map((schematic_component) => (
20
+ <Components.SchematicComponent
21
+ key={schematic_component.schematic_component_id}
22
+ component={{
23
+ source: projectClass.getSourceComponent(
24
+ schematic_component.source_component_id
25
+ ),
26
+ schematic: schematic_component,
27
+ }}
28
+ />
29
+ ))}
30
+ {project.schematic_ports.map((schematic_port) => (
31
+ <Components.SchematicPort
32
+ key={schematic_port.schematic_port_id}
33
+ port={{
34
+ source: projectClass.getSourcePort(
35
+ schematic_port.schematic_port_id
36
+ ),
37
+ schematic: schematic_port,
38
+ }}
39
+ />
40
+ ))}
41
+ {project.schematic_traces.map((schematic_trace) => (
42
+ <Components.SchematicTrace
43
+ key={schematic_trace.schematic_trace_id}
44
+ trace={{
45
+ source: projectClass.getSourceTrace(
46
+ schematic_trace.source_trace_id
47
+ ),
48
+ schematic: schematic_trace,
49
+ }}
50
+ />
51
+ ))}
52
+ {project.schematic_texts.map((schematic_text) => (
53
+ <Components.SchematicText
54
+ key={schematic_text.schematic_text_id}
55
+ schematic_text={schematic_text}
56
+ />
57
+ ))}
58
+ </>
59
+ )
60
+ }
61
+
62
+ export default ProjectComponent
@@ -0,0 +1,23 @@
1
+ interface Props {
2
+ text: string
3
+ }
4
+
5
+ export default ({ text }: Props) => {
6
+ return (
7
+ <div
8
+ style={{
9
+ position: "fixed",
10
+ backgroundColor: "red",
11
+ color: "white",
12
+ fontSize: 14,
13
+ fontFamily: "sans-serif",
14
+ padding: 5,
15
+ right: 0,
16
+ top: 0,
17
+ opacity: 0.75,
18
+ }}
19
+ >
20
+ {text}
21
+ </div>
22
+ )
23
+ }
@@ -0,0 +1,64 @@
1
+ import { useCameraTransform } from "lib/render-context"
2
+ import getSVGPathBounds from "lib/utils/get-svg-path-bounds"
3
+
4
+ import { applyToPoint } from "transformation-matrix"
5
+
6
+ interface Props {
7
+ rotation: number
8
+ center: { x: number; y: number }
9
+ size: { width: number; height: number }
10
+ paths: Array<{
11
+ strokeWidth: number
12
+ stroke: string
13
+ d: string
14
+ }>
15
+ }
16
+
17
+ export const SVGPathComponent = ({ size, center, rotation, paths }: Props) => {
18
+ const ct = useCameraTransform()
19
+ const pathBounds = getSVGPathBounds(paths.map((p) => p.d))
20
+ // Margin in SVG Space
21
+ const badRatio =
22
+ Math.abs(pathBounds.width / pathBounds.height - size.width / size.height) >
23
+ 0.01
24
+ if (badRatio) {
25
+ console.warn(
26
+ `Ratio doesn't match for component. ${pathBounds.width}:${pathBounds.height} is not close to ${size.width}:${size.height}`
27
+ )
28
+ }
29
+ pathBounds.height = Math.max(pathBounds.height, 1)
30
+ pathBounds.width = Math.max(pathBounds.width, 1)
31
+ const absoluteCenter = applyToPoint(ct, center)
32
+ const absoluteSize = {
33
+ width: Math.max(1, size.width * ct.a),
34
+ height: Math.max(1, size.height * ct.d),
35
+ }
36
+
37
+ return (
38
+ <svg
39
+ style={{
40
+ position: "absolute",
41
+ transform: rotation === 0 ? "" : `rotate(${rotation}rad)`,
42
+ left: absoluteCenter.x - absoluteSize.width / 2,
43
+ top: absoluteCenter.y - absoluteSize.height / 2,
44
+ // backgroundColor: badRatio ? "rgba(255, 0, 0, 0.5)" : "transparent",
45
+ }}
46
+ overflow="visible"
47
+ width={absoluteSize.width}
48
+ height={absoluteSize.height}
49
+ viewBox={`${pathBounds.minX} ${pathBounds.minY} ${pathBounds.width} ${pathBounds.height}`}
50
+ >
51
+ {paths.map((p, i) => (
52
+ <path
53
+ key={i}
54
+ fill="none"
55
+ strokeWidth={2 * (p.strokeWidth || 1)}
56
+ stroke={p.stroke || "red"}
57
+ d={p.d}
58
+ />
59
+ ))}
60
+ </svg>
61
+ )
62
+ }
63
+
64
+ export default SVGPathComponent
@@ -0,0 +1,52 @@
1
+ import * as Type from "lib/types"
2
+ import SVGPathComponent from "./SVGPathComponent"
3
+ import range from "lodash/range"
4
+
5
+ interface Props {
6
+ component: {
7
+ source: Type.SimpleBug
8
+ schematic: Type.SchematicComponent
9
+ }
10
+ }
11
+
12
+ export const SchematicBug = ({ component: { source, schematic } }: Props) => {
13
+ const ports_arrangement = schematic.port_arrangement!
14
+ const port_labels = schematic.port_labels!
15
+ const bugw = 30 // bug width
16
+ const rh = 15 // row height
17
+ const pd = 7.5 // port distance, the line for each port
18
+ const bugh =
19
+ Math.max(ports_arrangement.left_size, ports_arrangement.right_size) * rh
20
+ // TODO throw if schematic.size doesn't match computed ports_arrangement size
21
+ return (
22
+ <SVGPathComponent
23
+ rotation={schematic.rotation}
24
+ center={schematic.center}
25
+ size={schematic.size}
26
+ paths={[
27
+ {
28
+ stroke: "red",
29
+ strokeWidth: 1,
30
+ d: `M 0 0 L ${bugw} 0 L ${bugw} ${bugh} L 0 ${bugh}Z`,
31
+ },
32
+ ...range(
33
+ 0,
34
+ ports_arrangement.left_size + ports_arrangement.right_size
35
+ ).map((i) => {
36
+ const ls = ports_arrangement.left_size
37
+ const left = i < ls
38
+ const rowi = i % ls
39
+ const p1 = [left ? 0 : bugw, rh / 2 + rowi * rh]
40
+ const rd = [left ? -pd : pd, 0]
41
+ return {
42
+ stroke: "red",
43
+ strokeWidth: 1,
44
+ d: `M ${p1.join(" ")} l ${rd.join(" ")}`,
45
+ }
46
+ }),
47
+ ]}
48
+ />
49
+ )
50
+ }
51
+
52
+ export default SchematicBug
@@ -0,0 +1,42 @@
1
+ import { ProjectClass } from "tscircuit"
2
+ import * as Type from "lib/types"
3
+ import * as Component from "./"
4
+
5
+ interface Props {
6
+ component: {
7
+ source: Type.SourceComponent
8
+ schematic: Type.SchematicComponent
9
+ }
10
+ }
11
+
12
+ export const SchematicComponent = ({ component }: Props) => {
13
+ const { source, schematic } = component
14
+ switch (source.ftype) {
15
+ case "simple_resistor": {
16
+ return <Component.SimpleResistor component={{ source, schematic }} />
17
+ }
18
+ case "simple_capacitor": {
19
+ return <Component.SimpleCapacitor component={{ source, schematic }} />
20
+ }
21
+ case "simple_power_source": {
22
+ return <Component.SimplePowerSource component={{ source, schematic }} />
23
+ }
24
+ case "simple_ground": {
25
+ return <Component.SimpleGround component={{ source, schematic }} />
26
+ }
27
+ case "simple_inductor": {
28
+ return <Component.SimpleInductor component={{ source, schematic }} />
29
+ }
30
+ case "simple_bug": {
31
+ return <Component.SchematicBug component={{ source, schematic }} />
32
+ }
33
+ case "simple_diode": {
34
+ return <Component.SimpleDiode component={{ source, schematic }} />
35
+ }
36
+ default: {
37
+ return <div>unknown ftype: {component.source.ftype}</div>
38
+ }
39
+ }
40
+ }
41
+
42
+ export default SchematicComponent
@@ -0,0 +1,3 @@
1
+ export const SchematicGroup = () => {
2
+ return null
3
+ }
@@ -0,0 +1,39 @@
1
+ import { ProjectClass } from "tscircuit"
2
+ import * as Type from "lib/types"
3
+ import { directionToVec } from "lib/utils/direction-to-vec"
4
+ import * as Component from "./"
5
+
6
+ interface Props {
7
+ port: {
8
+ source: Type.SourcePort
9
+ schematic: Type.SchematicPort
10
+ }
11
+ }
12
+
13
+ export const SchematicPort = ({ port: { source, schematic } }: Props) => {
14
+ return (
15
+ <Component.SVGPathComponent
16
+ rotation={0}
17
+ center={schematic.center}
18
+ size={{ width: 0.2, height: 0.2 }}
19
+ paths={[
20
+ {
21
+ stroke: "blue",
22
+ strokeWidth: 1,
23
+ d: "M 0 0 l 10 0 l 0 10 l -10 0 z",
24
+ },
25
+ schematic.facing_direction
26
+ ? {
27
+ stroke: "blue",
28
+ strokeWidth: 0.5,
29
+ d: `M 5 5 l ${directionToVec(schematic.facing_direction).x * 7} ${
30
+ directionToVec(schematic.facing_direction).y * 7
31
+ }`,
32
+ }
33
+ : null,
34
+ ].filter(Boolean)}
35
+ />
36
+ )
37
+ }
38
+
39
+ export default SchematicPort
@@ -0,0 +1,41 @@
1
+ import * as Type from "lib/types"
2
+ import SVGPathComponent from "./SVGPathComponent"
3
+ import Path from "svg-path-generator"
4
+ import getSVGPathBounds from "lib/utils/get-svg-path-bounds"
5
+ import { useCameraTransform } from "lib/render-context"
6
+ import { applyToPoint } from "transformation-matrix"
7
+ import useMeasure from "react-use-measure"
8
+
9
+ interface Props {
10
+ schematic_text: Type.SchematicText
11
+ }
12
+
13
+ export const SchematicText = ({ schematic_text }: Props) => {
14
+ const ct = useCameraTransform()
15
+ const { text, position, anchor } = schematic_text
16
+ const tPos = applyToPoint(ct, position)
17
+ const [boundsRef, bounds] = useMeasure()
18
+ let offset = [0, 0]
19
+ if (anchor === "center") {
20
+ offset = [-bounds.width / 2, -bounds.height / 2]
21
+ } else if (anchor === "left") {
22
+ offset = [0, -bounds.height / 2]
23
+ } else if (anchor === "right") {
24
+ offset = [-bounds.width, -bounds.height / 2]
25
+ }
26
+ return (
27
+ <div
28
+ ref={boundsRef}
29
+ style={{
30
+ fontFamily: "'IBM Plex Mono', monospace",
31
+ position: "absolute",
32
+ left: tPos.x + offset[0],
33
+ top: tPos.y + offset[1],
34
+ }}
35
+ >
36
+ {text}
37
+ </div>
38
+ )
39
+ }
40
+
41
+ export default SchematicText
@@ -0,0 +1,48 @@
1
+ import * as Type from "lib/types"
2
+ import SVGPathComponent from "./SVGPathComponent"
3
+ import Path from "svg-path-generator"
4
+ import getSVGPathBounds from "lib/utils/get-svg-path-bounds"
5
+ import RenderError from "./RenderError"
6
+
7
+ interface Props {
8
+ trace: {
9
+ source: Type.SourceTrace
10
+ schematic: Type.SchematicTrace
11
+ }
12
+ }
13
+
14
+ export const SchematicTrace = ({ trace: { source, schematic } }: Props) => {
15
+ const edges = schematic.edges
16
+ if (edges.length === 0) {
17
+ return <RenderError text="Route with 0 edges" />
18
+ }
19
+ const path = Path()
20
+ for (let i = 0; i < edges.length; i++) {
21
+ path.moveTo(edges[i].from.x, edges[i].from.y)
22
+ path.lineTo(edges[i].to.x, edges[i].to.y)
23
+ }
24
+ const d = path.toString()
25
+ const pathBounds = getSVGPathBounds(d)
26
+ pathBounds.height = Math.max(pathBounds.height, 1)
27
+ pathBounds.width = Math.max(pathBounds.width, 1)
28
+ const center = {
29
+ x: pathBounds.minX + pathBounds.width / 2,
30
+ y: pathBounds.minY + pathBounds.height / 2,
31
+ }
32
+ return (
33
+ <SVGPathComponent
34
+ rotation={0}
35
+ center={center}
36
+ size={pathBounds}
37
+ paths={[
38
+ {
39
+ stroke: "green",
40
+ strokeWidth: 0.02,
41
+ d,
42
+ },
43
+ ]}
44
+ />
45
+ )
46
+ }
47
+
48
+ export default SchematicTrace
@@ -0,0 +1,29 @@
1
+ import * as Type from "lib/types"
2
+ import SVGPathComponent from "./SVGPathComponent"
3
+
4
+ interface Props {
5
+ component: {
6
+ source: Type.SimpleCapacitor
7
+ schematic: Type.SchematicComponent
8
+ }
9
+ }
10
+
11
+ export const SimpleCapacitor = ({
12
+ component: { source, schematic },
13
+ }: Props) => {
14
+ return (
15
+ <SVGPathComponent
16
+ rotation={schematic.rotation}
17
+ center={schematic.center}
18
+ size={schematic.size}
19
+ paths={[
20
+ { stroke: "red", strokeWidth: 1, d: "M 0 15 l 12 0" },
21
+ { stroke: "red", strokeWidth: 2, d: "M 12 0 l 0 30" },
22
+ { stroke: "red", strokeWidth: 2, d: "M 18 0 l 0 30" },
23
+ { stroke: "red", strokeWidth: 1, d: "M 18 15 l 12 0" },
24
+ ]}
25
+ />
26
+ )
27
+ }
28
+
29
+ export default SimpleCapacitor
@@ -0,0 +1,38 @@
1
+ import * as Type from "lib/types"
2
+ import SVGPathComponent from "./SVGPathComponent"
3
+
4
+ interface Props {
5
+ component: {
6
+ source: Type.SimpleDiode
7
+ schematic: Type.SchematicComponent
8
+ }
9
+ }
10
+
11
+ export const SimpleDiode = ({ component: { source, schematic } }: Props) => {
12
+ return (
13
+ <SVGPathComponent
14
+ rotation={schematic.rotation}
15
+ center={schematic.center}
16
+ size={schematic.size}
17
+ paths={[
18
+ { stroke: "red", strokeWidth: 2, d: "M 0,0 H 21" },
19
+ { stroke: "red", strokeWidth: 2, d: "M 49,0 H 59" },
20
+ { stroke: "red", strokeWidth: 2, d: "M 49,0 L 21 14 V -14 Z" },
21
+ { stroke: "red", strokeWidth: 2, d: "M 49,-14 V 14" },
22
+ // For LEDs
23
+ // {
24
+ // stroke: "red",
25
+ // strokeWidth: 2,
26
+ // d: "M 35 -32 l 7 5.25 l 1.75 -9.625 z m 3.5 2.625 l -5.25 7",
27
+ // },
28
+ // {
29
+ // stroke: "red",
30
+ // strokeWidth: 2,
31
+ // d: "M 52 -26 l 7 5.25 l 1.75 -9.625 z m 3.5 2.625 l -5.25 7",
32
+ // },
33
+ ]}
34
+ />
35
+ )
36
+ }
37
+
38
+ export default SimpleDiode
@@ -0,0 +1,28 @@
1
+ import * as Type from "lib/types"
2
+ import SVGPathComponent from "./SVGPathComponent"
3
+
4
+ interface Props {
5
+ component: {
6
+ source: Type.SimpleGround
7
+ schematic: Type.SchematicComponent
8
+ }
9
+ }
10
+
11
+ export const SimpleGround = ({ component: { source, schematic } }: Props) => {
12
+ return (
13
+ <SVGPathComponent
14
+ rotation={schematic.rotation}
15
+ center={schematic.center}
16
+ size={schematic.size}
17
+ paths={[
18
+ {
19
+ stroke: "red",
20
+ strokeWidth: 0.7,
21
+ d: "M -3 3 L 3 3 M -6 0 L 6 0 M -9 -3 L 9 -3 M 0 -3 L 0 -12",
22
+ },
23
+ ]}
24
+ />
25
+ )
26
+ }
27
+
28
+ export default SimpleGround
@@ -0,0 +1,29 @@
1
+ import * as Type from "lib/types"
2
+ import SVGPathComponent from "./SVGPathComponent"
3
+
4
+ interface Props {
5
+ component: {
6
+ source: Type.SimpleInductor
7
+ schematic: Type.SchematicComponent
8
+ }
9
+ }
10
+
11
+ export const SimpleInductor = ({ component: { source, schematic } }: Props) => {
12
+ return (
13
+ <SVGPathComponent
14
+ rotation={schematic.rotation}
15
+ center={schematic.center}
16
+ size={schematic.size}
17
+ paths={[
18
+ {
19
+ stroke: "red",
20
+ strokeWidth: 1,
21
+ // https://commons.wikimedia.org/wiki/File:Electrical_symbols_library.svg
22
+ d: "m 371,710.41665 h -14 c -0.0421,-16.39898 -14.02104,-16.39898 -14,0 -0.021,-16.399 -14.04182,-16.34072 -14,0 -2.6e-4,-16.45722 -14.04236,-16.45722 -14,0 2.8e-4,-16.3407 -13.97896,-16.39898 -14,0 -0.0421,-16.39898 -13.91338,-16.39898 -13.91338,0 H 273",
23
+ },
24
+ ]}
25
+ />
26
+ )
27
+ }
28
+
29
+ export default SimpleInductor