GithubHelp home page GithubHelp logo

cocopon / tweakpane Goto Github PK

View Code? Open in Web Editor NEW
3.3K 28.0 80.0 4.31 MB

:control_knobs: Compact GUI for fine-tuning parameters and monitoring value changes

Home Page: https://tweakpane.github.io/docs/

License: MIT License

JavaScript 1.06% TypeScript 91.74% SCSS 7.15% HTML 0.05%
tweaks gui creative-coding zero-dependency tweakpane

tweakpane's Introduction

Tweakpane

CI Coverage Status npm version

cover

Tweakpane is a compact pane library for fine-tuning parameters and monitoring value changes, inspired by dat.GUI.

  • Clean and simple design
  • Dependency-free
  • Extensible

(dat.GUI user? The migration guide can be helpful)

Installation

Refer to the Getting Started section for concrete steps. Remember to install @tweakpane/core if you are developing with TypeScript.

Features

See the official page for details.

Number, String, Boolean, Color, Point 2D/3D/4D

Bindings

Number, String, Boolean

Readonly bindings

Folder, Tab, Button, Separator

UI components

Theming

Plugins

  • Mobile support
  • TypeScript type definitions
  • JSON import / export

Development

CommonJS and ES modules

From version 4, Tweakpane has been migrated to ES modules. If you are looking for a CommonJS version of the package, use version 3.x.

Build your own Tweakpane

$ npm install
$ npm run setup
$ cd packages/tweakpane
$ npm start

The above commands start a web server for the document, build source files, and watch for changes. Open http://localhost:8080/ to browse the document.

Other resources

Includes the basics, styles and components for Tweakpane, providing a practical resource for creating your own plugin.

image

License

MIT License. See LICENSE.txt for more information.

tweakpane's People

Contributors

cocopon avatar kitschpatrol avatar williammanco-aq avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tweakpane's Issues

Folder doesn't resize after disposing child/input

Hi,
When I dispose some elements, they will disappear and the other items below it shift up and it is fine. But the height of the pane won't be updated so there will be an empty space at the end of the pane in a folder.

Untitled-2

ButtonAPI.on returns void instead of this

Hey, the ButtonAPI.on function returns void instead of ButtonAPI which is different from all the others.

this.box = pane.addInput(this, 'test').on('change', () =>
{
   // do something
});

this.button = pane.addButton();
this.button.on('click', () =>
{
    // do something
});

Update list for string list

A dynamic nature of application requires to change string list parameters at some time moments. I examined ListInputView and found that it fills select DOM element with option elements during construction. May you please recommend me some way for changing those option elements after construction?

Point 2D - y inverted?

I've noticed on the Point 2D input when you expand the pad that the y appears to be inverted. Not sure if this is intended?

I would expect the upper right quadrant of the pad to be +v.e for both x and y.

I tried reversing my min and max (and step) but this doesn't work.

I've attached an image
tweakpane_1

Chris

export presets using folders

It seems like folders should be included in preset export. This would help remove the need for hacks like presetKey. For example, given two folders obj1 and obj2 an exported preset might look like:

{
  obj1: {
    x:0,
    y:0,
    z:0
  },
  obj2: {
    x:1,
    y:1,
    z:0
  }
}

UI refresh() is unusually expensive

Currently performing pane.refresh() is taking upwards of 120ms to complete and triggers various layout shifts. Is there a way to update ui input values that have been changed in a script without causing this expensive reflow? For example only updating the components whos values have changed?

image

Also moving the colour picker also seems to be a very expensive operation and causes the animation loop to start juddering. This harms the user experience somewhat when working with realtime graphical applications.

Again thanks for the awesome framework, it's been incredibly useful so far. I wish I could help iron out these performance issues but I am a native / graphics developer and do not have much experience with browser processes etc.

(Ps. you should add a donate button to your site)

onTitleClick_ implementation

Hi again,

Is there any way to properly add an event listener to the folder title when the user expand or collapse? Something like the followings when creating a new folder:

myFolder= myPanel.addFolder({ title: 'Some title!' }).on('click', (thisFolder) => { console.log("The title of thisFolder is clicked"); }) ;

I know that there is a "onTitleClick_" event for the folder titles that is used internally in the code. But I do not know how to modify it properly. I tried the followings, which did not work:

