-
-
Notifications
You must be signed in to change notification settings - Fork 290
/
three_plot.jl
66 lines (59 loc) · 2.56 KB
/
three_plot.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# We use objectid to find objects on the js side
js_uuid(object) = string(objectid(object))
function all_plots_scenes(scene::Scene; scene_uuids=String[], plot_uuids=String[])
push!(scene_uuids, js_uuid(scene))
for plot in scene.plots
append!(plot_uuids, (js_uuid(p) for p in Makie.collect_atomic_plots(plot)))
end
for child in scene.children
all_plots_scenes(child, plot_uuids=plot_uuids, scene_uuids=scene_uuids)
end
return scene_uuids, plot_uuids
end
function JSServe.print_js_code(io::IO, plot::AbstractPlot, context::JSServe.JSSourceContext)
uuids = js_uuid.(Makie.collect_atomic_plots(plot))
# This is a bit more complicated then it has to be, since evaljs / on_document_load
# isn't guaranteed to run after plot initialization in an App... So, if we don't find any plots,
# we have to check again after inserting new plots
JSServe.print_js_code(io, js"""(new Promise(resolve => {
$(WGL).then(WGL=> {
const find = ()=> {
const plots = WGL.find_plots($(uuids))
if (plots.length > 0) {
resolve(plots)
} else {
WGL.on_next_insert(find)
}
};
find()
})
}))""", context)
end
function JSServe.print_js_code(io::IO, scene::Scene, context::JSServe.JSSourceContext)
JSServe.print_js_code(io, js"""$(WGL).then(WGL=> WGL.find_scene($(js_uuid(scene))))""", context)
end
function three_display(session::Session, scene::Scene; screen_config...)
config = Makie.merge_screen_config(ScreenConfig, screen_config)::ScreenConfig
scene_serialized = serialize_scene(scene)
window_open = scene.events.window_open
width, height = size(scene)
canvas_width = lift(x -> [round.(Int, widths(x))...], pixelarea(scene))
canvas = DOM.m("canvas"; tabindex="0", style="display: block")
wrapper = DOM.div(canvas; style="width: 100%; height: 100%")
comm = Observable(Dict{String,Any}())
done_init = Observable(false)
# Keep texture atlas in parent session, so we don't need to send it over and over again
ta = JSServe.Retain(TEXTURE_ATLAS)
evaljs(session, js"""
$(WGL).then(WGL => {
WGL.create_scene($wrapper, $canvas, $canvas_width, $scene_serialized, $comm, $width, $height, $(ta), $(config.framerate), $(config.resize_to_body))
$(done_init).notify(true)
})
""")
on(session, done_init) do val
window_open[] = true
end
connect_scene_events!(scene, comm)
three = ThreeDisplay(session)
return three, wrapper, done_init
end