Here's an interesting bit of non-error in the middle:
Anyway, we're in here wondering how to make this nicer:
We've already created a <wrapper>|<spacer> dualism, which allows bits of html to overlap as they change size, the larger groups adjusting slowly.
We are missing the final adjustment once things stop changing, which I simulate by clicking on things.
We might have access to that time (after everything has settled down, per Con) at the outer awareness already, which repeats itself via a simple singleton+ttl+delay loop (at the end of itself):
if (ttl < 3) {
...
setTimeout(() => {
animalsizing_loop(uniquely,ttl+1,was),
And if I make this adjustment to go the inner awareness every time,
// model chaos
// change &&
await animalsizing(ge)
it basically fixes it, but never ends:
chart labels
They are all piled up!
let label_height = 20
function spread_ys_labels(ys_labels) {
// sort by y
ys_labels = ys_labels.sort((a,b) => a.y - b.y)
// needy may get ahead of lab.y when lab are too bunched
let squidge = (i,needy) => {
let lab = ys_labels[i]
if (!lab) return
if (needy && needy > lab.y) {
// we are told lab.y needs to be further
lab.further = needy - lab.y
lab.y = needy
}
// next one should be...
needy = lab.y + label_height
squidge(i+1,needy)
}
squidge(0,0)
// console.log("ys_labels: ",map(lab => sex({},lab,'y,further'),ys_labels))
return ys_labels
}
This most basic bulldozing algorithm took a few tries.
Perhaps why good_width follows wrapperx so closely is because it is increasing.
You can see good_height fall towards wrappery before height is conservatively inched down.
Wi is width being tweened - we get an occasional intermediate value of it.
All looks okay? How about height not being put so low at the end... The way wob_height disappears it seems like our algorithm sort of fails.
Many things to look into there, eg:
// see if what we set it to before (sizehop) is close enough to our current guess (ge)
// this should avoid lots of slight adjustments around wobbling geo
let close_enough = 1
map((k) => {
let wob = getwobble([de[k],sizehop[k]])
if (isNaN(wob)) debugger
let far = wob > de[k]/4
if (far) close_enough = 0
}, ks)
But lets try and tidy our frenzy of browser activity:
Well, our chart comes out at 4fps:
// about 5% of the time?
if (oldness < 0.25) return verbose && console.log("freshness")
If that is decreased to 0.05 we never hit the ttl on animalsizing_loop:
But it does get around to closing the gaps at the end. The end being when wob is negligible and we settle on exactly the geometry with no padding.
I try to get there, wondering why it loops like so:
// model chaos
// change &&
await animalsizing(ge)
So I look at the compiled javascript in devtools, and spot some spurious reactivity:
Which I work around:
if (spaciness != 'absolute') {
spaciness = 'absolute'
}
// look_selected = 0
Also here:
Updating <Chart {spam} /> is an update
Up in Code.svelte, which contains the other organs:
And a unified:
Then in Con.svelte (somewhere inside Code.svelte):
... // send us over to Charting
// Send (contains getContext()) must be called inside component initialization
let Chart = geometricating && Send("Chart",C)
...
let geometricate = (ge) => {
...
spam.N.push(ge)
// attach charts to us, we eventually Charting
ahk(C.sc,'charts',"geo",spam)
Chart && Chart.update && Chart.update()
Yes, it must be done in two places...
Wanting to avoid complexity in Con.svelte, due to its wide use!
Con form a repeating container pattern that we can hang layout generalisations on.
There's a whole side of things called T, which is how the control end targets certain things amongst the wild end, eg to configure a little something somewhere. It's kind of a self-consciousness layer. If we are a thing that wants to chart, here we call that geometricating.
In Charting.svelte:
let g = Named("Chart")
That makes it findable to others, via the Names context.We define a data loader for Send to reach. It simply collects all the remotes (by name) and later insists those remotes have C.sc.charts.
g.charts indexing by C.t means we clobber C with the same name, which is probably correct.
g.charts ||= {}
g.input = (C) => {
g.charts[C.t] = C
g.update()
return g
}
Then reactivity into charts: lose the indexing, becoming a list for each. let charts = []
g.update = () => charts = havs(g.charts)
// they have a collection C%charts.$t = spam
let list_charts = (C) => havs(C.sc.charts)
havs gives all the values as an array, ~~ perl's values %$ahash (as a list).Then look through it:
{#each charts as n (n.t)}
<h2>{n.t} -></h2>
{#each list_charts(n) as spam (spam.t)}
<h3>{spam.t} -></h3>
<Chart {spam} />
{/each}
{/each}
spam is not Cish, but should be. Back in Con.svelte:
let spam = {C,t:'geo',began:now(),vers:0,N:[]}
And here's the charting, struggling with the frequency of updates:
// sweep together (delay and singularise) calls to g.update() let updating = null
let updatingHz = 2
g.update = (to) => {
if (!updating || updating != to) {
if (!updating) {
// the first call comes back:
updating = {}
setTimeout(() => { g.update(updating) }, 1000/updatingHz)
}
}
else {
updating = null
charts = havs(g.charts)
updated++
}
}
Ah! Nice and calm.
springs
Apparently for values that change a lot, spring() will look better.
I also visually indicate wrapper|spacer size, as they seem to go hectic now:
So I snip off my padding logic:
// desired shape of spacer, given recent turmoil
let de =
// good_size(ge)
ex({},ge)
Updating
No comments:
Post a Comment