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