From 9053367a474322fc2e03129ca12494eeb6f41d65 Mon Sep 17 00:00:00 2001 From: Abel de Bruijn Date: Tue, 28 Nov 2023 23:19:22 +0100 Subject: [PATCH 01/29] added sliders tutorial --- .../utils/sliders/CanvasWithSliders.svelte | 23 ++++ src/lib/stories/utils/sliders/sliders.mdx | 103 ++++++++++++++++++ .../stories/utils/sliders/sliders.stories.ts | 41 +++++++ src/lib/utils/Slider.ts | 2 +- 4 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 src/lib/stories/utils/sliders/CanvasWithSliders.svelte create mode 100644 src/lib/stories/utils/sliders/sliders.mdx create mode 100644 src/lib/stories/utils/sliders/sliders.stories.ts diff --git a/src/lib/stories/utils/sliders/CanvasWithSliders.svelte b/src/lib/stories/utils/sliders/CanvasWithSliders.svelte new file mode 100644 index 00000000..b1eec4bf --- /dev/null +++ b/src/lib/stories/utils/sliders/CanvasWithSliders.svelte @@ -0,0 +1,23 @@ + + + + {#if sliders} + {#if sliders?.x} + + {/if} + {#if sliders?.y} + + {/if} + {#if sliders?.z} + + {/if} + {/if} + diff --git a/src/lib/stories/utils/sliders/sliders.mdx b/src/lib/stories/utils/sliders/sliders.mdx new file mode 100644 index 00000000..fa763a56 --- /dev/null +++ b/src/lib/stories/utils/sliders/sliders.mdx @@ -0,0 +1,103 @@ +import { Canvas, Meta, Source } from '@storybook/blocks'; + +import * as SlidersStory from './sliders.stories'; + + + +# Sliders + +Sliders are crucial for UIs as they enable developers to add interactivity +to their applets. An applet can have multiple sliders, but the maximum +limit is 3. In this section, you'll find a range of sliders to choose from. + +An example of such a slider is shown below: + + + import { Slider, Sliders } from '$lib/utils/Slider'; + import Canvas from '$lib/d3-components/Canvas.svelte'; + + const sliders = new Sliders().add(new Slider(0.5, -2, 2, 0.5, PrimeColor.green)); + + + + + +`} /> + +The result of the above code is shown below: + + + +The end-user can drag the slider or choose to let it auto-play. In auto-play mode, +the slider moves back and forth in discrete steps, demonstrating the range of movement +for the interactive element. The auto-play mode can be stopped by either clicking the +pause button, or interacting manually with the range slider. + +The reset button to the bottom right will reset the positions of all sliders +and resets the values of \{sliders.x\}, \{sliders.y\} and \{sliders.z\}. + +## Multiple Sliders + +Multiple sliders can be added to the canvas by using by chaining the `add` +method of the `Sliders` class. The `add` method takes a `Slider` object +as an argument. The `Slider` object takes the following arguments: + +- `defaultValue`: (Required) The default value of the slider. +- `from`: (DEFAULT -1) The minimum value of the slider. +- `to`: (DEFAULT 1) The maximum value of the slider. +- `step`: (DEFAULT 0.1) The step value of the slider. +- `color`: (DEFAULT PrimeColor.ultramarine) The color of the slider (preference goes to one of the selected PRIME colours). + +### Example + + + import { Slider, Sliders } from '$lib/utils/Slider'; + import Canvas from '$lib/d3-components/Canvas.svelte'; + + const s1 = new Slider(0.5, -2, 2, 0.5, PrimeColor.green) + const s2 = new Slider(1, -2, 2, 0.5, PrimeColor.ultramarine) + const s3 = new Slider(1.5, -2, 2, 0.5, PrimeColor.red) + const sliders = new Sliders().add(s1).add(s2).add(s3); + + + + +`} /> + +We have created an example with three vectors, each interacting with +a different set of values from the sliders. The green slider controls +only the x direction of the green vector. The blue vector is controlled in +the same way as the green vector, but it adds a y direction that can be +controlled by the blue slider. Finally, the red vector is controlled in +both the x and y directions by the green and blue sliders, and the length +of the vector can be controlled by the red slider. + + + +With multiple sliders the user can extend each slider. All other sliders will +be collapsed to preseve verticle with in the applets. Sliders do not behave any +different in `fullscreen` or `iframe` mode. + +## Shorthand + +For consistency in applets, it is recommended to use the shorthand +method for initializing sliders. Here's how to do it: + + + import { Slider, Sliders } from '$lib/utils/Slider'; + import Canvas from '$lib/d3-components/Canvas.svelte'; + + const sliders = new Sliders() + .addSlider(0.5, -2, 2, 0.5) + .addSlider(1, -2, 2, 0.5) + .addSlider(1.5, -2, 2, 0.5); + + + + +`} /> + +Coloring these sliders using the shorthand syntax is not allowed. This maintains +consistency as the sliders are always colored in the sequence: red, yellow, +and green, as shown below: + \ No newline at end of file diff --git a/src/lib/stories/utils/sliders/sliders.stories.ts b/src/lib/stories/utils/sliders/sliders.stories.ts new file mode 100644 index 00000000..4836f911 --- /dev/null +++ b/src/lib/stories/utils/sliders/sliders.stories.ts @@ -0,0 +1,41 @@ +import { PrimeColor } from '$lib/utils/PrimeColors'; +import { Slider, Sliders } from '$lib/utils/Slider'; +import SliderCanvas from './CanvasWithSliders.svelte'; + +const sliders1 = new Sliders().add(new Slider(0.5, -2, 2, 0.5, PrimeColor.green)); + +const s1 = new Slider(0.5, -2, 2, 0.5, PrimeColor.green); +const s2 = new Slider(1, -2, 2, 0.5, PrimeColor.ultramarine); +const s3 = new Slider(1.5, -2, 2, 0.5, PrimeColor.red); +const sliders2 = new Sliders().add(s1).add(s2).add(s3); + +const sliders3 = new Sliders() + .addSlider(0.5, -2, 2, 0.5) + .addSlider(1, -2, 2, 0.5) + .addSlider(1.5, -2, 2, 0.5); + +export default { + title: 'Tutorial/Sliders', + component: SliderCanvas +}; + +export const OneSlider = { + args: { + title: 'One slider', + sliders: sliders1 + } +}; + +export const MultiSlider = { + args: { + title: 'Three sliders', + sliders: sliders2 + } +}; + +export const MultiSliderShorthand = { + args: { + title: 'Three sliders shorthand', + sliders: sliders3 + } +}; diff --git a/src/lib/utils/Slider.ts b/src/lib/utils/Slider.ts index a1f9f571..34d8775f 100644 --- a/src/lib/utils/Slider.ts +++ b/src/lib/utils/Slider.ts @@ -57,7 +57,7 @@ export class Sliders { // Get the value of a slider by its index private getSlider(index: number) { - if (this._sliders.length < index) return 0; + if (this._sliders.length - 1 < index) return 0; return this._sliders[index].value; } From 62bcf387e863ed5202368645ef46c620881d23dd Mon Sep 17 00:00:00 2001 From: Abel de Bruijn Date: Tue, 28 Nov 2023 23:30:14 +0100 Subject: [PATCH 02/29] setup anatomy tutoral --- .../utils/applet-anatomy/AnatomyCanvas.svelte | 17 +++++++++++++++++ .../stories/utils/applet-anatomy/anatomy.mdx | 7 +++++++ .../utils/applet-anatomy/anatomy.stories.ts | 19 +++++++++++++++++++ src/lib/threlte-components/Canvas.svelte | 4 ++++ 4 files changed, 47 insertions(+) create mode 100644 src/lib/stories/utils/applet-anatomy/AnatomyCanvas.svelte create mode 100644 src/lib/stories/utils/applet-anatomy/anatomy.mdx create mode 100644 src/lib/stories/utils/applet-anatomy/anatomy.stories.ts diff --git a/src/lib/stories/utils/applet-anatomy/AnatomyCanvas.svelte b/src/lib/stories/utils/applet-anatomy/AnatomyCanvas.svelte new file mode 100644 index 00000000..6dee1157 --- /dev/null +++ b/src/lib/stories/utils/applet-anatomy/AnatomyCanvas.svelte @@ -0,0 +1,17 @@ + + + + {#if sliders} + + {/if} + diff --git a/src/lib/stories/utils/applet-anatomy/anatomy.mdx b/src/lib/stories/utils/applet-anatomy/anatomy.mdx new file mode 100644 index 00000000..3d7f3458 --- /dev/null +++ b/src/lib/stories/utils/applet-anatomy/anatomy.mdx @@ -0,0 +1,7 @@ +import { Canvas, Meta, Source } from '@storybook/blocks'; + +import * as AntomyStory from './anatomy.stories'; + + + +# Anatomy of an Applet \ No newline at end of file diff --git a/src/lib/stories/utils/applet-anatomy/anatomy.stories.ts b/src/lib/stories/utils/applet-anatomy/anatomy.stories.ts new file mode 100644 index 00000000..1abde533 --- /dev/null +++ b/src/lib/stories/utils/applet-anatomy/anatomy.stories.ts @@ -0,0 +1,19 @@ +import { Sliders } from '$lib/utils/Slider'; +import AnatomyCanvas from './AnatomyCanvas.svelte'; + +const sliders = new Sliders() + .addSlider(0.5, -2, 2, 0.5) + .addSlider(1, -2, 2, 0.5) + .addSlider(1.5, -2, 2, 0.5); + +export default { + title: 'Tutorial/Anatomy of an applet', + component: AnatomyCanvas +}; + +export const OneSlider = { + args: { + title: 'One slider', + sliders: sliders + } +}; diff --git a/src/lib/threlte-components/Canvas.svelte b/src/lib/threlte-components/Canvas.svelte index e9541102..1d192cdd 100644 --- a/src/lib/threlte-components/Canvas.svelte +++ b/src/lib/threlte-components/Canvas.svelte @@ -12,6 +12,8 @@ export let title = ''; export let background = '#ffffff'; export let showFormulasDefault = false; + export let width = '100%'; + export let height = 'auto'; export let isIframe = false; // Is the scene inside an iframe? export let sliders: Sliders | undefined = undefined; export let formulas: Formula[] = []; @@ -27,6 +29,8 @@ let:height let:resetKey bind:sliders + --height={height} + --width={width} > From cc468dc8bea8cfaad0174f1287be1b8fb17f3f31 Mon Sep 17 00:00:00 2001 From: Abel de Bruijn Date: Wed, 29 Nov 2023 10:17:17 +0100 Subject: [PATCH 03/29] remove unnesecary util function that are no longer in use --- src/lib/utils/CSS2DRenderer.ts | 178 -------------------------------- src/lib/utils/ContextService.ts | 20 ---- src/lib/utils/DocsRoute.ts | 7 -- src/lib/utils/timeDelay.ts | 4 +- 4 files changed, 2 insertions(+), 207 deletions(-) delete mode 100644 src/lib/utils/CSS2DRenderer.ts delete mode 100644 src/lib/utils/ContextService.ts delete mode 100644 src/lib/utils/DocsRoute.ts diff --git a/src/lib/utils/CSS2DRenderer.ts b/src/lib/utils/CSS2DRenderer.ts deleted file mode 100644 index 04514d56..00000000 --- a/src/lib/utils/CSS2DRenderer.ts +++ /dev/null @@ -1,178 +0,0 @@ -import { Camera, Matrix4, Object3D, Scene, Vector3 } from 'three'; - -class CSS2DObject extends Object3D { - element: HTMLElement; - isCSS2DObject = true; - type = 'CSS2DObject'; - - constructor(element = document.createElement('div')) { - super(); - - this.element = element; - - this.element.style.position = 'absolute'; - this.element.style.userSelect = 'none'; - - this.addEventListener('removed', () => { - this.traverseScene(); - }); - } - - traverseScene() { - this.traverse((object: Object3D) => { - console.log(object); - if (object.element instanceof Element && object.element.parentNode !== null) { - object.element.parentNode.removeChild(object.element); - } - }); - } -} - -// - -const _vector = new Vector3(); -const _viewMatrix = new Matrix4(); -const _viewProjectionMatrix = new Matrix4(); -const _a = new Vector3(); -const _b = new Vector3(); - -interface CSS2DRendererElement { - element?: HTMLElement; -} - -class CSS2DRenderer { - domElement: HTMLElement; - - _width: number; - _height: number; - _widthHalf: number; - _heightHalf: number; - - cache = { - objects: new WeakMap() - }; - - constructor(parameters: CSS2DRendererElement = {}) { - this._width = window?.innerWidth || 0; - this._height = window?.innerWidth || 0; - this._widthHalf = this._width / 2; - this._heightHalf = this._height / 2; - - const domElement = - parameters.element !== undefined ? parameters.element : document.createElement('div'); - - domElement.style.overflow = 'hidden'; - - this.domElement = domElement; - } - - getSize() { - return { - width: this._width, - height: this._height - }; - } - - setSize(width: number, height: number) { - this._width = width; - this._height = height; - - this._widthHalf = this._width / 2; - this._heightHalf = this._height / 2; - - this.domElement.style.width = width + 'px'; - this.domElement.style.height = height + 'px'; - } - - getDistanceToSquared(object1: Object3D, object2: Object3D) { - _a.setFromMatrixPosition(object1.matrixWorld); - _b.setFromMatrixPosition(object2.matrixWorld); - - return _a.distanceToSquared(_b); - } - - filterAndFlatten(scene: Scene) { - const result: CSS2DObject[] = []; - - scene.traverse((object: Object3D) => { - if (object.type == 'CSS2DObject' && object instanceof CSS2DObject) result.push(object); - }); - - return result; - } - - zOrder(scene: Scene) { - const sorted = this.filterAndFlatten(scene).sort((a, b) => { - if (a.renderOrder !== b.renderOrder) { - return b.renderOrder - a.renderOrder; - } - - const distanceA = this.cache.objects.get(a).distanceToCameraSquared; - const distanceB = this.cache.objects.get(b).distanceToCameraSquared; - - return distanceA - distanceB; - }); - - const zMax = sorted.length; - - for (let i = 0, l = sorted.length; i < l; i++) { - sorted[i].element.style.zIndex = (zMax - i).toString(); - } - } - - renderObject(object: Object3D, scene: Scene, camera: Camera) { - if ('isCSS2DObject' in object && object instanceof CSS2DObject) { - _vector.setFromMatrixPosition(object.matrixWorld); - _vector.applyMatrix4(_viewProjectionMatrix); - - const visible = - object.visible === true && - _vector.z >= -1 && - _vector.z <= 1 && - object.layers.test(camera.layers) === true; - object.element.style.display = visible === true ? '' : 'none'; - - if (visible === true) { - object.onBeforeRender(this, scene, camera); - - const element = object.element; - - element.style.transform = - 'translate(-50%,-50%) translate(' + - (_vector.x * this._widthHalf + this._widthHalf) + - 'px,' + - (-_vector.y * this._heightHalf + this._heightHalf) + - 'px)'; - - if (element.parentNode !== this.domElement) { - this.domElement.appendChild(element); - } - - object.onAfterRender(this, scene, camera); - } - - const objectData = { - distanceToCameraSquared: this.getDistanceToSquared(camera, object) - }; - - this.cache.objects.set(object, objectData); - } - - for (let i = 0, l = object.children.length; i < l; i++) { - this.renderObject(object.children[i], scene, camera); - } - } - - render(scene: Scene, camera: Camera) { - if (scene.matrixWorldAutoUpdate === true) scene.updateMatrixWorld(); - if (camera.parent === null && camera.matrixWorldAutoUpdate === true) camera.updateMatrixWorld(); - - _viewMatrix.copy(camera.matrixWorldInverse); - _viewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, _viewMatrix); - - this.renderObject(scene, scene, camera); - this.zOrder(scene); - } -} - -export { CSS2DObject, CSS2DRenderer }; diff --git a/src/lib/utils/ContextService.ts b/src/lib/utils/ContextService.ts deleted file mode 100644 index f44c2626..00000000 --- a/src/lib/utils/ContextService.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { getContext, setContext } from 'svelte'; - -function setService(key: string | symbol, service: T): T { - setContext(key, service); - return service; -} - -function getService(key: string | symbol): () => T { - return () => getContext(key) as T; -} - -export function defineService(key: string | symbol = Symbol()): [() => T, (service: T) => T] { - return [ - getService(key), - (service: T) => { - setService(key, service); - return service; - } - ]; -} diff --git a/src/lib/utils/DocsRoute.ts b/src/lib/utils/DocsRoute.ts deleted file mode 100644 index 4b21b121..00000000 --- a/src/lib/utils/DocsRoute.ts +++ /dev/null @@ -1,7 +0,0 @@ -export default interface Route { - url: string; - name: string; - icon?: string; - children?: Route[]; - isExpanded?: boolean; -} diff --git a/src/lib/utils/timeDelay.ts b/src/lib/utils/timeDelay.ts index 098ddeb0..649f5aad 100644 --- a/src/lib/utils/timeDelay.ts +++ b/src/lib/utils/timeDelay.ts @@ -16,10 +16,10 @@ export function debounce(cb: (...args: T[]) => S, delay = 25 }; } -export function throttle(callback, delay = 250) { +export function throttle>(callback: (...args: A) => void, delay = 250) { let shouldWait = false; - return (...args) => { + return (...args: A) => { if (shouldWait) return; callback(...args); From bf67a36cb3dfa267d8c540a2389b9ccf08cced5f Mon Sep 17 00:00:00 2001 From: Abel de Bruijn Date: Wed, 29 Nov 2023 10:17:48 +0100 Subject: [PATCH 04/29] added anatomy of applet tutorial --- .../utils/applet-anatomy/AnatomyCanvas.svelte | 14 +++-- .../stories/utils/applet-anatomy/anatomy.mdx | 60 ++++++++++++++++++- .../utils/applet-anatomy/anatomy.stories.ts | 15 ++++- 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/src/lib/stories/utils/applet-anatomy/AnatomyCanvas.svelte b/src/lib/stories/utils/applet-anatomy/AnatomyCanvas.svelte index 6dee1157..5ceb00ee 100644 --- a/src/lib/stories/utils/applet-anatomy/AnatomyCanvas.svelte +++ b/src/lib/stories/utils/applet-anatomy/AnatomyCanvas.svelte @@ -1,17 +1,19 @@ - - {#if sliders} - - {/if} + + + + + diff --git a/src/lib/stories/utils/applet-anatomy/anatomy.mdx b/src/lib/stories/utils/applet-anatomy/anatomy.mdx index 3d7f3458..8ce9de37 100644 --- a/src/lib/stories/utils/applet-anatomy/anatomy.mdx +++ b/src/lib/stories/utils/applet-anatomy/anatomy.mdx @@ -1,7 +1,63 @@ -import { Canvas, Meta, Source } from '@storybook/blocks'; +import { Canvas, Meta } from '@storybook/blocks'; import * as AntomyStory from './anatomy.stories'; -# Anatomy of an Applet \ No newline at end of file +# Anatomy of an Applet + +All applets can be split-up into four catogories: Canvas, Header, Action Bars +and Share menu. Each will be explained in their subsequent section. A basic +applet can be seen below for reference. + + + +## Canvas + +This is the main content of each applet, displaying either 2D or 3D content. +To add content to the canvas, populate the main slot. To see how, observe the +`2D components` and `threlte` stories. + +## Header + +The header consists of multiple areas: title, interactivity toggle, and formulas. +Each area is optional. See below for a complete header. + + + +### Interactivity toggle + +To get the interactivity toggle, add the `isIframe` prop to the canvas. This is done +by default in the interactive book. When clicked it toggles between active and pasive +state. The pasive state preserves cpu cycles by pausing the applet and in addition +will prevent a user from getting stuck scrolling over a page. + +### Title + +To display a title, include the `title` prop in the canvas. By default, it is hidden +in iframe mode but can be shown by going fullscreen. This decision was made to align +with the book, where the title appears at the bottom of each applet. In fullscreen mode, +the title is displayed at the top to remind the end-user of the context. + +### Formulas + +The formulas, which provide critical information about the applet and its reactivity, +are shown in the top right corner of the header. They often include the values of the +sliders and their corresponding numbers in a formula. Formulas are hidden by default in +the iframe mode but can be shown by toggleing the fx button in the action bar. It is also +possible to show the formulas by default by setting the `showFormulasDefault` prop in the +canvas. To include formulas, use the `formulas` prop in the canvas and provide an array of +Formula objects. For more details, refer to the `formulas` story. + +## Action Bars + +The action bars are located at the bottom right of each applet. They control the interactivity +and toggle UI elements. The action bars are split into two sections: the main action bar and +the slider action bar. The main action bar is always visible and contains the fullscreen, reset, +fx toggle and share buttons. The slider action bar is only visible when sliders are specified +to see how to include sliders, refer to the `sliders` story. + +## Share menu + +One of the buttons in the action bar controls the toggle of the share menu. The share menu +includes a link to the book, a link to the github issue for this applet and a licence notice. diff --git a/src/lib/stories/utils/applet-anatomy/anatomy.stories.ts b/src/lib/stories/utils/applet-anatomy/anatomy.stories.ts index 1abde533..11a71501 100644 --- a/src/lib/stories/utils/applet-anatomy/anatomy.stories.ts +++ b/src/lib/stories/utils/applet-anatomy/anatomy.stories.ts @@ -1,3 +1,4 @@ +import { Formula } from '$lib/utils/Formulas'; import { Sliders } from '$lib/utils/Slider'; import AnatomyCanvas from './AnatomyCanvas.svelte'; @@ -11,9 +12,17 @@ export default { component: AnatomyCanvas }; -export const OneSlider = { +export const SimpleCanvas = { args: { - title: 'One slider', - sliders: sliders + title: 'Trivial example with red cube' + } +}; + +export const FullHeaderCanvas = { + args: { + title: 'Full header example', + isIframe: true, + formulas: [new Formula('3x = y')], + showFormulasDefault: true } }; From 6fcf555eb382829233d397aeca35d9a965ab7a09 Mon Sep 17 00:00:00 2001 From: Abel de Bruijn Date: Wed, 29 Nov 2023 23:19:58 +0100 Subject: [PATCH 05/29] added formulas docs --- .../utils/applet-anatomy/anatomy.stories.ts | 3 +- .../utils/formulas/FormulaCanvas.svelte | 39 +++++++++ src/lib/stories/utils/formulas/formulas.mdx | 84 +++++++++++++++++++ .../utils/formulas/formulas.stories.ts | 48 +++++++++++ .../utils/sliders/CanvasWithSliders.svelte | 6 +- 5 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 src/lib/stories/utils/formulas/FormulaCanvas.svelte create mode 100644 src/lib/stories/utils/formulas/formulas.mdx create mode 100644 src/lib/stories/utils/formulas/formulas.stories.ts diff --git a/src/lib/stories/utils/applet-anatomy/anatomy.stories.ts b/src/lib/stories/utils/applet-anatomy/anatomy.stories.ts index 11a71501..b1e011dd 100644 --- a/src/lib/stories/utils/applet-anatomy/anatomy.stories.ts +++ b/src/lib/stories/utils/applet-anatomy/anatomy.stories.ts @@ -23,6 +23,7 @@ export const FullHeaderCanvas = { title: 'Full header example', isIframe: true, formulas: [new Formula('3x = y')], - showFormulasDefault: true + showFormulasDefault: true, + sliders: sliders } }; diff --git a/src/lib/stories/utils/formulas/FormulaCanvas.svelte b/src/lib/stories/utils/formulas/FormulaCanvas.svelte new file mode 100644 index 00000000..f70444ef --- /dev/null +++ b/src/lib/stories/utils/formulas/FormulaCanvas.svelte @@ -0,0 +1,39 @@ + + + + + {#if sliders && sliders?.sliders.length > 0} + + {:else} + + {/if} + + + diff --git a/src/lib/stories/utils/formulas/formulas.mdx b/src/lib/stories/utils/formulas/formulas.mdx new file mode 100644 index 00000000..d4df80fb --- /dev/null +++ b/src/lib/stories/utils/formulas/formulas.mdx @@ -0,0 +1,84 @@ +import { Canvas, Meta, Source } from '@storybook/blocks'; + +import * as FormulasStory from './formulas.stories'; + + + +# Formulas + +Formulas are used to show how some objects in the canvas are derived from formulas. +Formulas can also show properties of objects in the canvas such as length or area, +depending on the context of the book. + +## Simple formula + +Formulas consist of a string, a value, and a color. Each formula is displayed on its own line. +The character `\\$` is used as a placeholder for the value position. + + + import { Canvas3D } from '$lib/threlte-components'; + import { Formula } from '$lib/utils/Formulas'; + import { PrimeColor } from '$lib/utils/PrimeColors'; + + const f1 = new Formula('Area = 1 * 2 * 3 = \\$', 6, PrimeColor.red); + const f2 = new Formula('Surface = 2 * (2 + 6 + 3) = \\$', 22, PrimeColor.yellow); + + + + + +`} /> + + + +## Formula with multiple colours on the same line + +Formulas can have multiple colours on the same line. This is useful when you want +to highlight a multiple specific parts of the formula. Here it is curtial to use +the `\\$` with a number to indicate the position of the value. + +> Using the same index will insert the same value at multiple places in the formula. + +The formula will have be colored by the `addParam` or `addAutoParam` methods. The `addParam` method +takes the index of the `\\$` and the value to insert. The `addAutoParam` method takes the value to insert +and will automatically increment the index starting from index 1. (Due to javascript limitations, the index does not start at 0) + + + + + +## Formula with interactivity + +The formulas are not interactive by default (in svelte v4, v5 will change this [see here](https://svelte.dev/blog/runes)). +To make the formulas interactive, you need to use the `$` sign in front of the variable name. +This will make the variable reactive and update the formula when the variable changes. + + + +> Notice how, the inclusion of, the formulas now provide more context to each slider. + + diff --git a/src/lib/stories/utils/formulas/formulas.stories.ts b/src/lib/stories/utils/formulas/formulas.stories.ts new file mode 100644 index 00000000..7515cdee --- /dev/null +++ b/src/lib/stories/utils/formulas/formulas.stories.ts @@ -0,0 +1,48 @@ +import { Formula } from '$lib/utils/Formulas'; +import { PrimeColor } from '$lib/utils/PrimeColors'; +import { Sliders } from '$lib/utils/Slider'; +import FormulaCanvas from './FormulaCanvas.svelte'; + +const sliders = new Sliders() + .addSlider(1, -2, 3, 0.5) + .addSlider(2, -2, 3, 0.5) + .addSlider(3, -2, 3, 0.5); + +const f1 = new Formula('Area = 1 * 2 * 3 = \\$', 6, PrimeColor.red); +const f2 = new Formula('Surface = 2 * (2 + 6 + 3) = \\$', 22, PrimeColor.yellow); + +const f3 = new Formula('Area = \\$1 * \\$3 * \\$2 = 6') + .addParam(1, 1, PrimeColor.red) + .addParam(3, 2, PrimeColor.yellow) + .addParam(2, 3, PrimeColor.green); + +const f4 = new Formula('Surface = \\$1 * (\\$1 + \\$2 + \\$3) = 22') + .addAutoParam(2, PrimeColor.red) + .addAutoParam(6, PrimeColor.yellow) + .addAutoParam(3, PrimeColor.green); + +export default { + title: 'Tutorial/Formulas', + component: FormulaCanvas +}; + +export const SimpleFormula = { + args: { + title: 'Trivial example with red rectangle', + formulas: [f1, f2] + } +}; + +export const MulticolorFormula = { + args: { + title: 'Multi-color example with red rectangle', + formulas: [f3, f4] + } +}; + +export const InteractiveFormula = { + args: { + title: 'Interactive example with red rectangle', + sliders: sliders + } +}; diff --git a/src/lib/stories/utils/sliders/CanvasWithSliders.svelte b/src/lib/stories/utils/sliders/CanvasWithSliders.svelte index b1eec4bf..57222fb7 100644 --- a/src/lib/stories/utils/sliders/CanvasWithSliders.svelte +++ b/src/lib/stories/utils/sliders/CanvasWithSliders.svelte @@ -10,13 +10,13 @@ {#if sliders} - {#if sliders?.x} + {#if sliders?.x != undefined} {/if} - {#if sliders?.y} + {#if sliders?.y != undefined} {/if} - {#if sliders?.z} + {#if sliders?.z != undefined} {/if} {/if} From 045fe09b17eb6c15a34f57502263f42e5cbe8ef5 Mon Sep 17 00:00:00 2001 From: Abel de Bruijn Date: Thu, 30 Nov 2023 15:40:50 +0100 Subject: [PATCH 06/29] Added draggable docs --- src/lib/stories/BookEmbed.mdx | 17 ++++++ .../draggables/CanvasWithDraggables.svelte | 19 +++++++ .../utils/draggables/Draggable.stories.ts | 19 +++++++ .../stories/utils/draggables/draggable.mdx | 52 +++++++++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 src/lib/stories/BookEmbed.mdx create mode 100644 src/lib/stories/utils/draggables/CanvasWithDraggables.svelte create mode 100644 src/lib/stories/utils/draggables/Draggable.stories.ts create mode 100644 src/lib/stories/utils/draggables/draggable.mdx diff --git a/src/lib/stories/BookEmbed.mdx b/src/lib/stories/BookEmbed.mdx new file mode 100644 index 00000000..bf91e95e --- /dev/null +++ b/src/lib/stories/BookEmbed.mdx @@ -0,0 +1,17 @@ +import { Meta } from '@storybook/blocks'; + + + +# How to embed an applet in a book + +This will be discussed in the next PGG meetings. + +## URL parsing + +### Encoding + +TODO + +### Decoding + +TODO diff --git a/src/lib/stories/utils/draggables/CanvasWithDraggables.svelte b/src/lib/stories/utils/draggables/CanvasWithDraggables.svelte new file mode 100644 index 00000000..2af9524c --- /dev/null +++ b/src/lib/stories/utils/draggables/CanvasWithDraggables.svelte @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/src/lib/stories/utils/draggables/Draggable.stories.ts b/src/lib/stories/utils/draggables/Draggable.stories.ts new file mode 100644 index 00000000..f4d37c9d --- /dev/null +++ b/src/lib/stories/utils/draggables/Draggable.stories.ts @@ -0,0 +1,19 @@ +import DraggableCanvas from './CanvasWithDraggables.svelte'; + +export default { + title: 'Tutorial/Draggables', + component: DraggableCanvas +}; + +export const SimpleExample = { + args: { + title: 'Simple example with two draggable vertices' + } +}; + +export const SnapExample = { + args: { + title: 'Two draggable vertices that snap to a grid', + snap: true + } +}; diff --git a/src/lib/stories/utils/draggables/draggable.mdx b/src/lib/stories/utils/draggables/draggable.mdx new file mode 100644 index 00000000..8cf7d29d --- /dev/null +++ b/src/lib/stories/utils/draggables/draggable.mdx @@ -0,0 +1,52 @@ +import { Canvas, Meta, Source } from '@storybook/blocks'; + +import * as DraggableStory from './Draggable.stories'; + + + +# Draggable + +The Draggable component enables interactivity with the mouse or touch for an element. +It is exclusive to the Canvas 2D block because dragging in a 3D space can be ambiguous on a 2D screen. +Just like sliders, zooming and panning are reset when the reset button is pressed. + +To create a draggable element, simply add a `Draggable2D` component to the Canvas 2D block with the following properties: + +- `id`: a unique identifier for the draggable element (required) +- `position`: a `Vector2` object that will be updated with the position of the draggable element (required) +- `color`: the color of the draggable element (optional, defaults to `PrimeColor.black`) + + + import { Canvas2D, Latex2D, Vector2D, Draggable2D } from '$lib/d3-components'; + import { PrimeColor } from '$lib/utils/PrimeColors'; + import { Vector2 } from 'three'; + +let w = new Vector2(1, 3); +let v = new Vector2(3, 0); + + + + + + + + + + +`} /> + + + +## Draggable snapping + +To enable snapping, add a `snap` property to the `Draggable2D` component. + + + +`} +/> + + From 672d6d3a8d211cc03a497eeba2e6be0a5fab3dd4 Mon Sep 17 00:00:00 2001 From: PHengst Date: Fri, 8 Dec 2023 11:55:33 +0100 Subject: [PATCH 07/29] move negative 2D y axis labels slightly, drop origin label for split canvas --- src/lib/d3-components/Canvas.svelte | 4 +--- src/lib/d3-components/grids/SquareGrid.svelte | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/lib/d3-components/Canvas.svelte b/src/lib/d3-components/Canvas.svelte index 82cb8b7f..9d2a5695 100644 --- a/src/lib/d3-components/Canvas.svelte +++ b/src/lib/d3-components/Canvas.svelte @@ -41,9 +41,7 @@
- - - + {/if} diff --git a/src/lib/d3-components/grids/SquareGrid.svelte b/src/lib/d3-components/grids/SquareGrid.svelte index 8bffde5c..6fdb9bd0 100644 --- a/src/lib/d3-components/grids/SquareGrid.svelte +++ b/src/lib/d3-components/grids/SquareGrid.svelte @@ -55,7 +55,7 @@ {#if index > 0} {:else} - + {/if} {/if} {/each} From 42aa139d429ea97cfb0e5cd5056eed53691bab93 Mon Sep 17 00:00:00 2001 From: PHengst Date: Fri, 8 Dec 2023 12:38:21 +0100 Subject: [PATCH 08/29] replace axis label with latex, fix positioning --- src/lib/threlte-components/Axis.svelte | 17 +++++++---------- src/lib/threlte-components/Latex.svelte | 2 +- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/lib/threlte-components/Axis.svelte b/src/lib/threlte-components/Axis.svelte index 03962d86..406261cc 100644 --- a/src/lib/threlte-components/Axis.svelte +++ b/src/lib/threlte-components/Axis.svelte @@ -84,19 +84,16 @@ {#if showNumbers} {#each labeledIndicators as indicator} {@const indicatorFixed = indicator.toFixed(2).replace('.00', '')} - - - - + + + + + + {/each} {/if} + diff --git a/src/lib/threlte-components/Latex.svelte b/src/lib/threlte-components/Latex.svelte index 70c1cc8f..d7f2f4d8 100644 --- a/src/lib/threlte-components/Latex.svelte +++ b/src/lib/threlte-components/Latex.svelte @@ -7,7 +7,7 @@ export let color = 'black'; export let position = new Vector3(0, 0, 0); export let size = 1; - export let offset = 0.25; + export let offset = 0; let str = ''; From e3ba535f642d701dedda3937e6efa1b2644eb6a8 Mon Sep 17 00:00:00 2001 From: PHengst Date: Fri, 8 Dec 2023 12:58:04 +0100 Subject: [PATCH 09/29] swap --- src/lib/threlte-components/Axis.svelte | 8 ++++---- src/lib/threlte-components/Latex.svelte | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib/threlte-components/Axis.svelte b/src/lib/threlte-components/Axis.svelte index 406261cc..14c1ab11 100644 --- a/src/lib/threlte-components/Axis.svelte +++ b/src/lib/threlte-components/Axis.svelte @@ -44,7 +44,7 @@ to.set(-size, 0, indicator); } - return [from, to]; + return [from, to]; } $: if (responsiveSpacing && $cameraStore) { @@ -85,11 +85,11 @@ {#each labeledIndicators as indicator} {@const indicatorFixed = indicator.toFixed(2).replace('.00', '')} - + - + - + {/each} {/if} diff --git a/src/lib/threlte-components/Latex.svelte b/src/lib/threlte-components/Latex.svelte index d7f2f4d8..70c1cc8f 100644 --- a/src/lib/threlte-components/Latex.svelte +++ b/src/lib/threlte-components/Latex.svelte @@ -7,7 +7,7 @@ export let color = 'black'; export let position = new Vector3(0, 0, 0); export let size = 1; - export let offset = 0; + export let offset = 0.25; let str = ''; From d3b356c624b813d3831a0e99cb0ed15180de383a Mon Sep 17 00:00:00 2001 From: PHengst Date: Fri, 15 Dec 2023 11:31:33 +0100 Subject: [PATCH 10/29] whoopsie --- .../innerproduct_projectionvectorline/+page.svelte | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/routes/applet/dot_product/innerproduct_projectionvectorline/+page.svelte b/src/routes/applet/dot_product/innerproduct_projectionvectorline/+page.svelte index bae0ba40..02ec15fa 100644 --- a/src/routes/applet/dot_product/innerproduct_projectionvectorline/+page.svelte +++ b/src/routes/applet/dot_product/innerproduct_projectionvectorline/+page.svelte @@ -29,7 +29,7 @@ @@ -38,7 +38,7 @@ @@ -46,7 +46,7 @@ - + From 49e7acf2f03cd30b0d1564023117d7f7389c2318 Mon Sep 17 00:00:00 2001 From: PHengst Date: Fri, 22 Dec 2023 16:23:06 +0100 Subject: [PATCH 11/29] label positions linesandplanes\vectorequation --- .../lines_and_planes/vector-equation/+page.svelte | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/routes/applet/lines_and_planes/vector-equation/+page.svelte b/src/routes/applet/lines_and_planes/vector-equation/+page.svelte index 224781e8..7fe7cf66 100644 --- a/src/routes/applet/lines_and_planes/vector-equation/+page.svelte +++ b/src/routes/applet/lines_and_planes/vector-equation/+page.svelte @@ -23,11 +23,11 @@ @@ -50,7 +50,7 @@ @@ -59,7 +59,7 @@ From 6c0eea2d2cf209615b4374f3972973cf520244ec Mon Sep 17 00:00:00 2001 From: Abel de Bruijn Date: Thu, 4 Jan 2024 16:18:00 +0100 Subject: [PATCH 12/29] format and linting --- src/lib/threlte-components/Axis.svelte | 22 ++++++++++++++----- .../+page.svelte | 6 ++++- .../embed_r2_r3/+page.svelte | 12 ++++------ 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/lib/threlte-components/Axis.svelte b/src/lib/threlte-components/Axis.svelte index 14c1ab11..986c555e 100644 --- a/src/lib/threlte-components/Axis.svelte +++ b/src/lib/threlte-components/Axis.svelte @@ -3,7 +3,6 @@ import { DoubleSide, Vector3 } from 'three'; import { PrimeColor } from '$lib/utils/PrimeColors'; - import Label from './Label.svelte'; import Latex3D from './Latex.svelte'; import Line from './Line.svelte'; import cameraStore from './stores/cameraStore'; @@ -28,7 +27,6 @@ $: indicatorMax = indicators[indicators.length - 1]; const tickSizes = [0.25, 0.125]; // Ortogonal lenth of tick - const axisLabelOpacity = 0.4; function getPoints(indicator: number, size: number, axis = 0): [Vector3, Vector3] { let from = new Vector3(indicator, 0, size); @@ -44,7 +42,7 @@ to.set(-size, 0, indicator); } - return [from, to]; + return [from, to]; } $: if (responsiveSpacing && $cameraStore) { @@ -85,11 +83,23 @@ {#each labeledIndicators as indicator} {@const indicatorFixed = indicator.toFixed(2).replace('.00', '')} - + - + - + {/each} {/if} diff --git a/src/routes/applet/dot_product/innerproduct_projectionvectorline/+page.svelte b/src/routes/applet/dot_product/innerproduct_projectionvectorline/+page.svelte index 0899aec3..1467654c 100644 --- a/src/routes/applet/dot_product/innerproduct_projectionvectorline/+page.svelte +++ b/src/routes/applet/dot_product/innerproduct_projectionvectorline/+page.svelte @@ -46,7 +46,11 @@ - + diff --git a/src/routes/applet/linear_transformation/embed_r2_r3/+page.svelte b/src/routes/applet/linear_transformation/embed_r2_r3/+page.svelte index ca94563e..16554636 100644 --- a/src/routes/applet/linear_transformation/embed_r2_r3/+page.svelte +++ b/src/routes/applet/linear_transformation/embed_r2_r3/+page.svelte @@ -1,10 +1,10 @@ - - + + - - + + diff --git a/src/lib/stories/utils/draggables/draggable.mdx b/src/lib/stories/utils/draggables/draggable.mdx index 8cf7d29d..a6a6dca1 100644 --- a/src/lib/stories/utils/draggables/draggable.mdx +++ b/src/lib/stories/utils/draggables/draggable.mdx @@ -27,11 +27,11 @@ let v = new Vector2(3, 0); - - + + - - + + `} /> @@ -44,8 +44,8 @@ To enable snapping, add a `snap` property to the `Draggable2D` component. - + + `} /> diff --git a/src/lib/stories/utils/formulas/FormulaCanvas.svelte b/src/lib/stories/utils/formulas/FormulaCanvas.svelte index f70444ef..ae9ffc1d 100644 --- a/src/lib/stories/utils/formulas/FormulaCanvas.svelte +++ b/src/lib/stories/utils/formulas/FormulaCanvas.svelte @@ -16,8 +16,8 @@ const f1 = new Formula('Area = |\\$1| * |\\$2| * |\\$3| = \\$4') .addAutoParam(x, PrimeColor.red) .addAutoParam(y, PrimeColor.yellow) - .addAutoParam(z, PrimeColor.green) - .addAutoParam(area, PrimeColor.ultramarine); + .addAutoParam(z, PrimeColor.darkGreen) + .addAutoParam(area, PrimeColor.blue); return [f1]; } diff --git a/src/lib/stories/utils/formulas/formulas.mdx b/src/lib/stories/utils/formulas/formulas.mdx index d4df80fb..80f6f712 100644 --- a/src/lib/stories/utils/formulas/formulas.mdx +++ b/src/lib/stories/utils/formulas/formulas.mdx @@ -46,13 +46,13 @@ and will automatically increment the index starting from index 1. (Due to javasc @@ -70,8 +70,8 @@ This will make the variable reactive and update the formula when the variable ch const f1 = new Formula('Area = |\\$1| * |\\$2| * |\\$3| = \\$4') .addAutoParam(x, PrimeColor.red) .addAutoParam(y, PrimeColor.yellow) - .addAutoParam(z, PrimeColor.green) - .addAutoParam(area, PrimeColor.ultramarine); + .addAutoParam(z, PrimeColor.darkGreen) + .addAutoParam(area, PrimeColor.blue); return [f1]; diff --git a/src/lib/stories/utils/formulas/formulas.stories.ts b/src/lib/stories/utils/formulas/formulas.stories.ts index 7515cdee..17c453e9 100644 --- a/src/lib/stories/utils/formulas/formulas.stories.ts +++ b/src/lib/stories/utils/formulas/formulas.stories.ts @@ -14,12 +14,12 @@ const f2 = new Formula('Surface = 2 * (2 + 6 + 3) = \\$', 22, PrimeColor.yellow) const f3 = new Formula('Area = \\$1 * \\$3 * \\$2 = 6') .addParam(1, 1, PrimeColor.red) .addParam(3, 2, PrimeColor.yellow) - .addParam(2, 3, PrimeColor.green); + .addParam(2, 3, PrimeColor.darkGreen); const f4 = new Formula('Surface = \\$1 * (\\$1 + \\$2 + \\$3) = 22') .addAutoParam(2, PrimeColor.red) .addAutoParam(6, PrimeColor.yellow) - .addAutoParam(3, PrimeColor.green); + .addAutoParam(3, PrimeColor.darkGreen); export default { title: 'Tutorial/Formulas', diff --git a/src/lib/stories/utils/sliders/sliders.mdx b/src/lib/stories/utils/sliders/sliders.mdx index fa763a56..48b07158 100644 --- a/src/lib/stories/utils/sliders/sliders.mdx +++ b/src/lib/stories/utils/sliders/sliders.mdx @@ -6,8 +6,8 @@ import * as SlidersStory from './sliders.stories'; # Sliders -Sliders are crucial for UIs as they enable developers to add interactivity -to their applets. An applet can have multiple sliders, but the maximum +Sliders are crucial for UIs as they enable developers to add interactivity +to their applets. An applet can have multiple sliders, but the maximum limit is 3. In this section, you'll find a range of sliders to choose from. An example of such a slider is shown below: @@ -16,7 +16,7 @@ An example of such a slider is shown below: import { Slider, Sliders } from '$lib/utils/Slider'; import Canvas from '$lib/d3-components/Canvas.svelte'; - const sliders = new Sliders().add(new Slider(0.5, -2, 2, 0.5, PrimeColor.green)); + const sliders = new Sliders().add(new Slider(0.5, -2, 2, 0.5, PrimeColor.darkGreen)); @@ -28,18 +28,18 @@ The result of the above code is shown below: -The end-user can drag the slider or choose to let it auto-play. In auto-play mode, -the slider moves back and forth in discrete steps, demonstrating the range of movement +The end-user can drag the slider or choose to let it auto-play. In auto-play mode, +the slider moves back and forth in discrete steps, demonstrating the range of movement for the interactive element. The auto-play mode can be stopped by either clicking the pause button, or interacting manually with the range slider. -The reset button to the bottom right will reset the positions of all sliders +The reset button to the bottom right will reset the positions of all sliders and resets the values of \{sliders.x\}, \{sliders.y\} and \{sliders.z\}. ## Multiple Sliders -Multiple sliders can be added to the canvas by using by chaining the `add` -method of the `Sliders` class. The `add` method takes a `Slider` object +Multiple sliders can be added to the canvas by using by chaining the `add` +method of the `Sliders` class. The `add` method takes a `Slider` object as an argument. The `Slider` object takes the following arguments: - `defaultValue`: (Required) The default value of the slider. @@ -54,7 +54,7 @@ as an argument. The `Slider` object takes the following arguments: import { Slider, Sliders } from '$lib/utils/Slider'; import Canvas from '$lib/d3-components/Canvas.svelte'; - const s1 = new Slider(0.5, -2, 2, 0.5, PrimeColor.green) + const s1 = new Slider(0.5, -2, 2, 0.5, PrimeColor.darkGreen) const s2 = new Slider(1, -2, 2, 0.5, PrimeColor.ultramarine) const s3 = new Slider(1.5, -2, 2, 0.5, PrimeColor.red) const sliders = new Sliders().add(s1).add(s2).add(s3); @@ -64,12 +64,12 @@ as an argument. The `Slider` object takes the following arguments: `} /> -We have created an example with three vectors, each interacting with -a different set of values from the sliders. The green slider controls +We have created an example with three vectors, each interacting with +a different set of values from the sliders. The green slider controls only the x direction of the green vector. The blue vector is controlled in the same way as the green vector, but it adds a y direction that can be -controlled by the blue slider. Finally, the red vector is controlled in -both the x and y directions by the green and blue sliders, and the length +controlled by the blue slider. Finally, the red vector is controlled in +both the x and y directions by the green and blue sliders, and the length of the vector can be controlled by the red slider. @@ -84,20 +84,23 @@ For consistency in applets, it is recommended to use the shorthand method for initializing sliders. Here's how to do it: - import { Slider, Sliders } from '$lib/utils/Slider'; + +import { Slider, Sliders } from '$lib/utils/Slider'; import Canvas from '$lib/d3-components/Canvas.svelte'; - - const sliders = new Sliders() - .addSlider(0.5, -2, 2, 0.5) - .addSlider(1, -2, 2, 0.5) - .addSlider(1.5, -2, 2, 0.5); + +const sliders = new Sliders() +.addSlider(0.5, -2, 2, 0.5) +.addSlider(1, -2, 2, 0.5) +.addSlider(1.5, -2, 2, 0.5); + `} /> -Coloring these sliders using the shorthand syntax is not allowed. This maintains -consistency as the sliders are always colored in the sequence: red, yellow, +Coloring these sliders using the shorthand syntax is not allowed. This maintains +consistency as the sliders are always colored in the sequence: red, yellow, and green, as shown below: - \ No newline at end of file + + diff --git a/src/lib/stories/utils/sliders/sliders.stories.ts b/src/lib/stories/utils/sliders/sliders.stories.ts index 4836f911..291d3420 100644 --- a/src/lib/stories/utils/sliders/sliders.stories.ts +++ b/src/lib/stories/utils/sliders/sliders.stories.ts @@ -2,10 +2,10 @@ import { PrimeColor } from '$lib/utils/PrimeColors'; import { Slider, Sliders } from '$lib/utils/Slider'; import SliderCanvas from './CanvasWithSliders.svelte'; -const sliders1 = new Sliders().add(new Slider(0.5, -2, 2, 0.5, PrimeColor.green)); +const sliders1 = new Sliders().add(new Slider(0.5, -2, 2, 0.5, PrimeColor.darkGreen)); -const s1 = new Slider(0.5, -2, 2, 0.5, PrimeColor.green); -const s2 = new Slider(1, -2, 2, 0.5, PrimeColor.ultramarine); +const s1 = new Slider(0.5, -2, 2, 0.5, PrimeColor.darkGreen); +const s2 = new Slider(1, -2, 2, 0.5, PrimeColor.blue); const s3 = new Slider(1.5, -2, 2, 0.5, PrimeColor.red); const sliders2 = new Sliders().add(s1).add(s2).add(s3); diff --git a/src/routes/applet/basisdim/standardbasis/+page.svelte b/src/routes/applet/basisdim/standardbasis/+page.svelte index 99f93b8f..40526a70 100644 --- a/src/routes/applet/basisdim/standardbasis/+page.svelte +++ b/src/routes/applet/basisdim/standardbasis/+page.svelte @@ -17,22 +17,22 @@ - + - + @@ -40,12 +40,12 @@ - - + + - - + + From 32abf4e86093a0f82a7b80a8ea65cd0702c940ea Mon Sep 17 00:00:00 2001 From: Abel de Bruijn Date: Tue, 6 Feb 2024 12:54:37 +0100 Subject: [PATCH 21/29] hotfix: searching in applets --- src/lib/utils/Slider.ts | 2 +- src/routes/[...catchall]/+page.svelte | 9 ++------- src/routes/[...catchall]/FilterList.svelte | 2 +- src/routes/[...catchall]/ListItem.svelte | 10 +++++++++- .../lines_and_planes/disjoint_planes/+page.svelte | 2 +- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/lib/utils/Slider.ts b/src/lib/utils/Slider.ts index 64d8dda5..c0f1ee42 100644 --- a/src/lib/utils/Slider.ts +++ b/src/lib/utils/Slider.ts @@ -205,7 +205,7 @@ export class Slider { return this; } - green() { + darkGreen() { this.color = PrimeColor.darkGreen; return this; } diff --git a/src/routes/[...catchall]/+page.svelte b/src/routes/[...catchall]/+page.svelte index d359001f..5b2c73ef 100644 --- a/src/routes/[...catchall]/+page.svelte +++ b/src/routes/[...catchall]/+page.svelte @@ -33,12 +33,11 @@ if (e.key == 'k' && e.metaKey) searchInput.focus(); } - let search = debounce(async () => { + let search = debounce(() => { searchInput.focus(); searchInput.setSelectionRange(searchQuery.length, searchQuery.length); url.searchParams.set('q', searchQuery); - await goto(url, { replaceState: true }); searchInput.focus(); searchInput.setSelectionRange(searchQuery.length, searchQuery.length); }, 2000); @@ -58,11 +57,7 @@ placeholder="Enter applet name" class="input input-bordered w-full max-w-xs" bind:value={searchQuery} - on:keyup={async () => { - await search(); - - searchInput.setSelectionRange(searchQuery.length, searchQuery.length); - }} + on:keyup={() => search()} />
⌘ diff --git a/src/routes/[...catchall]/FilterList.svelte b/src/routes/[...catchall]/FilterList.svelte index 7d5a37b4..2b7e5425 100644 --- a/src/routes/[...catchall]/FilterList.svelte +++ b/src/routes/[...catchall]/FilterList.svelte @@ -38,7 +38,7 @@
{#each searchedFiles as { item: file } (file.url)} - + {:else} diff --git a/src/routes/applet/lines_and_planes/disjoint_planes/+page.svelte b/src/routes/applet/lines_and_planes/disjoint_planes/+page.svelte index 7993691b..5679ae4a 100644 --- a/src/routes/applet/lines_and_planes/disjoint_planes/+page.svelte +++ b/src/routes/applet/lines_and_planes/disjoint_planes/+page.svelte @@ -8,7 +8,7 @@ import { Formula } from '$lib/utils/Formulas'; const n0 = new Vector3(1, 1, 1).normalize(); - let sliders = new Sliders().add(new Slider(0, -2, 2, 0.5, PrimeColor.darkGreen)); + let sliders = new Sliders().add(new Slider(0, -2, 0.5, 0.5, PrimeColor.darkGreen)); $: n1 = new Vector3(sliders.x, 1, 1).normalize(); From f7421fe2be42dd853c7594550e57febae9e33481 Mon Sep 17 00:00:00 2001 From: Abel de Bruijn Date: Fri, 9 Feb 2024 13:45:52 +0100 Subject: [PATCH 22/29] fix: button height --- src/lib/components/FormulasAndActivityPanel.svelte | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/lib/components/FormulasAndActivityPanel.svelte b/src/lib/components/FormulasAndActivityPanel.svelte index e48a9d73..e27caed5 100644 --- a/src/lib/components/FormulasAndActivityPanel.svelte +++ b/src/lib/components/FormulasAndActivityPanel.svelte @@ -27,14 +27,17 @@ {#if $activityStore} {:else} - {/if} From 22fadf6a5a198b22e1b0138f4ce55c2c0c1f285b Mon Sep 17 00:00:00 2001 From: Abel de Bruijn Date: Fri, 9 Feb 2024 13:47:36 +0100 Subject: [PATCH 23/29] fix typo --- src/lib/components/ShareWindow.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/ShareWindow.svelte b/src/lib/components/ShareWindow.svelte index a8c7981c..815cd8e9 100644 --- a/src/lib/components/ShareWindow.svelte +++ b/src/lib/components/ShareWindow.svelte @@ -133,7 +133,7 @@ '' )}%29" > - Go this applet's github page here Go to this applet's github page here From 8137054b94b8bd1230c4a5fb94b23d22f6761b70 Mon Sep 17 00:00:00 2001 From: Abel de Bruijn Date: Fri, 9 Feb 2024 14:01:14 +0100 Subject: [PATCH 24/29] Update latex formatting in span_one, span_three_plane, span_two_line, and span_two_plane pages --- .../applet/linear_combinations/span_one/+page.svelte | 2 +- .../linear_combinations/span_three_plane/+page.svelte | 9 ++++----- .../linear_combinations/span_two_line/+page.svelte | 7 +------ .../linear_combinations/span_two_plane/+page.svelte | 9 ++++----- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/routes/applet/linear_combinations/span_one/+page.svelte b/src/routes/applet/linear_combinations/span_one/+page.svelte index 5e9c7b4f..d50bbcb5 100644 --- a/src/routes/applet/linear_combinations/span_one/+page.svelte +++ b/src/routes/applet/linear_combinations/span_one/+page.svelte @@ -17,7 +17,7 @@ diff --git a/src/routes/applet/linear_combinations/span_three_plane/+page.svelte b/src/routes/applet/linear_combinations/span_three_plane/+page.svelte index 8aeb7d96..be35798d 100644 --- a/src/routes/applet/linear_combinations/span_three_plane/+page.svelte +++ b/src/routes/applet/linear_combinations/span_three_plane/+page.svelte @@ -10,8 +10,8 @@ - - + + @@ -40,12 +40,11 @@ /> - + diff --git a/src/routes/applet/linear_combinations/span_two_line/+page.svelte b/src/routes/applet/linear_combinations/span_two_line/+page.svelte index 0897894d..235dee66 100644 --- a/src/routes/applet/linear_combinations/span_two_line/+page.svelte +++ b/src/routes/applet/linear_combinations/span_two_line/+page.svelte @@ -24,11 +24,6 @@ /> - + diff --git a/src/routes/applet/linear_combinations/span_two_plane/+page.svelte b/src/routes/applet/linear_combinations/span_two_plane/+page.svelte index edb9d9ff..110e959c 100644 --- a/src/routes/applet/linear_combinations/span_two_plane/+page.svelte +++ b/src/routes/applet/linear_combinations/span_two_plane/+page.svelte @@ -11,20 +11,19 @@ - - + + - + From 0b464a04dafd1a3e48e10498dd6dfd5dcef2295d Mon Sep 17 00:00:00 2001 From: Abel de Bruijn Date: Fri, 9 Feb 2024 17:57:26 +0100 Subject: [PATCH 25/29] Sliders -> Controllers --- src/lib/components/AbstractCanvas.svelte | 31 ++-- ...derPanel.svelte => ControllerPanel.svelte} | 0 src/lib/components/ShareWindow.svelte | 22 +-- src/lib/components/Slider.stories.ts | 6 +- src/lib/components/ToggleControls.svelte | 35 ++++ src/lib/components/ToggleSliders.svelte | 28 --- src/lib/d3-components/Canvas.svelte | 8 +- .../stories/Canvas.stories.svelte | 2 +- .../utils/applet-anatomy/AnatomyCanvas.svelte | 8 +- .../utils/applet-anatomy/anatomy.stories.ts | 5 +- .../utils/formulas/FormulaCanvas.svelte | 30 ++-- .../utils/formulas/formulas.stories.ts | 7 +- .../utils/sliders/CanvasWithSliders.svelte | 22 +-- .../stories/utils/sliders/sliders.stories.ts | 21 +-- src/lib/threlte-components/Canvas.svelte | 8 +- .../stories/Canvas.stories.ts | 14 +- src/lib/utils/Controls.ts | 162 ++++++++++++++++++ src/lib/utils/Slider.ts | 134 ++------------- .../inner_product_length/+page.svelte | 36 ++-- .../span_three/+page.svelte | 25 +++ .../disjoint_planes/+page.svelte | 17 +- .../parametric_line_space/+page.svelte | 10 +- .../plane_line_intersection/+page.svelte | 12 +- .../planes_point_intersection/+page.svelte | 18 +- .../two_disjoint_planes/+page.svelte | 12 +- .../two_plane_line_intersection/+page.svelte | 12 +- 26 files changed, 387 insertions(+), 298 deletions(-) rename src/lib/components/{SliderPanel.svelte => ControllerPanel.svelte} (100%) create mode 100644 src/lib/components/ToggleControls.svelte delete mode 100644 src/lib/components/ToggleSliders.svelte create mode 100644 src/lib/utils/Controls.ts create mode 100644 src/routes/applet/linear_combinations/span_three/+page.svelte diff --git a/src/lib/components/AbstractCanvas.svelte b/src/lib/components/AbstractCanvas.svelte index d1212857..6773b9bf 100644 --- a/src/lib/components/AbstractCanvas.svelte +++ b/src/lib/components/AbstractCanvas.svelte @@ -4,14 +4,16 @@ import ActionButtons from '$lib/components/ActionButtons.svelte'; import FormulasAndActivityPanel from '$lib/components/FormulasAndActivityPanel.svelte'; import ShareWindow from '$lib/components/ShareWindow.svelte'; - import SliderPanel from '$lib/components/SliderPanel.svelte'; - import ToggleSliders from '$lib/components/ToggleSliders.svelte'; + import ControllerPanel from '$lib/components/ControllerPanel.svelte'; + import ToggleControls from '$lib/components/ToggleControls.svelte'; + import type { Controls } from '$lib/utils/Controls'; import type { Formula } from '$lib/utils/Formulas'; - import { Sliders } from '$lib/utils/Slider'; import { onDestroy, onMount } from 'svelte'; + type G = $$Generic[]>; + /** "The ability to enable move (translate) the applet. On devices with a mouse this can be controlled by right mouse button dragging. On touchscreen devices, this can be done by dragging with two finders on the screen."*/ - export let sliders = new Sliders(); + export let controls: Controls | undefined = undefined; export let title = ''; export let background = '#ffffff'; export let showFormulasDefault = false; @@ -31,10 +33,10 @@ let sceneEl: HTMLDivElement; /** - * Reset camera position, rotation and sliders. + * Reset camera position, rotation and controls. */ function reset() { - sliders = sliders.reset(); // Reset sliders to default values + controls = controls?.reset(); // Reset controls to default values resetKey = Math.random(); // Update the key to reset the set camera component } @@ -57,9 +59,10 @@ onMount(() => { const params = $page.url?.searchParams; - if (sliders.fromURL) { - sliders = sliders?.fromURL(params?.get('sliders') || '') || sliders; + if (controls) { + controls = controls.fromURL(params?.get('controls') || '') || controls; } + isIframe = JSON.parse(params?.get('iframe') || 'false') || isIframe; if (!isIframe) { @@ -102,15 +105,15 @@ {/if} - {#if sliders?.sliders?.length > 0} - - 0} + + (isChangingSliders = true)} on:stopChanging={() => (isChangingSliders = false)} /> - + {/if} @@ -137,7 +140,7 @@
- +