@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.
- package/.prettierrc +1 -0
- package/.storybook/main.js +15 -0
- package/.storybook/preview.js +9 -0
- package/README.md +26 -0
- package/ava.config.js +7 -0
- package/dist/Schematic.js +8606 -0
- package/dist/Schematic.js.map +1 -0
- package/dist/lib/hooks/index.js +2170 -0
- package/dist/lib/hooks/index.js.map +1 -0
- package/dist/lib/hooks/use-maybe-promise.js +2170 -0
- package/dist/lib/hooks/use-maybe-promise.js.map +1 -0
- package/dist/lib/render-context/index.js +45 -0
- package/dist/lib/render-context/index.js.map +1 -0
- package/dist/lib/types/core.js +18 -0
- package/dist/lib/types/core.js.map +1 -0
- package/dist/lib/types/index.js +18 -0
- package/dist/lib/types/index.js.map +1 -0
- package/dist/lib/types/route-solver.js +18 -0
- package/dist/lib/types/route-solver.js.map +1 -0
- package/dist/lib/types/source-component.js +18 -0
- package/dist/lib/types/source-component.js.map +1 -0
- package/dist/lib/types/util.js +18 -0
- package/dist/lib/types/util.js.map +1 -0
- package/dist/lib/utils/direction-to-vec.js +96 -0
- package/dist/lib/utils/direction-to-vec.js.map +1 -0
- package/dist/lib/utils/get-svg-path-bounds.js +51 -0
- package/dist/lib/utils/get-svg-path-bounds.js.map +1 -0
- package/dist/lib/utils/point-math.js +57 -0
- package/dist/lib/utils/point-math.js.map +1 -0
- package/dist/pages/_app.js +2714 -0
- package/dist/pages/_app.js.map +1 -0
- package/dist/pages/index.js +8612 -0
- package/dist/pages/index.js.map +1 -0
- package/dist/pages/led-circuit-react.js +2185 -0
- package/dist/pages/led-circuit-react.js.map +1 -0
- package/dist/pages/led-circuit.js +8656 -0
- package/dist/pages/led-circuit.js.map +1 -0
- package/dist/schematic-components/MovableGrid/MovableGrid.stories.js +47 -0
- package/dist/schematic-components/MovableGrid/MovableGrid.stories.js.map +1 -0
- package/dist/schematic-components/MovableGrid/index.js +34 -0
- package/dist/schematic-components/MovableGrid/index.js.map +1 -0
- package/dist/schematic-components/ProjectComponent.js +8584 -0
- package/dist/schematic-components/ProjectComponent.js.map +1 -0
- package/dist/schematic-components/RenderError.js +40 -0
- package/dist/schematic-components/RenderError.js.map +1 -0
- package/dist/schematic-components/SVGPathComponent.js +90 -0
- package/dist/schematic-components/SVGPathComponent.js.map +1 -0
- package/dist/schematic-components/SchematicBug.js +468 -0
- package/dist/schematic-components/SchematicBug.js.map +1 -0
- package/dist/schematic-components/SchematicComponent.js +8451 -0
- package/dist/schematic-components/SchematicComponent.js.map +1 -0
- package/dist/schematic-components/SchematicGroup.js +32 -0
- package/dist/schematic-components/SchematicGroup.js.map +1 -0
- package/dist/schematic-components/SchematicPort.js +8348 -0
- package/dist/schematic-components/SchematicPort.js.map +1 -0
- package/dist/schematic-components/SchematicText.js +71 -0
- package/dist/schematic-components/SchematicText.js.map +1 -0
- package/dist/schematic-components/SchematicTrace.js +137 -0
- package/dist/schematic-components/SchematicTrace.js.map +1 -0
- package/dist/schematic-components/SimpleCapacitor.js +103 -0
- package/dist/schematic-components/SimpleCapacitor.js.map +1 -0
- package/dist/schematic-components/SimpleDiode.js +101 -0
- package/dist/schematic-components/SimpleDiode.js.map +1 -0
- package/dist/schematic-components/SimpleGround.js +102 -0
- package/dist/schematic-components/SimpleGround.js.map +1 -0
- package/dist/schematic-components/SimpleInductor.js +102 -0
- package/dist/schematic-components/SimpleInductor.js.map +1 -0
- package/dist/schematic-components/SimplePowerSource.js +104 -0
- package/dist/schematic-components/SimplePowerSource.js.map +1 -0
- package/dist/schematic-components/SimpleResistor.js +102 -0
- package/dist/schematic-components/SimpleResistor.js.map +1 -0
- package/dist/schematic-components/index.js +8618 -0
- package/dist/schematic-components/index.js.map +1 -0
- package/next-env.d.ts +5 -0
- package/package.json +52 -0
- package/parsel.d.ts +81 -0
- package/src/Schematic.tsx +40 -0
- package/src/lib/hooks/index.ts +1 -0
- package/src/lib/hooks/use-maybe-promise.ts +14 -0
- package/src/lib/render-context/index.ts +15 -0
- package/src/lib/types/core.ts +179 -0
- package/src/lib/types/index.ts +4 -0
- package/src/lib/types/route-solver.ts +10 -0
- package/src/lib/types/source-component.ts +63 -0
- package/src/lib/types/util.ts +52 -0
- package/src/lib/utils/direction-to-vec.ts +50 -0
- package/src/lib/utils/get-svg-path-bounds.ts +22 -0
- package/src/lib/utils/point-math.ts +26 -0
- package/src/pages/_app.tsx +23 -0
- package/src/pages/index.tsx +10 -0
- package/src/pages/led-circuit-react.tsx +51 -0
- package/src/pages/led-circuit.tsx +91 -0
- package/src/schematic-components/MovableGrid/MovableGrid.stories.tsx +23 -0
- package/src/schematic-components/MovableGrid/index.tsx +4 -0
- package/src/schematic-components/ProjectComponent.tsx +62 -0
- package/src/schematic-components/RenderError.tsx +23 -0
- package/src/schematic-components/SVGPathComponent.tsx +64 -0
- package/src/schematic-components/SchematicBug.tsx +52 -0
- package/src/schematic-components/SchematicComponent.tsx +42 -0
- package/src/schematic-components/SchematicGroup.tsx +3 -0
- package/src/schematic-components/SchematicPort.tsx +39 -0
- package/src/schematic-components/SchematicText.tsx +41 -0
- package/src/schematic-components/SchematicTrace.tsx +48 -0
- package/src/schematic-components/SimpleCapacitor.tsx +29 -0
- package/src/schematic-components/SimpleDiode.tsx +38 -0
- package/src/schematic-components/SimpleGround.tsx +28 -0
- package/src/schematic-components/SimpleInductor.tsx +29 -0
- package/src/schematic-components/SimplePowerSource.tsx +30 -0
- package/src/schematic-components/SimpleResistor.tsx +28 -0
- package/src/schematic-components/index.tsx +17 -0
- package/tsconfig.json +31 -0
- 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,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,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
|