2023/12/16: sketch
porting sketch using svelte 5 and conjuring
runes
sketch is an attempt to build myself a platform to experiment with creative art, or learn doing dumb stuff with canvas api and svelte (such as webgpu, webgl) etc⌠hopefully while building this will help me
learn how to create motion with code
learn more about math: matrix, trig, vector,âŚ
build an interactive component to supplement my blog like this
some inspirations/libraries that i want to mimic and learn from
2023/12/14: viole.in
added notes, created note
slugwith regex voodo and google-fu.
notes gonna be my random entry point for everything uncatergorized and adhoc, until it have a better place/
still getting things out from logseq with properties and generate static path with regex voodo
const slug = (s: string) => s.replace(/[^a-z\d ]+/ig, " ").replace(/\s{2,}/g, " ").trim().split(" ").join("-") this will make things into something-like-this for path purpose.
horrendous, i know. but it quick and painless and i have /dev/log here for future reference
also query specific block using uuid in logseq
[
:find (pull ?b ${model})
:in $ %
:where [?b :block/uuid #uuid "${id}"]
] i donât know why, but it works, so it works
2023/12/13: viole.in
firefox havenât supported
:has()selector yetâŚ
polyfill and introducing postcss-preset-env is too much complication for me to go that route. browser polyfill with js -> no. no. no.
back to class way. figuring out which li have nested ul, and then add .parent to that.
:has made styling parent element so much easier. why firefox, why
long anyways to see if it wraps correctlyok
2023/12/12: viole.in
resurrecting til and marks, this time simpler, no more âjavascriptâ. hurrah.
goodreads killed off their api, so i ended up tracking book myself
logseq and simple query are good for this kind of stuff, so why not
(and (property :book) (not (property :quote)) (property :status "read")) games and movies are next đ¤
2023/12/10: viole.in
iâve been working on
v2with minimal to unstyle css, and had great fun with it. entire css hopefully is just under 100 lines of css.
logseq contentcss recently introduce & nesting selector so scoping style for logseq is trivial now, and new css selector like :has, :is is a bliss to work with.
the gap after list marker default
doesnât give me any kind of alignment to create a border like logseq. so i have to jumping through hoop and align everything by myself.
the hardest thing about this is make the alignment just right for header and the bullet
i have a simple solution is using fixed line-height for all the header and then absolute positioning the bullet
it convenient and still look great. keep it simple, stupid.
.logseq {
& * > * {margin-bottom: 8px;}
& h1, h2, h3, h4, h5, h6 {
line-height: 32px; padding: 8px 0;
& + ul:has(> :is(h1,h2,h3,h4,h5, h6)) {margin-top: -16px;}
& + ul { margin-top: -8px;} }
& ul { width: 100%; margin: 0 8px;}
& * > ul {padding-left: 8px;}
& li {list-style: none; position: relative; --bullet-spacing:0px}
& li:has(> ul)::after {content:"";
position: absolute; top: calc(24px + var(--bullet-spacing)); left: -8px; transform: translateX(100%);
height: calc(100% - 24px - var(--bullet-spacing)); width: 2px;
background-color: var(--sel); };
& li::before{content: "â˘"; position: absolute; left: -8px;}
& li:has(h1,h2,h3,h4,h5,h6)::before{top:12px;}
& li:has(h1,h2,h3,h4,h5,h6)::after {--bullet-spacing:12px;}
} 2023/12/02: rye
tldrawwhat we need: scroll to zoom like cad
we want to mimic the user interaction of existing tools, such as Autodesk's Revit, AutoCAD for ease of transition to our product.
these tools scrolling the wheel means zooming instead of scrolling/panning.
relevant issues: #1344
what we knew:
currently in tldraw: the pinch, wheel and pointer get special treatment from tldraw event (i think)
these kind of event all related to zooming and such
in wheel:
wheel event will pan before emit info to user state chart to handle
holding ctrl/alt will zoom and immediately return without emiting anything to user state chart to handle
what we tried:
handling event using onWheel provided by tldraw api:
not working as intended due to editor intercept wheel event and pan before emiting info details to us

patching Editor.ts:
i tried inverting the logic of ctrl/alt by removing ! before
Of course not working due to inability to comprehend the magic inside tldraw lol đ
2023/11/17: rye
tldraw architecture: loosely manual to navigate @tldraw codebasetldraw is a whiteboard app built upon html and svg not canvas
scale and translate both use css transform: no canvas math here
every shapes are represent with a component and an indicator using svg to draw the outline of its shape
component of the shape can be any kind of markup(jsx) e.g div, button, even an iframe point to another site or another html
svg is there to serialize, to indicate component
readmore: https://canary.tldraw.dev/docs/shapes#The-shape-object
technical stack aka stuff tldraw use
react đ
@tldraw/signia: primitive signal home grown by tldraw team to build
@tldraw/state: built upon @tldraw/sigina
@tldraw/editor: core engine which tldraw team nicely split out for normie like me to poke around, and underlying of @tldraw/tldraw
this package purpose is for builder (like me and you) to build our own tldraw
@tldraw/tldraw: https://tldraw.com app, act as a demo showcasing capabilities of what @tldraw/editor and friends can do
what is components, default components?
a set of components layer on top each other and render together to provide some functionality for the canvas
ref: canvas.ts editor.css
canvas split into 3 layers: background, camera/overlay part of the canvas, canvas
background/z-index:100: have background component, grid line, and ui debug log, svg defs for other shapes to reference to (cursor shape too)
canvas/z-index:200: where shapes/z-index:300 get rendered, and things that follow shapes like selection background
overlay/z-index:400: foremost layer that have components that you can interact with shapes behind like
Handles: to manipulate shapes, scale, squish, expand, rotate
Selection Foreground: to highlight selected shaped, create handles to manipulate
notable, necessary components: Background, SelectionForeground, Handles, OnTheCanvas, PositionOnCanvas,
tools: set of tools to interact with canvas, to create new shape, move around, select stuff, etcâŚ
ref: canary docs
think about tools like a state chart where one tool state can transition to another through action/event

notable, necessary tools: Selection, Zoom, Hand, Line, Stamp
shape: things that exist on canvas
internal itâs just a JSON record carry some information of how to render its shape onto the canvas
tldraw have some default shapes but we can create our own using ShapeUtils
notable, regularly uses property of ShapeUtils:
props
coordinates, rotation of shape on canvas: x, y, rotation
flags: hideRotateHandles, hideResizeHandles
2023/11/12: viole.in
here a little peak into how logseq store the block inside datascript nicely encoded in typescript
interface Node {
id: number
left_node: Node //sibling next to the node
parent: Node //parent of this node
}
type Tree = Node[] this is a linked list (ikr đ¤Ż) reprensenting a tree
this kind of data structure help us figured out which of the node is the first children of other node with simple check node.left_node.id === node.parent.id
the other children will need to follow left_node until left_node.id == node.parent.id also
the length of search will neatly indicate the order of node in a tree (e.g first child = 1, second (left = first child ) = 2)
and we can find the order of node by follow the left_node until the left_node is also the parent_node, which mean we at the very first sibling of this tree
after we establish the relationship between parent and left_node we can easily traverse the tree with this beautiful recursive function
function walk(tree, parent, count){
if (tree.id === parent.id) return count;
return walk(tree.left_node, parent, count+1)
} the problem become sort by the distance from the node to the parent
first we need to recursively pulled the left node of this node
with (pull [{:block/left ...}])
then we traverse the tree until we found the left node id equal to the parent
the only requirement to make this problem easier is the nodes to be sorted with should have the same parent
even logseq itself have no clue how to sort when the query result have different parent
fixed some weird bugs about textarea and @preact/signals
textarea doesnât support value property so when i tried to passed value into it some thing broke. move the value inside textarea and it works fine now
2023/11/12: viole.in
init devlog