/dev/log
development log of various projects.
follow the project name to read their entries.
-
2024/07/19: viole.in
-
rework notes
-
now entry with the same name together, separate by date
-
-
remove
/sketch
-
-
2024/07/19: mtg
-
on hold until svelte 5 or i have free time again
-
-
2024/07/10: viole.in
-
create friction log for feedback
-
why & how: https://blog.sbensu.com/posts/friction-logs/
-
i still remember how to build lol.
-
-
2024/06/29: mtg
-
side quest: letās see how fast i can do it on react
-
stack: react, tldraw
-
-
2024/05/29: mtg
-
drag n drop second round
-
the last implementation of html introduce a lot of headache. and not currently support dragging around inside the box which lead to clashing interaction between
drag
anddrag to drop
-
so iām gonna try to improve the implementation by porting
dnd-kit
back intosvelte
-
dnd-kit
have enough good stuff for me to follow, very performant due to using css transform such astranslate3d()
-
-
rough idea for dropzone
-
measures the
rect bounding
ofdraggable
-
measures the
rect bounding
ofdroppable
(s) -
check intersect/collision
-
require both
draggable
&droppable
sitting inside the same coordinate aka context?
-
-
if yes =>
dropable
=> run callback-
when yes?
onPointerUp
-
-
should save the after translate position for keeping after dropping
-
-
stuff about drag
-
every draggable node create an event which attached into window
-
node have indentifier or something to know which node is currently being dragged
-
mostly for running callback which update something for userland
-
otherwise
event.target
should be enough
-
-
-
-
notes:: clientX/Y, offsetX/Y
-
-
clientX,Y
: is pointer event which absolute position compare to theviewport
-
offsetX,Y
: is position of the mouse comparetarget node
-
clientX,Y
-initial offsetX,Y
: should yield the should be position of target node after translate -
deltaX,Y
to translate isclientX,Y
-initial offsetX,Y
-initial bounding X,Y
-
-
-
2024/05/23: mtg
-
rough roadmap for mtg
-
goal
-
get everybody i know to play mtg, eventually have enough people to draft a cube
-
recreation programming
-
try to learn and reimplement most interesting stuff while building this
-
-
-
single player experience. streamable. watch able in discord call. spelltable capable of recognizing all the art card
-
drag and drop between zone
-
card interaction
-
tap, untap
-
draw, scry, discard
-
context menu
-
spawn stuff
-
viewable
-
-
view zone
-
selection, mass update something
-
baseline is the goldfish testing of moxfield
-
-
multiplayer eventually (stretch goal)
-
share playfield, zoomable, able to interact card between player. similar to tabletop simulator
-
-
non goal
-
card scripting, too much work. the point is get people to talk to each other, why take the fun out of it.
-
-
-
-
2024/05/22: mtg
-
how to implement drag n drop in svelte?
-
dragging a round inside is relatively simple (itās not)
-
bound with parent and the mouse event somehow updating the coord of card relatively to the field
-
so the card should have the normal flow and only use
transform
to moving around?-
thus achieve the effect of orderly into chaos later aka. first it drop into neatly order thing, when user start dragging, everything went apeshit.
-
-
ok not so easy
-
-
drag and then dropping into another container is a different beast.
-
-
-
2024/01/06: rye
-
is zoomable now
-
useGestureEvent
andnormalizeWheel
were the missing pieces -
learned how to make a patch with
pnpm
-
-
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
slug
with 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
withproperties
and generate static path withregex 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
inlogseq
-
[ :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 whichli
have nestedul
, and then add.parent
to that.-
:has
made stylingparent element
so much easier. why firefox, why
-
-
test on firefox to check if things work correctly or not
-
another level?
-
nobody should ever use h1 here, but i make it
long
anyways to see if it wraps correctly -
siblings?
-
ok
-
-
-
-
-
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
andsimple 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
v2
with minimal to unstyle css, and had great fun with it. entire css hopefully is just under 100 lines of css. -
make an outline style for
logseq
content-
css recently introduce
& nesting selector
so scoping style forlogseq
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 theheader
and then absolute positioning thebullet
-
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
-
problem with scrolling with mouse in
tldraw
-
what 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 beforeemit
info to user state chart to handle -
holding
ctrl/alt
will zoom and immediately return withoutemit
ing anything to user state chart to handle
-
-
-
-
what we tried:
-
handling event using
onWheel
provided bytldraw
api:-
not working as intended due to
editor
interceptwheel event
andpan
before emitinginfo
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
codebase-
tldraw
is a whiteboard app built upon html and svg not canvas-
scale
andtranslate
both usecss transform
: nocanvas
math here -
every
shapes
are represent with acomponent
and anindicator
usingsvg
to draw the outline of its shape-
component
of the shape can be any kind of markup(jsx) e.gdiv
,button
, even aniframe
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 bytldraw
team to build -
@tldraw/state
: built upon@tldraw/sigina
-
@tldraw/editor
: core engine whichtldraw
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
: whereshapes
/z-index:300
get rendered, and things that follow shapes likeselection background
-
overlay
/z-index:400
: foremost layer that have components that you can interact withshapes
behind like-
Handles
: to manipulate shapes, scale, squish, expand, rotate -
Selection Foreground
: to highlight selected shaped, createhandles
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 astate chart
where onetool state
can transition to another throughaction/event
-
-
notable, necessary
tools
:Selection
,Zoom
,Hand
,Line
,Stamp
-
-
shape
: things that exist oncanvas
-
internal itās just a
JSON record
carry some information of how to render itsshape
onto thecanvas
-
tldraw
have some defaultshapes
but we can create our own usingShapeUtils
-
notable, regularly uses
property
ofShapeUtils
:-
props
-
coordinates, rotation of
shape
oncanvas
:x
,y
,rotation
-
flags
:hideRotateHandles
,hideResizeHandles
-
-
-
-
-
2023/11/12: viole.in
-
figuring out how to sort by left node #logseq
-
here a little peak into how
logseq
store the block insidedatascript
nicely encoded intypescript
-
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
untilleft_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 theleft_node
is also theparent_node
, which mean we at the very first sibling of this tree
-
-
after we establish the relationship between
parent
andleft_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 supportvalue
property so when i tried to passedvalue
into it some thing broke. move the value insidetextarea
and it works fine now
-
-
-
2023/11/12: viole.in
-
init devlog
-