Giter Site home page Giter Site logo

tixi's Introduction

Textik Travis CI status

Web based ASCII diagrams editor, written in ClojureScript.

Basically, the main goal of this project initially was to try out ClojureScript, React, and the approach of having one global state for the whole relatively complex app and having fully synchronous flow instead of reacting to changes via observers.

As a side effect, it appears to be nice and hopefully useful tool. :)

Features

  • You can draw rectangles and lines (items) on the canvas, and write text
  • You can write text inside the items
  • You can select items, move them around, resize
  • You can "lock" lines to rectangles, so if you move/resize rectangle, the line will be moved too
  • You can add arrows to the lines
  • There is undo and redo.
  • There is copy and paste (with regular Cmd+C/Ctrl+C and Cmd+V/Ctrl+V)
  • You can copy the final result to the clipboard, and paste it somewhere in email/docs/comments/etc.

Libraries and Frameworks

It is written in ClojureScript, using ReactJS as a view layer, Quiescent as a thin functional wrapper around React, CodeMirror as a text editor, and a bunch of other dependencies you can find in project.clj

Architecture

All starts from tixi.core, where we do initial assigning of auxiliary event listeners (like, keypress events or resize events), create a core.async channel listener, where forward all the messages from the channel to tixi.dispatcher. And then - it does initial rendering of the view via tixi.view/render, passing our global state into it, which is just one large atom value.

In tixi.view, we assign different event handlers via React's event system, and when these events happen, we create a appropriate payload and send it to core.async channel, which then will be dispatched to tixi.dispatcher.

tixi.dispatcher tries to figure out what's really going on (e.g., if this is just mouse move or mouse drag), and calls an appropriate function in tixi.controller. After that, tixi.controller depending on the received payload calls various tixi.mutators, which change the global state (our atom), and then tixi.controller rerenders the app via tixi.view/render again, passing the new value of the atom to it (from tixi.data)

Like this:

    +----------------+      +-------------------+      +-------------------+ 
    |                |      |                   |      |                   | 
    |   tixi.core    +----->+     tixi.view     +----->+  tixi.dispatcher  | 
    |                |      |                   |      |                   | 
    +----------------+      +---------+---------+      +---------+---------+ 
                                      ^                          |           
                                      |                          v           
                                      |                +---------+---------+ 
                                      +----------------+                   | 
                                                       |  tixi.controller  | 
                                      +--------------->+                   | 
                                      |                +---------+---------+ 
                                      |                          |           
                                      |                          v           
                            +---------+---------+      +---------+---------+ 
                            |                   |      |                   | 
                            |     tixi.data     +<-----+   tixi.mutators   | 
                            |                   |      |                   | 
                            +-------------------+      +-------------------+ 
    

And that's it. Very simple, no observers at all, very clear flow.

Pros:

  • Simple architecture - less bugs, easier to track them, we can easily restore the whole state of the app just by assigning one value to tixi.data/data.
  • Easy to add new features - you almost always just add new tixi.mutators, which do something new with the data.
  • Clear separate of responsibilities of the namespaces
  • It's easy to test business logic
  • There is basically only one place where the data is being changed - in tixi.mutators. All other functions are pure.
  • Purely React thing, but so cool - React tracks and cleans up all the event handlers you create there. It is a huge deal, from my experience there is always a lot of hard-tracking errors and memory leaks when you somehow forget to remove event handlers.

Cons:

  • It's a bit harder to make REALLY reusable widgets - they should know something about the global data structure to keep their data there. Not a big deal for this app though.

Data and rendering

The application data is kind of split to 3 parts - canvas state (with undo/redo stack), cache and all other stuff. The canvas state contains only the data, which describe the data on the canvas in the shortest way.

For example, if we have a line and a rectangle on the canvas, we will describe them as:

{:completed {0 {:input R[1 1][5 5], :type :rect, :z 0}
             1 {:input R[10 10][20 20], :type :line, :z 0}}}

Which means the rectangle will be with the coordinates - left-top corner is (1,1), and right-bottom corner is (5,5), and the line will be with coordinates (10, 10) and (20, 20).

