Coder Social home page Coder Social logo

bluefish's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

bluefish's Issues

Generalize logic for Context and Fragment nodes

Currently context and fragment node handling isn't very smart. Many points assume there is only a single child. e.g. you have to add a top-level Group component beneath an SVG for context to work. And if you have multiple child fragments then measurement only runs for the first child.

We need to generalize this logic. The crux of the difficulty is that Context and Fragment nodes can appear arbitrarily deep in the tree.

Separate repo into test and publishable packages.

To let other people use Bluefish, we need to separate the test React app from the package stuff. We did this with the previous Bluefish version so it shouldn't be too bad.

Once we do this, though, major modifications will require bumping the version number of republishing.

The benefit is that other people (e.g. Geoffrey) can use it in their own projects.

Expose domref in Measurable

Currently the underlying dom reference is opaque to consumers of a component. This is a problem, because a consumer may want to e.g. rasterize that component for further processing.

We can expose the dom ref by extending the Measurable type and wrapping basic components in forwardRef then forwarding that ref to the dom.

Implement Vega Label Algorithm

Implement Vega Label as a reusable Bluefish component: https://github.com/vega/vega-label

This will require developing a rasterization interface. This might be a bit tricky since currently we only pass around bbox information, which is resolved at measurement time.

Rasterization is performed at render time. Moreover, rasterization in Vega Label is performed using canvas, but we're currently using SVG.

Pass children to Layout+Mark Components

Pure layout components have a natural default rendering behavior.
Marks don't have to worry about children.

But components that both perform measurements using child components and do rendering (like lines) need access to their children at render time b/c right now we just always inject component children as SVG children. This doesn't work b/c giving a line children doesn't make any sense, and more importantly doesn't render.

Custom data API for components i.e. allow users to create custom interfaces

Implementation effort: There is a base level of effort for threading custom interface extensions through all the existing code & deciding what the API would look like.
e.g. boundary Bézier curves. Useful for…
Euclidean geometry (requires e.g. identifying intersections between two components)
Calculus (requires e.g. computing tangents)
Boundary/line labels (requires intelligent placement along curves)
Arrows & other connectors
Incidentally would fix the line problem we have with the tree examples in a less hacky way (i.e. avoids negative widths and heights)
Implementation effort: Fortunately there are some pretty good existing Bézier curve JS libraries that we could use (e.g. paperjs). so the main hurdle is in exposing the actual interface
e.g. rasterization. Useful for…
Vega point labels
Precise placement algorithms e.g. positioning things in an organic blobby shape
Implementation effort: This could be a bit tricky since we need we are currently use SVG to render, but would need to render to canvas for rasterization (e.g. using canvg). We could also switch completely to canvas rendering, but that’s a bigger lift.
e.g. polygon approximation. Useful for…
Vega area labels
Optimizations for rasterization algorithms
Implementation effort: Again things like paperjs have nice interfaces for this stuff

Fix view tearing during interaction.

There's some tearing right now, which you can see in the markops lagging behind the character list.

CleanShot 2022-10-24 at 16 42 11

I'm not sure why this happens. It might have something to do with concurrent renders. See e.g. reactwg/react-18#69. It might have to do with useContext being updated in a way I don't expect.

Experiment with APIs for specifying references

With more complex Bluefish structures, specifying references will get trickier. Right now we use a global context for the entire diagram, but this is not very good for composability b/c of name conflicts
We might need a more complex query/selection API for e.g. grabbing the second element of a list of items
There’s not an immediate need in any of our examples (or near term examples) to implement this, though…

Alignment guides

Components like text need additional guidelines like baseline to be used effectively. TeX equation layout also requires guidelines. Custom images, too, often have natural guidelines that need to be used sometimes.
This is a pretty standard part of declarative UI frameworks, and we could probably just copy their approach.
On the other hand, alignment guides could just be seen as another custom interface (see above)

Porting existing layout techniques like tidy tree, graphviz, TeX paragraph layout, TeX equation layout

This enables higher-fidelity, more real examples like nice-looking trees, annotated mathematics, etc.
There is some interesting reuse/modularity possible with these algorithms that is hard to access today. All the layout techniques I mentioned use things like bounding boxes and alignment+spacing to specify their outputs. These boxes could then be annotated/etc. using Bluefish abstractions. Some of the boxes could be replaced by arbitrary figures e.g. have a LaTeX fraction with diagrams on top and bottom instead of math expressions (cf. Andrew Head’s math augmentations paper)
This is more-or-less “just” ripping out existing algorithms and fitting them into the Bluefish ecosystem. But those scare quotes are hiding a significant amount of effort. I already have certain versions of this for tidy tree and graphviz for the older version of Bluefish, though.

Modifiers

View/component modifiers are another common piece of UI frameworks. Instead of wrapping a component in e.g. a padding component and a background component and a translation component and a…, you pass these in as modifiers to a component
These sort of act like special syntax for single-child components, but at least in Jetpack Compose they have a slightly different semantics (though I’m not sure what it is…)

Read-Write Dimension Interface

Consider adding to the type system a way to track which values are undefined and which one aren't.

This is useful for defining interfaces to a component e.g. if you want a component to have a known size or if it cannot determine its own size and must be set later by another component.

Updating props doesn't update diagram

Expected behavior: passing new prop values to a diagram component should update the diagram

Observed behavior: some prop updates work, but not others. Example where it doesn't work:

CleanShot.2022-09-29.at.16.42.29.mp4

Code for this:

function App() {
  test_blob();
  const [startOpId, setStartOpId] = React.useState('5@B');
  return (
    <div className="App">
      <select value={startOpId} onChange={(e) => setStartOpId(e.target.value)}>
        {['5@B', '6@B', '7@A'].map((opId) => (
          <option value={opId}>{opId}</option>
        ))}
      </select>
      "OP ID": {startOpId}
      {
        <Peritext
          chars={[
            { value: 'T', opId: '1@A', deleted: false, marks: ['italic'] },
            { value: 'h', opId: '2@A', deleted: true, marks: ['italic'] },
            { value: 'e', opId: '5@B', deleted: false, marks: ['bold', 'italic'] },
            { value: ' ', opId: '6@B', deleted: false, marks: ['bold', 'italic'] },
            { value: 'f', opId: '7@A', deleted: false, marks: ['bold'] },
            { value: 'o', opId: '8@A', deleted: true, marks: [] },
            { value: 'x', opId: '9@A', deleted: false, marks: [] },
          ]}
          markOps={[
            {
              action: 'addMark',
              opId: '18@A',
              start: { opId: startOpId },
              end: { opId: '7@A' },
              markType: 'bold',
              backgroundColor: '#F9EEEE',
              borderColor: '#E57E97',
            },
            {
              action: 'addMark',
              opId: '10@B',
              start: { opId: '1@A' },
              end: { opId: '6@B' },
              markType: 'italic',
              backgroundColor: '#E3F2F7',
              borderColor: '#00C2FF',
            },
          ]}
        />
      }
    </div>
  );
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.