myFolder.controller.onTitleClick_ = function() { FLDR_SP.controller.onTitleClick_() ; myFcn(); }

However, the following hack does the trick:

myFolder.controller.view.element.addEventListener("click",myFcn)

Is there a better an cleaner way to do this? somehow taking advantage of onTitleClick_ ?

3D Vector input

Hey! As you know we started using tweakpane a lot with react-three-fiber & threejs, so it's coming up that a vector3 type input would be extremely useful. I'll add some of my ideas:

  • we could use the xy input and add a slider for z underneath like the RGB/color picker
    image

  • we could let the user choose any pair of xyz axes to manipulate with the Pad - not sure about the UI here. This would more easily allow for any vector dimension

Multiline label

Also, thinking about labels with more than one line like: "label line1<\br> label line2". Maybe some enhancements can be useful here.
#46 (comment)

First argument of change event handler for color property is useless

const pane = new Tweakpane();
const params = {
  color: '#000',
};

pane.addInput(params, 'color').on('change', (firstArg) => {
  console.log(firstArg);
});

Console:

{
  comps_: [0, 32.35294117647059, 56.25],
  emitter: {
    observers_: { ... }
  },
  mode_: "hsv"
}

Currently firstArg is an instance of internal Color class and it's not useful in any case. It should be the property value itself or an instance of some useful class.

Theming with CSS3 vars

Great project! I Would you be open to receive a pull request for an idea I had, to use CSS3 vars to theme tweakpane? I often want to adapt the panes in by projects.

should config include expanded option

Hi,

Just playing with TweakPane, really like it. I can see that folders have an 'expanded' property which can be set on construction but the main pane doesn't. Although I can set the pane expansion programatically afterwards, it would seem logical to also offer this during construction, in the config object, like folders. Also the hidden property would also be suited to be available in the config.

Just an idea!

Example for options text (i18n)

Very minor!

I couldn't find anything in the documentation about localizing tweakmenu text - particularly in selections. After digging around the code and I bit of trial and error I found you could like this!

tweakpane.addInput(menu, 'value', {label:'Shape'
,options: [
{value: 'rectangle', text: 'Rectangle'}
,{value: 'circle', text: 'Circle'}
]
});

Chris

Log scale for numeric ranges

Great library!

Would it be possible to add an option for numeric ranges to use a log scale? That is, something like:

PARAMS.frequency = 440
pane.addInput(PARAMS, 'frequency', {
  min: 100,
  max: 10000,
  logScale: true,
});

And then in the above example, the middle of the slider would correspond to 1000 rather than 5050.

Thanks for considering!


Note for anyone else needing this: I'm currently hacking in this functionality by overwriting the input's formatter, thusly:

var min = 100
var max = 10000
PARAMS.frequency = 440

PARAMS.logFrequency = Math.log10(PARAMS.frequency)
var input = pane.addInput(PARAMS, 'logFrequency', {
    label: 'frequency',
    min: Math.log10(min),
    max: Math.log10(max),
})

// make the text label show the non-log scale value
var formatter = (v) => Math.pow(10, v) | 0
input.controller.controller.view_.textInputView_.formatter_.format = formatter

// to initialize the formatted display
PARAMS.logFrequency *= 1.00001
input.refresh()

// the actual param we want
input.on('change', v => { PARAMS.frequency = formatter(v) })

But obviously real support would be better.

Ability to change min/max/step etc at Runtime

Hi,

I'm confused by this one. I don't know how to update any config of the config parameters at runtime.

For example:

Create a point 2D menu
config = {label:'Center',x: {min: -100, max: 100, step:0.1 },y: {min: -100, max: 100, step:0.1 }};
tweakpane.addInput(menu, 'value', config);

If I then change config sometime later (because the user has changed a container size for example)
config.x.min = -10
tweakpane.refresh();

The min/max values are not updated. Not sure how to even hack this one?

Chris

Moveable/Floating Panes

Hey I've been looking for something like this! Great work!

I had a question/possible enhancement. With IMGUI you can move the panes around freely and dock them. Do you have the ability to move the panes around right now? If not I would love to help add that!

Date/Time input components

Currently, I use string input and manually check/convert them to JavaScript date/time. As an enhancement, considering input components for Date and Time can be also useful for lots of applications.

MIDI Support

Hello! This project is amazing. As a dat.gui superfan I'm very surprised I haven't stumbled across this before.

I maintain a library for personal use - https://www.npmjs.com/package/@malven/gui - that is essentially just an abstraction on top of dat.gui that mostly just provides effortless, near automatic support for MIDI controllers. I use a MIDI knob controller that I find makes it way more intuitive, interactive, and fun to tweak parameter values.

I'd love to experiment with doing something similar for tweakpane, but I'd ideally like to avoid going down the route of creating another abstraction on top of tweakpane and instead build a more "official" connection.

I see you have official plugin support on the roadmap, but I'd totally understand if that's months/years away from being a priority for you.

Short of an official plugin, do you have any recommendations for how you would go about this? Not looking for specific implementation details or anything, just a high level nudge in the right direction. Thanks!

.on events have no 'this' defined

I noticed when binding to an 'on' event that 'this' is undefined when the handler is called.

For example:
tweakpane.addInput(menu, 'value', someconfig)
.on('change', myfunction);

where
myfunction(value) {
//doing something here
//but 'this' undefined unless you explicitly call 'bind' on the handler function
}

Should 'this' be set to the input interface instance?

Chris

Insert input/monitor in a specific order

Hi,
It will be great to have an option for adding input/monitor in the pane/folder in a specific order, not at the end of all elements.
Currently, when adding items with for example ".addInput()" or ".addButton()", the item will be placed at the end of the pane. How if it is possible to place an item in a specific index in the pane? The reason is, after creating the pane, in some applications, it may be necessary to delete (dispose()) some of the elements and substitute them with some new inputs, so it is required to place the item exactly on the position it was deleted, not at the end of the pane.

Is there any hide/show functionality

I really like your plugin. Used datgui and controlkit but this seems cleaner.

Is there any way to hide/show an element? For example I might make a selection that should then hide/show a number of other buttons/inputs?

Picker Toggle UX Issue

Hi, great work on this library, its been a joy to use so far.

Just wanted to mention a minor UX issue that when toggling a colour picker or point2D panel the intuition is that you can close the panel by clicking on the button that opened it (the colour square for colour or + sign for the 2D panel). I'm using this library to expose some design options to a client and want them to have as smooth an experience as possible. It took me a few clicks to realise how to close these panels and sure they will too as it is not obvious that you have to click outside the panel (but not on the button that opened it).

As a side note it would be great to be able to increase the width of the default panel from the js side. At the moment my variable names are all bunched up due to the fixed (quite small) size. Any suggestions for where I can change this in style etc would be helpful.

Thanks again for the great work!

Disabled input

Is it possible to disable text or number input?
It would be very useful to create read-only fields, and to enable/disable them as needed.
Maybe via InputParamsOption with optional "enabled" flag?

Adding support for various color notations

