Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add TypeScript support #18

Open
wants to merge 12 commits into
base: dev
Choose a base branch
from

Conversation

FabienMotte
Copy link

@FabienMotte FabienMotte commented Sep 5, 2022

Summary

This PR adds TypeScript support for Fragment sketches.

Since Fragment uses Vite behind the scenes (which already supports TypeScript transpilation via esbuild), TypeScript support is pretty straightforward to add.

Result

  • The CLI now accepts sketch files with a .ts extension, for example: fragment ./sketch.ts --new.
  • Templates are available in TypeScript version, you just need to add -ts at the end of the template name: fragment ./sketch.ts --new --template=2d-ts.
  • tsconfig.json file is created automatically for you with the right paths when you create a new sketch based on a TypeScript template.
  • All sketch exports are typed and can be imported from @fragment/types. You just need to pass your current sketch rendering as a generic to lifecycle functions to have the proper types, for example: Init<"2d">.
  • Props are also typed thanks to a helper function typedProps.
  • TypeScript modules have been added for GLSL files (.glsl, .vs, .fs, .vert, and .frag).

Demo

typescript-demo.mov

Code sample

import { onControlChange } from "@fragment/triggers";
import { typedProps } from "@fragment/types/helpers";
import type {
  Init,
  Update,
  Resize,
  FilenamePattern,
  Name,
  Fps,
  Duration,
  Rendering,
} from "@fragment/types";

export let props = typedProps({
  number: {
    value: 50,
    hidden: false,
    onChange({ value }) {
      console.log(value);
    },
    params: {
      min: 0,
      max: 100,
      step: 0.1,
    },
  },
});

export let init: Init<"2d"> = ({ context, width, height }) => {
  onControlChange(18, (event) => {
    props.number.value = event.value * 100;
  });
};

export let update: Update<"2d"> = ({ canvas, context, width, height }) => {
  context.clearRect(0, 0, canvas.width, canvas.height);
  context.beginPath();
  context.arc(width * 0.5, height * 0.5, props.number.value, 0, Math.PI * 2);
  context.fillStyle = "red";
  context.fill();
};

export let resize: Resize<"2d"> = ({ context, canvas, width, height }) => {
  context.clearRect(0, 0, canvas.width, canvas.height);
};

export let rendering: Rendering = "2d";
export let duration: Duration = 1;
export let fps: Fps = 60;
export let name: Name = "test";
export let filenamePattern: FilenamePattern = ({ filename, suffix }) =>
  `${filename}.${suffix}`;

@FabienMotte FabienMotte changed the base branch from main to dev September 6, 2022 08:13
@FabienMotte FabienMotte marked this pull request as ready for review September 6, 2022 10:14
@raphaelameaume raphaelameaume added the enhancement New feature or request label Sep 6, 2022
@raphaelameaume
Copy link
Owner

Thanks for this detailed PR @FabienMotte!

There's a few changes I'd like to request and I also have a few questions since I have very little experience with Typescript:

  • In the CLI docs, I find it a bit confusing to have both example with and without typescript following each other.
    I'd rather have two <code> block, the first one left untouched and a second one with just a subtitle With typescript. It seems to me that beginners could misunderstand the command to type if you have no knowledge of what typescript is. If that's the case, you can just ignore the second block and focus on the first command.

  • Are type Duration, type Fps and type Name really needed ? I find it a bit confusing not to have just number or string in the templates. These are primitive data types, I'm wondering what the need for a additional layer here ?

  • Looking at package.json, I see that three and p5 are hosting their @types outside of the repository. Could it be done easily ? What's the pros and cons of that ?

And thanks for spotting the filename pattern issue in the docs where suffix was renamed timestamp, the docs were indeed not up to date!

@raphaelameaume
Copy link
Owner

I merged some changes into dev which makes some types obsolete already, sorry 😄

  • "vec2" and "vec3" do not exist anymore, in favor of a generic vec fieldType. It also supports 4 dimensions vectors now, see Fix VectorInput behaviour #19 for details
  • ColorInput supports new kinds of values for hsl and also objects with r, g, b and optionnally a keys. See Fix ColorInput behaviour #20 for details

I also noticed that options seems to be missing in params types as I get an error when trying to create a select GUI by passing options to params.

Capture d’écran, le 2022-09-07 à 15 09 56

@FabienMotte
Copy link
Author

  • In the CLI docs, I find it a bit confusing to have both example with and without typescript following each other.
    I'd rather have two <code> block, the first one left untouched and a second one with just a subtitle With typescript. It seems to me that beginners could misunderstand the command to type if you have no knowledge of what typescript is. If that's the case, you can just ignore the second block and focus on the first command.

I updated the docs to make the separation clearer between JS and TS. Don't hesitate to put yourself as a reviewer and ask for a change if that's not what you had in mind.

  • Are type Duration, type Fps and type Name really needed ? I find it a bit confusing not to have just number or string in the templates. These are primitive data types, I'm wondering what the need for a additional layer here ?

I removed those types, indeed, they are unnecessary.

  • Looking at package.json, I see that three and p5 are hosting their @types outside of the repository. Could it be done easily ? What's the pros and cons of that ?

I guess the answer is yes and would make more sense since Fragment is a JavaScript library. The typing should live on https://github.com/DefinitelyTyped/DefinitelyTyped as Three.js or p5.js are doing. I never published a package on this repo, so I would need to see how this can be done.

I merged some changes into dev which makes some types obsolete already, sorry 😄

No worries, I'll update those accordingly.

I also noticed that options seems to be missing in params types as I get an error when trying to create a select GUI by passing options to params.

Oops, good catch, totally forgot to include this type in the Prop union!

Thank you for your comments!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants