A Vue3 port of the popular dat.GUI library.
This is a lightweight graphical user interface to change variables in Javascript (or Typescript). Useful for all your demos or experimental codes.
Check out the demo page.
- cyrilf/microbios: Cellular automata simulation / Github
- ...
- Feel free to submit a PR to add your website.
npm install --save @cyrilf/vue-dat-gui
Then the usage is:
import { createApp } from "vue";
import VueDatGui from "@cyrilf/vue-dat-gui";
import "@cyrilf/vue-dat-gui/dist/style.css";
/* your code */
// ...
const app = createApp(App);
app.use(VueDatGui);
app.mount("#app");
In your head tag, include the following code:
<link
rel="stylesheet"
href="https://unpkg.com/@cyrilf/vue-dat-gui@latest/dist/style.css"
/>
<script type="module" lang="ts">
import {
createApp,
computed,
ref,
} from "https://unpkg.com/vue@3/dist/vue.esm-browser.js";
import VueDatGui from "https://unpkg.com/@cyrilf/vue-dat-gui@latest/dist/vue-dat-gui.js";
createApp({
/*your code*/
})
.use(VueDatGui)
.mount("#app");
</script>
The main branch contains code for Vue3. It's refering to the tags v1.x
.
The deprecated branch vue2 is for Vue2 support. It's refering to the tags v0.x
.
You can find the README with all the required information for this version.
You can always refer to the public/index.html file for the most up-to-date example of how to use it. (keep in mind that this is a demo version using the CDN version of Vue and vue-dat-gui, so it's a bit different than the usage in your app).
The demo page is also available.
In your view:
<div class="app">
<DatGui
closeText="Close controls"
openText="Open controls"
closePosition="bottom"
>
<DatColor v-model="background" label="Background" />
<DatNumber v-model="titleFontSize" label="Title font-size" />
<DatString v-model="title" label="Title" />
<DatButton @click="triggerAlert" label="Trigger alert" />
<DatFolder label="Picture">
<DatSelect v-model="pictureUrl" :items="pictures" label="Picture" />
<DatBoolean v-model="showPicture" label="Show Picture" />
<DatFolder label="Box shadow">
<DatBoolean
v-model="boxShadow.disabled"
:label="boxShadow.disabled ? 'Enable options' : 'Disable options' "/>
<DatNumber
v-model="boxShadow.offsetX"
:min="-100"
:max="100"
:step="1"
label="Offset X"
:disabled="boxShadow.disabled"
/>
<DatNumber
v-model="boxShadow.offsetY"
:min="-100"
:max="100"
:step="1"
label="Offset Y"
:disabled="boxShadow.disabled"
/>
<DatNumber
v-model="boxShadow.blurRadius"
:min="0"
:max="100"
:step="1"
label="Blur radius"
:disabled="boxShadow.disabled"
/>
<DatNumber v-model="boxShadow.spreadRadius" label="Spread radius" :disabled="boxShadow.disabled" />
<DatColor v-model="boxShadow.color" label="Color" :disabled="boxShadow.disabled" />
</DatFolder>
</DatFolder>
</DatGui>
</div>
In your javascript:
// <script setup lang="ts">
import { computed, ref } from "vue";
const pictures = [
{
name: "forest",
value:
"https://images.unsplash.com/photo-1516214104703-d870798883c5?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80",
},
{
name: "mountain",
value:
"https://images.unsplash.com/photo-1526080676457-4544bf0ebba9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80",
},
{
name: "beach",
value:
"https://images.unsplash.com/photo-1520942702018-0862200e6873?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=750&q=80",
},
];
const background = ref("#cdeecc");
const titleColor = ref("#077d43");
const titleFontSize = ref(75);
const title = ref("vue-dat-gui");
const showPicture = ref(true);
const boxShadow = ref({
disabled: false,
offsetX: 27,
offsetY: 27,
blurRadius: 75,
spreadRadius: 2,
color: "rgba(3, 23, 6, 1)",
});
const pictureStyle = computed(() => {
const { offsetX, offsetY, blurRadius, spreadRadius, color } = boxShadow.value;
return {
"box-shadow": `${offsetX}px ${offsetY}px ${blurRadius}px ${spreadRadius}px ${color}`,
};
});
const triggerAlert = () => alert("Yeah, you pressed it!");
let pictureUrl = ref(pictures[0].value);
const nextPicture = () => {
const currentIndex = pictures.findIndex(
(picture) => picture.value === pictureUrl.value
);
const nextIndex = (currentIndex + 1) % pictures.length;
pictureUrl.value = pictures[nextIndex].value;
};
// </script>
The main menu that wraps all components. (required)
<DatGui
v-model:open="isOpen"
open-text="Open Controls"
close-text="Close Controls"
close-position="bottom"
>
<!-- other components -->
</DatGui>
Name | Type | Default | Description |
---|---|---|---|
v-model:open |
Ref<boolean> |
true |
2ways binding to the open state of the GUI |
open |
boolean |
true |
1way binding to the open state of the GUI |
@update:open |
Function |
noop |
Listener for the open change |
open-text |
boolean |
'Open controls' |
Text for the open button |
close-text |
boolean |
'Close controls' |
Text for the close button |
close-position |
'bottom' | 'top' |
'bottom' |
Position of the close button |
A checkbox element
<DatBoolean v-model="isActive" label="Is active?" />
Name | Type | Default | Description |
---|---|---|---|
v-model |
Ref<boolean> |
false |
2ways binding |
label |
string |
"" |
Text for the label |
disabled |
boolean |
false |
disabled |
A button element
<DatButton @click="onSurpriseClick" label="Surprise me!" />
Name | Type | Default | Description |
---|---|---|---|
@click |
Function |
noop |
Click handler |
label |
string |
"" |
Button text |
disabled |
boolean |
false |
disabled |
A color-picker element
<DatColor v-model="mainColor" label="Main color" />
Name | Type | Default | Description |
---|---|---|---|
v-model |
Ref<string> |
"" |
2ways binding |
label |
string |
"" |
Text for the label |
disabled |
boolean |
false |
disabled |
A folder element
<DatFolder v-model:open="isOpen" label="Optional settings">
<!-- other components -->
</DatFolder>
Name | Type | Default | Description |
---|---|---|---|
v-model:open |
Ref<boolean> |
true |
2ways binding to the open state of the GUI |
open |
boolean |
true |
1way binding to the open state of the GUI |
@update:open |
Function |
noop |
Listener for the open change |
label |
string |
"" |
Text for the folder |
A number input element. If min
and max
are specified, then a slider is added.
<DatNumber
v-model="areaWidth"
:min="0"
:max="1000"
:step="5"
:showSlider="false"
label="Area width"
/>
Name | Type | Default | Description |
---|---|---|---|
v-model |
Ref<number> |
"" |
2ways binding |
min |
number |
Number.NEGATIVE_INFINITY |
Minimum value |
max |
number |
Number.POSITIVE_INFINITY |
Maximum value |
step |
number |
Read note below* |
Incremental value |
label |
string |
"" |
Text for the label |
disabled |
boolean |
false |
disabled |
Note*
: it's the "order of magnitude of the absolute difference between max and min and returns a power of 10 corresponding to that order of magnitude".
A select element
<DatSelect v-model="mainPicture" :items="pictures" label="Main picture" />
Type Item = { name: string; value: string; } | string | number
Name | Type | Default | Description |
---|---|---|---|
v-model |
Ref<string> | Ref<number> |
"" |
2ways binding |
items |
Item[] |
[] |
The options for the select |
label |
string |
"" |
Text for the label |
disabled |
boolean |
false |
disabled |
A text input element
<DatString v-model="username" label="Username" />
Name | Type | Default | Description |
---|---|---|---|
v-model |
Ref<string> |
"" |
2ways binding |
label |
string |
"" |
Text for the label |
disabled |
boolean |
false |
disabled |
./deploy
Feel free to open any Pull Request/Issues.
- dat.GUI for the initial project