feat: Initial enabling of 3D
Turns on 3D viewer when needed; implements tetrahedron command. Still quite several commands remaining for first test construction (from Rostamian's incenter.html) to work.
This commit is contained in:
parent
c99b51dafa
commit
3245db6d07
28 changed files with 29178 additions and 36 deletions
|
@ -1,11 +1,12 @@
|
|||
{AppletDescription, AdapParams, params, flags, ConfigType} from ./adapptypes.ts
|
||||
{ AppletDescription, AdapParams, ConfigType,
|
||||
params, flags, contains3d } from ./adapptypes.ts
|
||||
|
||||
// (At least some of) Joyce's pages have inline scripts that remove their
|
||||
// own applet nodes, so we have to watch for them as they are added. Hence,
|
||||
// this script runs at document_start, and watches for applets being added,
|
||||
// setting up the joyceApplets structure as it goes
|
||||
|
||||
joyceApplets: AppletDescription[] := []
|
||||
joyceApplets: AppletDescription[] .= []
|
||||
obs := new MutationObserver (mutationList) =>
|
||||
for each change of mutationList
|
||||
for each newGenericNode of change.addedNodes
|
||||
|
@ -38,13 +39,32 @@ function addScriptTag(url: string, module = false)
|
|||
document.head.appendChild script
|
||||
|
||||
document.addEventListener "DOMContentLoaded", async =>
|
||||
finalJoyceApplet := document.querySelector "applet[code='Geometry']"
|
||||
if joyceApplets.length or finalJoyceApplet
|
||||
finalJoyceApplets := document.querySelectorAll "applet[code='Geometry']"
|
||||
if finalJoyceApplets.length
|
||||
joyceApplets = []
|
||||
for jApp of finalJoyceApplets
|
||||
jParent := jApp.parentNode as HTMLElement
|
||||
unless jParent then continue
|
||||
id .= jParent.getAttribute 'id'
|
||||
unless id
|
||||
id = 'joyceApplet' + joyceApplets.length
|
||||
jParent.setAttribute 'id', id
|
||||
joyceApplets.push {
|
||||
html: jApp.outerHTML,
|
||||
params(jApp.children),
|
||||
id,
|
||||
width: parseInt(jApp.getAttribute('width') ?? '200'),
|
||||
height: parseInt(jApp.getAttribute('height') ?? '200') }
|
||||
if joyceApplets.length
|
||||
config := await browser.storage.local.get(flags) as ConfigType
|
||||
adapParams: AdapParams := {
|
||||
codebase: browser.runtime.getURL('deps/GeoGebra/HTML5/5.0/webSimple'),
|
||||
config,
|
||||
joyceApplets }
|
||||
use3d .= false
|
||||
for each jApp of joyceApplets
|
||||
if contains3d jApp.params
|
||||
use3d = true
|
||||
break
|
||||
codebase .= browser.runtime.getURL 'deps/GeoGebra/HTML5/5.0/'
|
||||
codebase += use3d ? 'web3d' : 'webSimple'
|
||||
adapParams: AdapParams := {codebase, config, joyceApplets }
|
||||
// @ts-ignore
|
||||
window.wrappedJSObject.adapParams = cloneInto(adapParams, window)
|
||||
addScriptTag(browser.runtime.getURL 'deps/GeoGebra/deployggb.js').then =>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import ./deps/jquery.js
|
||||
import type {AppletObject} from ./deps/geotypes/api.ts
|
||||
import {AppletDescription, AdapParams, params} from ./adapptypes.ts
|
||||
import {AppletDescription, AdapParams, params, contains3d} from ./adapptypes.ts
|
||||
colorsea from ./deps/colorsea.js
|
||||
|
||||
joyceApplets: AppletDescription[] := []
|
||||
|
@ -46,13 +46,31 @@ function postApplets(jApplets: AppletDescription[], codebase = '')
|
|||
appletOnLoad: (api: AppletObject) =>
|
||||
elements: JoyceElements := {}
|
||||
backgroundRGB := [255, 255, 255] as RGB
|
||||
config3d := contains3d jApp.params
|
||||
if config3d
|
||||
worked := api.enable3D true
|
||||
api.setPerspective 'T'
|
||||
else
|
||||
api.setPerspective 'G'
|
||||
for name, value in jApp.params
|
||||
dispatchJcommand api, name, value, elements, backgroundRGB
|
||||
api.setCoordSystem -10, 10 + jApp.width, -10, 10 + jApp.height
|
||||
api.setAxesVisible false, false
|
||||
api.setGridVisible false
|
||||
dispatchJcommand
|
||||
api, name, value, elements, backgroundRGB, config3d
|
||||
if config3d
|
||||
depth .= jApp.width
|
||||
if jApp.height > depth then depth = jApp.height
|
||||
api.setCoordSystem
|
||||
-10, 10 + jApp.width,
|
||||
-10, 10 + jApp.height,
|
||||
-depth - 10, depth + 10,
|
||||
false
|
||||
api.setAxesVisible 3, false, false, false
|
||||
else
|
||||
api.setCoordSystem -10, 10 + jApp.width, -10, 10 + jApp.height
|
||||
api.setAxesVisible false, false
|
||||
api.setGridVisible false
|
||||
} as const
|
||||
geoApp := new GGBApplet params
|
||||
console.log 'About to inject', jApp.id, 'with', codebase
|
||||
if codebase then geoApp.setHTML5Codebase codebase
|
||||
geoApp.inject jApp.id
|
||||
|
||||
|
@ -110,7 +128,8 @@ function dispatchJcommand(
|
|||
name: string,
|
||||
value: string,
|
||||
elements: JoyceElements
|
||||
backgroundRGB: RGB): void
|
||||
backgroundRGB: RGB,
|
||||
is3d: boolean): void
|
||||
switch name
|
||||
'background'
|
||||
newback := joyce2rgb value, backgroundRGB
|
||||
|
@ -123,7 +142,8 @@ function dispatchJcommand(
|
|||
'title'
|
||||
if adapParams.config?.commands
|
||||
console.log 'Setting title to', value
|
||||
api.evalCommand `TitlePoint = Corner(1,1)
|
||||
corner := is3d ? 'Corner(-1,1)' : 'Corner(1,1)'
|
||||
api.evalCommand `TitlePoint = ${corner}
|
||||
Text("${value}", TitlePoint + (2,5))`
|
||||
/e\[\d+\]/
|
||||
num := parseInt(name.slice(2))
|
||||
|
@ -398,11 +418,11 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
|||
`${name} = Intersect(${destination}, Ray(${center}, ${aux}4))`
|
||||
auxiliaries.push ...[2..4].map (i) => `${aux}${i}`
|
||||
'extend'
|
||||
unless args.subpoints then return
|
||||
sp := args.subpoints
|
||||
unless sp then return
|
||||
direction .= `UnitVector(Vector(${sp[0]},${sp[1]}))`
|
||||
if args.line and (
|
||||
not args.point or args.point[0] !== args.subpoints[0])
|
||||
not args.point or args.point[0] !== sp[0])
|
||||
direction = `UnitVector(${args.line[0]})`
|
||||
displacement := `Distance(${sp[2]}, ${sp[3]})*${direction}`
|
||||
commands.push `${name} = Translate(${sp[1]}, ${displacement})`
|
||||
|
@ -410,7 +430,9 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
|||
unless args.subpoints then return
|
||||
commands.push `${name} = ${args.subpoints[0]}`
|
||||
/fixed|free/
|
||||
commands.push `${name} = (${args.scalar?.join ','})`
|
||||
coords := args.scalar
|
||||
unless coords then return
|
||||
commands.push `${name} = (${coords.join ','})`
|
||||
if method is 'fixed'
|
||||
callbacks.push (api: AppletObject) => api.setFixed name, true
|
||||
'foot'
|
||||
|
@ -600,4 +622,37 @@ classHandler: Record<JoyceClass, ClassHandler> :=
|
|||
|
||||
plane: (name, method, args) => freshCommander()
|
||||
sphere: (name, method, args) => freshCommander()
|
||||
polyhedron: (name, method, args) => freshCommander()
|
||||
polyhedron: (name, method, args, index) =>
|
||||
return := freshCommander()
|
||||
return.value.ends = ['', '']
|
||||
{commands, callbacks, parts, auxiliaries, ends} := return.value
|
||||
aux := name + 'aUx'
|
||||
switch method
|
||||
'tetrahedron'
|
||||
pt := args.subpoints
|
||||
unless pt and pt.length is 4 then return
|
||||
commands.push '' // hack, make sure there is a command
|
||||
parts[0].push ...pt
|
||||
ends[0] = aux + 1
|
||||
ends[1] = pt[3]
|
||||
callbacks.push (api: AppletObject, moreParts: DimParts) =>
|
||||
madeBase := api.evalCommandGetLabels
|
||||
`${ends[0]} = Polygon(${pt[0]},${pt[1]},${pt[2]})`
|
||||
if not madeBase return
|
||||
for each obj of madeBase.split ','
|
||||
if obj is ends[0] continue
|
||||
newObj := 'GeoAux' + index + obj
|
||||
api.renameObject obj, newObj
|
||||
moreParts[1].push newObj
|
||||
made := api.evalCommandGetLabels
|
||||
`${name} = Pyramid(${aux}1, ${pt[3]})`
|
||||
if not made return
|
||||
for each obj of made.split ','
|
||||
if obj is name continue
|
||||
newObj := 'GeoAux' + index + obj
|
||||
api.renameObject obj, newObj
|
||||
switch api.getObjectType newObj
|
||||
'segment'
|
||||
moreParts[1].push newObj
|
||||
'triangle'
|
||||
moreParts[2].push newObj
|
||||
|
|
|
@ -23,3 +23,9 @@ export function params(kids: HTMLCollection): Record<string, string>
|
|||
value := kid.getAttribute 'value'
|
||||
unless name and value then continue
|
||||
return.value[name] = value
|
||||
|
||||
prim3d := /polyhedron|sphere|plane|face/
|
||||
export function contains3d(params: Record<string, string>): boolean
|
||||
for value of Object.values(params)
|
||||
if prim3d.test(value) then return true
|
||||
return false
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue