Learn Bluefish
The planets diagram consists of a row of four circles that represent the first four terrestrial planets. There is box behind them and a label for Mercury. There is also an arrow pointing from the label to Mercury.
- How to write a Bluefish specification using JSX.
- How to use common Bluefish elements (like
Circle
) and relations (likeAlign
). - How to use the
Ref
component to reference other components.
Writing Bluefish Specifications with JSX
Bluefish's JSX syntax is only available in SolidJS environments. If you are working in other environments like Svelte or Observable, you will instead need to use Bluefish's function syntax.
(This section of the tutorial is based on React's documentation.)
To write a Bluefish specification (or spec), you typically use JSX syntax. JSX is a syntax extension to JavaScript that lets you write HTML-like code in JavaScript. For example, the following is JSX code:
<h1>Hello, world!</h1>
We typically call an element like h1
a component. Components are the building blocks of Bluefish
specifications.
JSX is stricter than HTML. You have to close tags like <br />
. Your component also can't return
multiple JSX tags. You have to wrap them into a shared parent, like a <div>...</div>
or an empty
<>...</>
wrapper:
<>
<h1>Hello, world!</h1>
<br />
<p>This is a paragraph.</p>
</>
Unlike built-in HTML components, Bluefish components are written with capital letters, like Circle
or Row
. Bluefish components can only be used within a Bluefish specification, which is scoped by a
<Bluefish>
component.
<Bluefish>
<Circle cx={20} cy={30} r={15} fill="#EBE3CF" stroke-width={3} stroke="black" />
</Bluefish>
Your First Bluefish Diagram
1. Make a Circle
It's time to add your first Bluefish component!
The first thing we'll do is draw the planet Mercury.
Replace the Text
component in the editor with the code below.
<Circle cx={20} cy={30} r={15} fill="#EBE3CF" stroke-width={3} stroke="black" />
2. Add the Other Planets
Now we can add the other planets. Append this code below the Mercury circle.
<Circle cx={100} cy={30} r={36} fill="#DC933C" stroke-width={3} stroke="black" />
<Circle cx={160} cy={30} r={38} fill="#179DD7" stroke-width={3} stroke="black" />
<Circle cx={280} cy={30} r={21} fill="#F1CF8E" stroke-width={3} stroke="black" />
It's hard to make the circles evenly spaced by hand. See if you can do it!
3. Put Circles in a StackH
Instead of placing the circles manually, we can use a StackH
component to position them.
StackH
distributes its children horizontally and aligns them vertically.
Add the StackH
component to the diagram and put the Circle
s inside it.
<StackH spacing={50}>circles go here</StackH>
Then delete the positions (cx
and cy
) on the Circle
s. For example,
<Circle cx={20} cy={30} r={15} fill="#EBE3CF" stroke-width={3} stroke="black" />
should become
<Circle r={15} fill="#EBE3CF" stroke-width={3} stroke="black" />
Try changing the spacing or the size of the circles. What happens?
4. Add a Background
To add a background, we can wrap the StackH
in a Background
component.
<Background padding={20}>stackH goes here</Background>
5. Add a Label
Now it's time to add a label to the Mercury circle. So far, we've been building a hierarchical tree of components. But now we need to reference the circle that's in the stack in order to position it.
To do so, we'll first name the circle, then we'll select it later in the code. To name the
first circle in the row, we'll add a name
prop to it.
<Circle name="mercury" ... />
Then we can add a label by making a StackV
with Text
for the label and a Ref
to the planet.
Place this below the Background
component, but inside the Bluefish
component.
<StackV spacing={20}>
<Text>Mercury</Text>
<Ref select="mercury" />
</StackV>
6. Add an Arrow
Now let's draw an arrow from the label to the planet. To do so, we'll first name the label:
<Text name="label">Mercury</Text>
Then we'll add an Arrow
component, pointing from the label to the planet. We can place this below
the StackV
component, but inside the Bluefish
component.
<Arrow>
<Ref select="label" />
<Ref select="mercury" />
</Arrow>
7. Improve the label spacing
We want the label to always be outside the background box, but right now the label is spaced
relative to the planet. We can replace the StackV
component with horizontal Align
and vertical
Distribute
to position the label more precisely.
First, replace the StackV
component with an Align
.
<Align alignment="centerX">Keep the same children as StackV</Align>
Then we'll name the planets earlier in the diagram:
<Background name="planets" ... >
...
</Background>
Then add a Distribute
. We can place this below the Align
and above the Arrow
:
<Distribute direction="vertical" spacing={20}>
<Ref select="label" />
<Ref select="planets" />
</Distribute>
import { Bluefish, Group, StackH, Circle, Text, Ref, Background, Arrow, StackV, Align, Distribute } from "@bluefish-js/solid"; const App = () => { return ( <Bluefish> <Text>TODO: Starting writing your code here!</Text> </Bluefish> ); }; export default App;
Simple Variations
Here are some simple variations on the diagram to test your knowledge. If you want to reveal the answer, click "Open Sandbox" on the variation. We've provided the solution to the tutorial above in the sandbox on your right.
import { Bluefish, Group, StackH, StackV, Circle, Text, Ref, Background, Arrow, Align, Distribute, Rect } from "@bluefish-js/solid"; const App = () => { return ( <Bluefish> <Background padding={20}> <StackH spacing={50}> <Circle name="mercury" r={15} fill="#EBE3CF" stroke-width={3} stroke="black" /> <Circle r={36} fill="#DC933C" stroke-width={3} stroke="black" /> <Circle r={38} fill="#179DD7" stroke-width={3} stroke="black" /> <Circle r={21} fill="#F1CF8E" stroke-width={3} stroke="black" /> </StackH> </Background> <Align alignment="centerX"> <Text name="label">Mercury</Text> <Ref select="mercury" /> </Align> <Distribute direction="vertical" spacing={60}> <Ref select="label" /> <Ref select="mercury" /> </Distribute> <Arrow> <Ref select="label" /> <Ref select="mercury" /> </Arrow> </Bluefish> ); }; export default App;