This update introduces enhanced support for SummaryBox
, including proper representation of ResourceFunction
and related elements. GraphicsComplex
has been improved to support additional primitives like Tube
, Sphere
, and Line
, with optimized performance for Tube geometry and dynamic updates for both coordinates and radius.
New features include the ability to export entire notebook folders as compressed files for easy sharing, import functionality for reusing symbols and templates across notebooks, and the introduction of TabView for intuitive tab-based visualizations. Additionally, dialog tools such as ChoiceDialog
and MessageDialog
have been added for interactive user prompts.
const balloonContainer = document.getElementById("balloon-container"); function random(num) { return Math.floor(Math.random() * num); } function getRandomStyles() { var r = random(255); var g = random(255); var b = random(255); var mt = random(200); var ml = random(50); var dur = random(5) + 5; return ` background-color: rgba(${r},${g},${b},0.7); color: rgba(${r},${g},${b},0.7); box-shadow: inset -7px -3px 10px rgba(${r - 10},${g - 10},${b - 10},0.7); margin: ${mt}px 0 0 ${ml}px; animation: float ${dur}s ease-in infinite `; } function createBalloons(num) { for (var i = num; i > 0; i--) { var balloon = document.createElement("div"); balloon.className = "balloon"; balloon.style.cssText = getRandomStyles(); balloonContainer.append(balloon); } } function removeBalloons() { balloonContainer.style.opacity = 0; setTimeout(() => { balloonContainer.remove() }, 500) } createBalloons(10); setTimeout(removeBalloons, 15000); return '';
Improved support for SummaryBox and special symbols
Now ResourceFunction
has its representation, and many other from the function repository can render correctly
metric = ResourceFunction["MetricTensor"]
metric = ResourceFunction[(*VB[*) ResourceObject[<|"Name" -> "MetricTensor", "ShortName" -> "MetricTensor", "UUID" -> "c6c98873-a3bc-43e4-a1a4-ed6e5dbbaa32", "ResourceType" -> "Function", "Version" -> "1.0.0", "Description" -> "Represent a metric tensor (field) for a Riemannian or pseudo-Riemannian manifold", "RepositoryLocation" -> URL["https://www.wolframcloud.com/obj/resourcesystem/api/1.0"], "SymbolName" -> "FunctionRepository`$e8bf75f345d9428d8514b42f99452556`MetricTensor", "FunctionLocation" -> CloudObject["https://www.wolframcloud.com/obj/841aede1-5fed-4606-91bd-ebe5f6619e11"]|>, ResourceSystemBase -> Automatic] (*,*)(*"1:eJxNj09rwzAMxbN2659dBr0MeloP/QI59taxlBWyFpIs57qxPAy2BbLD1m8/OS60lx96T9KztTpjpcZZlvkl4x3/dkj2tCUS7gdk3Vsr6MK2eogzL4wdoQuFk62m0AuTGo+MTzRyKA7o4GaX2gc1iur17oVr8j6AbTX81pO4Jyxs3tLsM6OQOiDFdkqbMo5KGRQyGXPGd1V+QIcS6gWrdZ5/QSDdNeA8EssUFz9S9QbqWSxAyKMzl8FtqAf/FO8SxsM/DdFEIQ=="*)(*]VB*)][{"Schwarzschild", 1}, {t, r, a1, a2}]
(*VB[*)temporalStorage$126228(*,*)(*"1:eJxdUsuumlAANLZNmn7F7V35aCIoL5t0AYgKHAUOCMLNXfA4IIq8kcfXV7vsZjIzmcUkMz+9DIZfRqNR9eMJQhDXWWnGqNXH49HogOoy9g2UVln5MZmZ3Mds+jaZ/ZpNJ7N3/DeS+vpUJUo7sBoIq8aIYknArgRLsyJnkbVW7GLhqJ2G6xXPAbhJnhxoKbUBjKPIcQygbPYIFou7EczTxxYWj9KxCxUeQKXsS809tBk2xLiB3SFQ032UyThSsAKQpGdBkWKl7KRBCSnDxWEGT97sGCtfng/crs9IVhLS/BSZ6kBzThetKKxmzjbjzNd1Hs4LpIfzhgv3AsGbTuAl3N1XE9tc0hTi5UPRYMbaR/hlECzfNjPD6gjEdyuijgo+ui1STCRw/hhbjmBdgkXTROe9JOH7lr9UCCadRmLseU0zNKCKs0Ig6uGnuurrtbjk66zR1CiWTXHA+X61tY9QACV77zfMLrJg3mdHN3NxVtm33OK4DZKAWEHYnbHWRW5/0pBWmwpwuMGg5TIIwF3kc3UbeiIFESqxEHcJ0gxFmANbqxZDt/L8Qq9y68jzjUW08bAciEx8lnLowDjl9u1WedgWENxcDih2TdXMn/fXvp8mN5t+huPXNb4+ATYJ0r+/CHIDJU36f65RNui/zOtHOkqQX7tegqpvT7l1kwr9BQzswCU="*)(*]VB*)
Improved support for primitives Graphics3D
Tubes, Spheres inside GraphicsComplex
GraphicsComplex
expression is an efficient way of rendering many objects with shared coordinates, vertices, normals and colors. For a long time it was only possible for Polygon
to work with such structures. Now we added the support for Tube
, Sphere
, Line
decomposition = ResourceFunction["DiscreteHypersurfaceDecomposition"][ metric, {t, 0, 1}, {r, 0, 4}, {a1, -Pi, Pi}, 200, 1.5]; decomposition["CoordinatizedPolarGraphColored"] // GraphPlot3D
(*VB[*)(FrontEndRef["d935435c-c070-49da-b160-7822545d2d50"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKp1gam5oYmybrJhuYG+iaWKYk6iYZmhnomlsYGZmamKYYpZgaAAB4dhTc"*)(*]VB*)
Tube supports variable radius and dynamics!
The original implementation of Tube geometry from the standard library of THREE.js was quite limited. We reimplemented Tube
from scratch in Javascript manually generating each vertex, normal and then passing it to a dynamic buffer of GPU.
Now it works much faster and does support dynamic updates of both: coordinates and radius. We don't waste the resources of GPU and heavily reuse the created buffers
Tube[{{0,1,0}, {0,0,0}, {0,-1,0}}, {0.2,0.3,0.1}] // Graphics3D
(*VB[*)(Graphics3D[Tube[{{0, 1, 0}, {0, 0, 0}, {0, -1, 0}}, {0.2, 0.3, 0.1}]])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRAeF5BwL0osyMhMLjZ2SWOCqQgpTUpNY4bxfDKLS1B5mUCaIRNkBJiFTZIBn+R/IMAiWTRrJgictC8yBoPL9lCRnfYA05Irhw=="*)(*]VB*)
Here is a beautiful example of using tubes to draw scalar fields (taken from stackoverflow)
(*VB[*)(FrontEndRef["730749d0-16d4-41b0-874c-cf9fa7d38b91"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKmxsbmJtYphjoGpqlmOiaGCYZ6FqYmyTrJqdZpiWapxhbJFkaAgB1ZBVM"*)(*]VB*)
There are still some issues with calculating normals at the ends, but we will fix it later.
New export feature
Keep the filesystem within the notebook
It allows you to compress the whole notebook folder and embed it to a notebook. It uses simple gzip
and stores the binary data as Base64 string
Then you only need to share your .wln
file and on the first start it will self extract the files maintaining the original folder structure.
Experimental: Import WLN notebook
It might come handy, if you don't want to create a library, but still like to reuse some functions or templates from the other notebook.
We have registered the converter for that reason. What it does?
- Evaluate all initialization cells in the isolated context (can be any kind of cell)
- Evalaute the last input cell in the notebook and return the result (must be wolfram language cell)
Since it involves breaking the order of evaluation, Import
will return Promise
, that you would need to resolve. For example I have WLX templates defined in other notebook, that I would like to reuse here
p = Import[ FileNameJoin[{NotebookDirectory[], "attachments", "detect.wln"}], "WLN" ]; Then[p, (MyBigHeader = #)&];
Now we can safely use it
.slide <MyBigHeader>Title</MyBigHeader>
<dummy ><h2 style=" white-space: nowrap; display: inline-block; font-size: 400px;">Title</h2></dummy>
You can see the unique context of the given symbol
MyBigHeader
bellman311`Header
Or something even cooller! Let it be a piano view
p = Import[ FileNameJoin[{NotebookDirectory[], "attachments", "Piano.wln"}], "WLN" ]; Then[p, (pianoView = #)&];
Try to play
pianoView[]
(*VB[*)(FrontEndRef["6f07b81b-dac8-4872-af9f-6233ab175067"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKm6UZmCdZGCbppiQmW+iaWJgb6SamWabpmhkZGycmGZqbGpiZAwCIGRV5"*)(*]VB*)
TabView implemented!
We have added the support for TabView
TabView[{ Sin->Plot3D[Sin[x] Sin[y], {x,-2Pi,2Pi}, {y,-2Pi,2Pi}], Sinh->Plot3D[Sinh[x] Sinh[y], {x,-2Pi,2Pi}, {y,-2Pi,2Pi}] }]
(*VB[*)(Null)(*,*)(*"1:eJytUstuglAQta2Lpn9RVkpKwuOC0B0YxIBaC4oB4+ICF0W4XMQX/l8/rFLTdNM2bdPNyZzJOTOTk7kPiB1fNRqNbfMMfZJF8U3N7s4wgYGboKNGqvj6XTFItrsLqxV6lOxIWYuc2uUk+YfS3mfIua0LBKOnPDu9dSflHn3qb178q58P+PaclzNt0a42p9utXknynZ5HNornlMLFkgAEnmEFKWIAhzgmkGXAiBGAMSvKbCeIqEW7RT+cnTTFPSKzmkyGZOzgUeoZKvGXutM/pKJld5FuakdLLseW0B85grFzdHY/mGbDU5qO3KVuzaoNxjYODO1QGKskKFACDcuDUuL7M3NN8AZ6puX5uEc83EWZqmonvpraVL174Wp0+895fhlAiMJIllmekTpByABeURhFElkmBDwAEMRhEAv/FoAphbjgVp6hrQtcpLmJ9tDoZVDKNhDbJTGLrYf9ZYo3z5kpTX312O0Rbbb9XQBJ/cCvkzS/6g=="*)(*]VB*)
And it will work offline, since the widget prerenders all states and just swap between them using HTML and JS.
It has WLXForm
implemented, therefore it can work on slides too
TabWidget = TabView[{ Sin->Plot3D[Sin[x] Sin[y], {x,-2Pi,2Pi}, {y,-2Pi,2Pi}], Sinh->Plot3D[Sinh[x] Sinh[y], {x,-2Pi,2Pi}, {y,-2Pi,2Pi}] }];
.slide ## My Tab Widget <TabWidget/>
<dummy > ## My Tab Widget FrontEndExecutable[e065d062-f0a0-4f67-8c4c-0abbce0ad31c]</dummy>
ChoiceDialog and MessageDialog
We added the support for dialog-tools. For example to show the message
MessageDialog[Plot[x, {x,0,1}]]
If you want to prompt user to click yes or no, use
ChoiceDialog[Plot[x, {x,0,1}]]
Or choose from the options
ChoiceDialog["Click on a plot", { Plot[x^2, {x,0,1}] -> 1, Plot[x^3, {x,0,1}] -> 2 }]
There is also async version, which returns a Promise
Then[ChoiceDialogAsync["Click on a plot", { Plot[x^2, {x,0,1}] -> 1, Plot[x^3, {x,0,1}] -> 2 }], Function[result, Do[Beep[]; Pause[0.2], {result}] ]];
Ballon animation by Jemima (codepen)