Eventcatcher Example: Simple Canvas

You’re right - I meant click in 5.3.8. I still haven’t spent time with the 5.4.0 yet, but I tried to simplify and replace the click with mouseup and it’s not working at the moment - I have to take a break on this for today.

This is as far as I got (NOT WORKING) just posting in case you see something obvious
stobot_canvas_macros.json (4.7 KB)

Ah.

That gives me an idea - I was thinking about arrows as well. I need to implement a way to have many version of the same tiddler, but with separate position, size, and rotation values stored in the canvas tiddler. Should be too hard, will think about the most elegant way to implement it. Right now, you’d have to have a unique tiddler for each arrow you’d want, I think I can overcome that.

1 Like

Hmm. I think detecting if you drag an item above the top or left would be relatively easy since I can just use the coordinates and look for x or y values below zero. I’m not sure how I’d get the right side since probably most of the time I’d want the canvas size to be 100% width, I don’t know if there’s a non-javascript way to figure that out in a value I can compare cursor position and width to. If anyone knows about that, let me know!

I don’t have the opportunity to test but my instinct suggests blank values from the state tiddler might be the issue, try this:

\procedure note-mouseup()
<%if [<tiddler>get[moved]!is[blank]else[no]!match[yes]] %>
  <$action-log/>
  <$action-navigate $to=<<currentTiddler>>/>
  <%if [<modifier>match[ctrl]] %>
    <$action-sendmessage $message="tm-edit-tiddler" $param=<<currentTiddler>>/>
  <%endif%>
<%endif%>
<$action-setfield 
  $tiddler=<<tiddler>> 
  action=""
  moved=""
/>
\end

Note that I threw in an action-log widget, so if this does not resolve it, check the variables logged.

1 Like

This is becoming a bit more complex, but implemented some small tweaks, bug fixes, and two big features - specifically around arrows like @Justin_H asked about. Still based on in 5.3.8 for now, though I’ll explore the new widget over the weekend.

The two big features are:

  • Note-level css override: If you want to style individual notes differently (like floating arrows)
  • Cloning notes: Once you have a note how you like it, clone it and then re-style (like rotate etc.)

canvas-2025-11-21.json (24.4 KB)

Demo: Building something like a process flow map out of tiddlers.

Note that the package now contains a tiddler named “arrow” that’s just a ascii arrow with font-size turned up. Works on my Windows machine, you can change to whatever you want though obviously

Step 1 (optional): Add a little overall styling and separate the 3 demo tiddlers. You might also notice that I added a default hover style which will come in handy later below.

<<canvas note-style:"box-shadow:0 0 6px;">>

Step1

Step 2: Add some individual styling (css below) to one specific note. I alt-click and an input box appears just below the canvas, I paste in the below and hit enter (or you can use the little emoji button on the far right).

display:flex;justify-content:center;align-items:center;box-shadow:0 0;background-color:hsl(0 0 0 / 0);

note-style

Step 3: Clone the arrow (as many times as you want) using ctrl-click. Note that ctrl-click used to be open in edit mode, I changed that to shift-click. This new note/clone is special, it has all of the same abilities as a regular note and it can be styled individually, but it lives in the canvas id tiddler (which is named blank by default). The content of the note continues to be linked to the original one though. To make it easy, I generate all clones in the top left.

note-clone

Step 4: Make and delete more clones! Did you notice that the hover color for the clones was green instead of red? That’s because clones can be deleted using shift-ctrl-click. Play around and clone & “unclone”.

note-unclone

This is getting pretty close to a usable plugin - I think I’m going to stabilize and clean it up and host it on TiddlyHost with better instructions. That’ll take me a bit though, adding features is always more fun!

7 Likes

I thought it’d be a fun exercise to do a slightly more complex demo using the same functionality, and highlighting that each canvas tiddler stores all of the parameters like position in a single tiddler. Because of that, you can save “states” and overwrite them to “reset” canvases.

For this demo I built a little Chess game. There’s a chessboard made with a table, and chess pieces made from unicode characters. This highlights the “cloning” as there’s a tiddler for one of each piece (on the left below), and then all the ones on the board are clones, so they can be deleted as the “game” progresses. Because of the “states”, there’s a tiddler called canvas/chess/ready that has everything setup, and then an exact copy is canvas/chess/play

The Chess tiddler just contains the macro pointed to canvas/chess/play. When you want to reset your game, clone canvas/chess/ready overtop of canvas/chess/play. Anyways, thought it was a fun way to illustrate a couple of the features. It does make me consider if I should add some pixel snapping capability to have things line up cleanly - optionally…

canvas-chess.json (24.9 KB)

canvas-chess

5 Likes

Thank you @stobot these are really fabulous demos, and deserve a wider audience.

2 Likes

@Christian_Byron the examples in this thread would merit a mention in the newsletter if that makes sense with the structure you have in mind.

Saq, With the work on the eventcatcher designers of wikis often want to use it to capture wikiwide / global solutions. The only legitimate way is to create a new Layout by creating a new page template and wrap that in event catcher. The the users can switch layouts, alternatively they need to modify the core page template.

  • I wonder if with 5.4.0 and the eventcatcher update there may be a way to add eventcatching in a permissible hack method so additional layouts or core modifications are not necessary.
  • Feel free to direct me to a better place to place this comment.

[Post Script] For example if the events to catch could be introduced like actions can be introduced through the actions parameter on buttons, or via a tag.

Hi @saqimtiaz - I’m trying some testing on this now.

Couple of questions though:

  • What am I testing for exactly? It looks like I just change “mouse” to “pointer” and add one property that says pointerCapture="dynamic". Just doing that seemed to work, but not sure what I should expect to see. I’m happy to try more things if you can give some insight - or point me to some notes on what the differences are in the new $eventcatcher widget - sorry if it’s somewhere obvious and I missed it.
  • I can’t seem to get the style.parameter things to work at all, and I can’t seem to find any documentation on how it’s supposed to work, can you point me to that? It would be much nicer looking code if I could get that to work.

Added optional “snapping” to the moves. The default here now is 10px for moves and resizes, and 15deg for rotations. This makes it much easier to line things up nicely. To adjust, add parameters to the macro call, these are the defaults:

<<canvas ..otherstuff.. min-px:10 min-deg:15>>

If your use case was actually Chess, doing 50px for min-px woudl actually be cleanest as the board is 50px per square.

canvas-minimums.json (41.7 KB)

Animation

4 Likes