We use that information to build :cache - a set of points and text, which we are going to show on the screen. The code for that is in tixi.items and resources/tixi/js/drawer.js. I had to write generating points and ASCII text in JavaScript, because it shows significantly better performance, and this is the only part of the app where this performance is crucial for smooth UX.

After that, we end up with the list of points, which we could use to track "locks", "hits" (to track when mouse is over some character), and also with the ASCII text we are going to render on the screen.

Undo / Redo stack

Undo/Redo stack is a tree. So, it actually could support "Undo Tree", like in Vim or Emacs, when you don't lose your history even if you accidentally Undoed something, and then added a new change.

So far, it is not implemented in UI though, in UI it is "flat" for now, so I always select the rightmost branch of the tree when do "Redo".

Running on your machine

The most convenient way of doing that is just to run:

$ lein figwheel dev

It will compile a project, and start the figwheel server, which will reload the code in browser every single time you change any cljs or CSS file

Now, open http://localhost:3449/index.html in your browser, and you should be able to see it working.

There is also brepl running on 9000 port in dev build, so you could connect to it from REPL.

Contributing

If you want to help to the project, and fix some bug or add some feature - feel free to create a pull request, that's the whole point of the open source software, right? :)

To run tests use lein cljsbuild test unit command.

If you found a bug, and want to create a ticket - please do that in Github Issues.

If you just want to help and add some code, but have no idea what to work on, there is TODO, you can get something from there.

Right now the UI of the app looks awful, and some designer's help would be very appreciated. If you want to help with the design, that would be very appreciated.

tixi's People

Contributors

astashov avatar celsoagra avatar rodrigosetti avatar sudodoki avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tixi's Issues

[Feature] - Line Resize

Can Line Resizing be like Box resizing, i.e. display a 'Bounding Box', and also have resize control handles on the bounding box, so making it easier/preciser to resize in a particular dimension(s).

Polyline tool

Currently it is possible to draw «Line», and «Rectangle-Line». A nice addition would be adding the possibility to do «Polyline».

For instance if I want to draw something like this arrow:

   +--------+
   |        |
   |        |
+-----+  +-----+
|  |  |  |  |  |
|  +  |  |  v  |
|     |  |     |
+-----+  +-----+

I would either need to use three lines, or one line and one rectangular line. It would be nice to draw arbitrary-length line by starting to draw a line, and then clicking to add intermediary points, until Enter is pressed for instance.

It would be like:

  2          3
   +--------+
   |        |
   |        |
+-----+  +-----+
|  |  |  |  |  |
| 1+  |  |  v4 |
|     |  |     |
+-----+  +-----+
  1. Click point 1
  2. Click point 2 (Or these two first steps may be replaced by dragging from point 1 to point 2)
  3. Click point 3
  4. Click point 4
  5. Press Enter

Feel free to close this issue if you don't like the idea, I just opened this to suggest some ideas for future enhancements if you look for such!

Allow to specify arrows after a line has been drawn

It is currently possible to change the ending arrows of a line by being in «Select» mode and pressing the associated buttons. This doesn't work in other modes though.

Usually I start by drawing a line where I want it, then I'm thinking about what ending I wants for this line. This requires quite a lot of steps currently:

  1. Select Line tool
  2. Drag and Drop a new line
  3. Go to Select mode
  4. Select the line
  5. Change the ending
  6. Go back to line tool for the next line

It would be easier from an UX perspective to allow something like this:

  1. Select the Line tool
  2. Drag and Drop the line
  3. Press >, < or the associated buttons to change the endings of the line I just draw
  4. Drag and Drop a new line

This change would also require to add > or < key bindings.


Feel free to close this issue if you don't like the idea, I just opened this to suggest some ideas for future enhancements if you look for such!

Cannot import diagram

One can export by Ctrl + C,
but there is no possibility to import by Ctrv + V.

So there is no possibility to import any previously exported diagram.
One has to use asciiflow.com instead for this reason,
despite textik.com would be more comfortable for many cases.

Canvas Size Change is not saved

case1:

  1. change the canvas size,
  2. draw a line
  3. ctrl-z : I saw the canvas size changed back to default

case2:

  1. change the canvas size
  2. refresh the page
  3. I saw the canvas size changed back to default

"Show Result" doesn't work for me

I'm drawing a diagram and click the "Show Result" Icon.
At best I get the last objet I created but not the whole diagram.

I'm using windows and chrome 43.0
textik

Can't copy and paste the result out of the browser

Tested on:

  • Firefox 72.0.2 on Linux
  • Chromium Version 79.0.3945.130 (openSUSE Build) (64-bit)

Paste not working and no other way to export means the tool can't be used.
A simple Save-as or Export functionality would be great.

Add test command

Hi!
Can you please add command to run test to Contributing section of the readme?
I've seen TravisCI running lein cljsbuild test unit - is it the one? Are there any other build steps to do before running tests?

Use «Delete» key to delete elements

I noticed that Backspace can be used to delete the selected elements, but at first I tried to use Delete as it was the most obvious shortcut in my mind for removing elements.

Making Delete to behave as Backspace would be an (hopefully) easy way to improve the user experience.


Feel free to close this issue if you don't like the idea, I just opened this to suggest some ideas for future enhancements if you look for such!

Z-Indexes - overlap does work

Current behavior

               +--------------+  
               |              |  
               |              |  
+-------------------+         |  
|              |  +-------------+
|              +--|-|---------+ |
|                 | |           |
|                 | |           |
|                 +-------------+
|                   |            
+-------------------+            

Expected state:

               +--------------+  
               |              |  
               |              |  
+-------------------+         |  
|                 +-------------+
|                 |             |
|                 |             |
|                 |             |
|                 +-------------+
|                   |            
+-------------------+            

[Feature] - ReSize; Objects

Can it be implemented that when resizing objects, it can be done via Numeric Input to specify the Width & Height, or Scale (both Width & Height).

Also specify it in Characters or Percentages.

Also choose which Control Point / Anchor Point to make the Resizing from, e.g. say for Rectangle it could be any corner or any side and also the center.

[Feature] - Line Angles

Can it be made so that when creating lines:

The 'angle' of the line is shown somewhere on the screen.
Lines can be drawn with a user pre-specified angle setting. E.g. 45 Degrees.
When Line is being drawn, it can be made to Snap to an Angle, e.g. 45, 90,, etc degreess. By both toggling a Interface option AND/OR holding down the SHIFT key.
When a Line is selected, its Angle can be modified using a values typed into the GUI, rather than visually with the mouse.

Import, Ctrl+V or something like that

Hi there,
I am using textik.com for a while for drawing workflows and stuff
So I use it, export to a text file, and be done with it
But I found no way of editing those text files in tixi
My impression was that I would be able to just ctrl+v my files into it and start working, but that din't work
Is there a way to do this? Thanks.

"Show Result" to "Show/Copy Result"

Please make it more obvious how you can get to the final picture.

I think all which is needed is to update the hoover text which you see if you have the mouse over the eye-icon:

"Show Result" to "Show/Copy Result"

It took me some time to find this solution.

Thank you very much for this service!

How to save and reload progress?

I love this, am considering using for map on bbs on my FPS, but I need to know how to load and save so when I update my map I can edit it, where are those options? I dont see a save!.. thanks.

can't change name of projects

I did three projects and they are all named "My Project 1"
editing project name doesn't seem to have any effect.

anyway, thanks for this very nice work !

my projects ??

is it me or is "my projects" not working ?
I logged in with Google Acccount
and just get this
image

[Feature] - Pre-Defined Shapes; Flow Chart

Can you have option to draw pre-defined Shapes, like used in flow-charts and other shapes also.

E.g. Click an icon to select a shape, say Rectangle, which then prompts you to the Text for inside the rectangle, also allowing the adjustment of the options; size / dimentions / scale, border thichkness, Auto Resize To Text, while confirming to create the shape, and then allowing it to be put down onto a position on the canvas.

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.