---
title: "some movement ๐ copy"
order: 1
author:
- name: "Declan Naughton ๐งฎ๐จโ๐ป๐ง"
url: "https://calcwithdec.dev/about.html"
description: "some visuals for 'main' model"
format:
html:
resources:
- '../../models/main/*.js'
- '../../models/main/*.js.map'
- './models/**'
---
# Some visuals
```{ojs}
import {Scrubber} from "@mbostock/scrubber"
viewof frame_in = Scrubber(_.range(0,90), {delay: 60})
keys_stream_in = [{ key: "ArrowRight", frame: 20 },
{ key: "ArrowUp", frame: 30 },
{ key: "ArrowLeft", frame: 45 },{ key: "ArrowLeft", frame: 48 },
{ key: "ArrowUp", frame: 60 },
{ key: "ArrowUp", frame: 64 }]
main.keys({frame_in,keys_stream_in})
viewof g_in = Inputs.range([-1,2], {value:1, step:0.01, label:'g_in'})
viewof s_in = Inputs.range([-6,6], {value:4, step:0.01, label:'s_in'})
viewof jump_limit_in = Inputs.range([0,3], {value:2, step:1, label:'jump_limit_in'})
```
gameplay (for fixed key stream) (workings are below)
```{ojs}
embed(
calcuvizspec({
models: [main],
input_cursors: [{frame_in, keys_stream_in, g_in, s_in, jump_limit_in}],
mark: {type:'text',align:'left'},
encodings: {
x: {name: 'player_x', grid:false, type:'quantitative', scale: {domain:[-30,50]}},
y: {name: 'player_y', grid:false, type:'quantitative', scale: {domain:[-5,50]}},
text: {name: 'keys_annotation', type: 'nominal'}, // keys_annotation includes the emoji, will fix
},
height:100,
}))
md`double jump scenarios`
embed(
calcuvizspec({
models: [main],
input_cursors: [{frame_in, keys_stream_in, g_in, s_in, jump_limit_in:2}],
mark: {type:'text',align:'left'},
encodings: {
x: {name: 'player_x', grid:false, type:'quantitative', scale: {domain:[-30,50]}},
y: {name: 'player_y', grid:false, type:'quantitative', scale: {domain:[-5,50]}},
text: {name: 'keys_annotation', type: 'nominal'},
opacity: {name: 'jump_limit_in', domain: [1,2]}, // or row
},
width: 350,
height:200
}))
```
"instant" replay trail
```{ojs}
embed(
calcuvizspec({
models: [main],
input_cursors: [{frame_in, keys_stream_in, g_in, s_in, jump_limit_in:2}],
mark: {type:'text',align:'left'},
encodings: {
x: {name: 'player_x', grid:false, type:'quantitative', scale: {domain:[-30,50]}},
y: {name: 'player_y', grid:false, type:'quantitative', scale: {domain:[-5,50]}},
detail: {name:'frame_in',domain:_.range(0,91,1)},
row: {name: 'jump_limit_in', domain: [1,2]},
},
width: 350,
height:200,
spec_post_process: spec => {spec.encoding.text = {value:'๐พ'}; return spec}
}))
```
workings ("gameplay" visual):
```{ojs}
viewof grid = embed(
calcuvizspec({
models: [main],
input_cursors: [{keys_stream_in, g_in, s_in, jump_limit_in}],
mark: 'text',
encodings: {
x: {name: 'frame_in', type:'nominal', domain: [..._.range(19,50,1)]},
text: {name: 'value', type: 'quantitative'},
y: {name: 'formula', type:'nominal', domain: formulae_not_inputs},
color: {name: 'formula', type:'nominal', domain: formulae_not_inputs, legend:false},
},
//width: 250
height:200
}))
```
<!-- code viewer -->
<details open><summary>*calculang formulae* ๐ช behind the workings</summary>
```{ojs}
//| echo: false
// todo here: pull introspection-no-memo, use entrypoint.cul.js, publish as a helper? -> test in calcuvizspec
// ALSO will formula UI sit inside/outside? Inside is better, how to maintain interactivity?
code_viewer = async (entrypoint, formula) => {
const cul_fetch = await fetch(`${entrypoint_no_cul_js}${1 ? '-nomemo_esm' : '_esm'}/cul_scope_${0}.${code_opt_fv.indexOf('source') != -1 ? 'cul.js' : 'mjs'}`)
const cul = await cul_fetch.text()
return md`
~~~js
${
formulae_objs.filter(f => f.name == formula_select).map(f => cul.split('\n').filter((d,i) => i >= f.loc.start.line-1 && i < f.loc.end.line).join('\n').slice(13)).join('\n\n')
}
~~~
`
}
code_viewer('',formula_select)
viewof formula_select = Inputs.select(/*Object.entries(introspection_nomemo.cul_functions).filter(([a,b]) => b.reason == 'definition' && b.cul_source_scope_id==0).map(([a,b]) => b.name)*/formulae_not_inputs, {label: "formula"})
```
</details>
<!-- end code viewer -->
<details><summary>appendix</summary>
```{ojs}
//| echo: false
// code viewer
formulae_objs = Object.values(introspection_nomemo.cul_functions).filter(d => d.reason == 'definition' && inputs.indexOf(d.name+'_in') == -1)
viewof code_opt_fv = Inputs.select(["๐ calculang source ๐ฌ", "โจ calculang output โจ for ๐ฅ๏ธ"], {label: "๐ง via ๐ฒs", value: "๐ calculang source ๐ฌ"})
// force nomemo here
//cs = (code_opt_fv.indexOf("source") != -1 ? calcuin_fv : calcuout).split('\n')
```
```{ojs}
//| echo: false
grid.addEventListener('mousemove', (event, item) => {
viewof formula_select.value = item.datum.formula;
viewof formula_select.dispatchEvent(new CustomEvent("input"))
})
```
</details>
# Appendix
```{ojs}
import { calcuvizspec } from "@declann/little-calcu-helpers"
embed = require('vega-embed');
entrypoint = './models/vek.cul.js'//Inputs.select(['models/main/main.cul.js'], {label:'entrypoint'})
entrypoint_no_cul_js = entrypoint.slice(0,-7)
main = require(`${entrypoint_no_cul_js}.js`);
introspection_fetch = await fetch(`${entrypoint_no_cul_js}.introspection.json`)
introspection = introspection_fetch.json({typed:true})
introspection_nomemo_fetch = await fetch(`${entrypoint_no_cul_js}-nomemo.introspection.json`)
introspection_nomemo = introspection_nomemo_fetch.json({typed:true})
inputs = Object.values(introspection.cul_functions).filter(d => d.reason == 'input definition').map(d => d.name).sort()
formulae = Object.values(introspection.cul_functions).filter(d => d.reason == 'definition').map(d => d.name)
// formulae excluding pure inputs
formulae_not_inputs = Object.values(introspection.cul_functions).filter(d => d.reason == 'definition' && inputs.indexOf(d.name+'_in') == -1).map(d => d.name)
```