Currently output of a color property is only string (#112233) but it would be nice if Tweakpane supports other style of colors (e.g. 0x112233, [11, 22, 33], {r: 11, g: 22, b: 33}, ...)

'getter' functions

Hi,

Sorry for yet another comment. This is an ease of use thing/enhancement suggestion.

When setting up my menu items I can specify properties such as min/max step etc like this

tweakpane.addInput(menu, 'value', x: {min:0, max: 100, step:0.1});

I don't think I can specify javascript getter functions

tweakpane.addInput(menu, 'value', x: {min:mymingetterfn, max: mymaxgetterfn, step:mystepfn});

This means I have to set up a javascript object for the menu. When changes occur in my interface copy these into the menu javascript object and call tweakpane.refresh. If functions were permitted, I could just call tweakpane.refresh?

Taking this further, I assume that 'value' could also be replaced optionally with a function? So the interface would look like:

tweakpane.addInput(contextobject, 'value'/fn, x: {min:value/fn, max: value/fn, step:value/fn});

Chris

Disable or declare programmatically input type

Hi,
Is it possible to disable an input type or declare programmatically it?
For example, I don't want to use point2D for an object that contains x and y properties but I want to use the slider to change these values.

Thank you very much for your works. It is very useful!

Point 2D - key support

Hi,

I'm using the Point 2D input to position an object. If you click in either the X or Y fields this allows the up/down arrows to be used to change the values - great.

If I expand the 2D pad, I can only change the position by clicking on the pad. It would be great if I could use the arrow keys to move the position on the pad.

Would this be possible?

If not, is there any way to bind to a keypress event for a particular item on Tweakpane so that I could do this myself?

Thanks,

Chris

Panes do not scroll when params exceed window height.

Hi.

I've come across this issue where you cannot reach certain parameters if the ui exceeds the window height.

I tried to solve this in the parent container using overflow-y: auto; but still the only way to reach the bottom parameters was to collapse parent folders above. Even adding many separate TweakPane instances to a div container with overflow enabled doesnt seem to allow scrolling to reach them.

Is there a simple way to fix this using custom css for tweakpane or is it something that needs to happen in the library its self?

I'm not a css expert so apologies if this is trivial. Thanks in advance.

Unwanted hue changing with color picker

Steps:

  1. Add a color input
  2. Click a swatch and show its color picker
  3. Pick white (or black) color with a SV palette
  4. It will cause unwanted hue changing of H palette

Retrieving color picker value as RGB

I'm having a little difficulty figuring out how to retrieve the RGB component values of a color picker. When I use the following code, the value of the comps_ array in my value var always seems to be in HSV:

renderingFolder
  .addInput(parameterValues.gradientColors, 'color1RGB', { label: 'Color 1' })
  .on('change', (value) => {
    console.log(value);
});

Where parameterValues.gradientColors.color1RGB = {r:255, g:0, b:0}.

In issue #18 I see that support was added in release 1.2.0 for different output formats based on an input config variable, but for me the mode stays as hsv when I use input: 'color.rgb' (shown below). Is there maybe something small that I'm missing?

[...].addInput(..., 'color1RGB', { label: 'Color 1', input: 'color.rgb' })

Result:

Color: {
  comps_: [array],
  mode: "hsv",
  mode_: "hsv"
}

(btw, loving this library so far! You've done an epic job with the architecture of this thing!)

Adjusting the width of pane/label column

Currently, two classes control the width of the pane and the column width of the labels: "tp-dfwv" and "tp-lblv_v"

scr1

By default they are 256px and 160px. However, when user adds some long labels, they do not fit and it makes the pane looks ugly.

scr2

To solve this problem, it is necessary to manually modify these two classes in the main file according to the length of the labels which are used. In my case, I changed 256px to 300px and 160px to 130px to fix the problem.

As a recommendation, it will be great if the user can also control these width when creating the pane. Or there can be a trigger to dynamically adjust the with according to the length of the labels.

Also, thinking about labels with more than one line like: "label line1<\br> label line2". Maybe some enhancements can be useful here.

Style Specificity

Hi,

I have been trying to incorporate Tweakpane into a site. I am having difficultly with styling. In particular, the site I'm working with has existing styles that use selectors such as

button:not(.toggle)

This sets the background colour and button padding amongst other things. This overrides the Tweakpane styling (as far as I can tell) because this selector has a higher css 'weight' or specificity.

Have you got any suggestions for how I can get around this?

Thanks,

Chris

How to use tweakpane

I want to write an article about this on LogRocket blog, How do I use it. I followed the get started page.

  1. Added a Script tag to my html file.
  2. Created a new new TweakPane()
  3. Added some configurations as specified in the Page

After all this, I preview the HTML file and nothing displayed. Please how do i use this TweakPane library?

Steppers don't work properly when panel is zoomed

I use zoom: 1.5 for root div because otherwise panel is too small for my liking.
But the issue is that steppers don't work properly when panel is zoomed.
By stepper I mean input defined with options { step: 1, min: 1, max: 100 }

Thank you for a great library. It is great aesthetic alternative for dat.gui

Only update Monitor on demand - feature request

Hi, I like the monitor control but I am finding that important data is either being missed due to sampling rate or it's scrolled off. What would help and provide additional functionality would be a way to change the sampling mode from auto to on-demand.

Maybe there is an official way I didn't notice, but have found I can do this in a hacky way, as follows:

  1. set interval to 0 in monitor config
  2. add values eg, pm.controller.controller.value.append(0.1)

Would adding an append member function to the MonitorBindingApi, to allow official usage in this way be possible?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.