mirror of
https://github.com/eugene-serb/wavelovers.git
synced 2023-09-09 23:41:16 +03:00
- Added component and view for manual configuring and playing patterns.
- Added component NavigationList for routing over vue-router views. - Rename component WaveloversApp, now is a AppPatterns. - Rename HomeView, now is a PatternView. - Modified function vibrate in MGamepads and change function in index vuex. - Root component App now has mounted and unmounted event listeners for gamepads adding and deleteting functions. - Fixed CSS rules for inputs and input[type=range]. - Added new rules for input[type=range].
This commit is contained in:
parent
c5631603ac
commit
ebe813e7d3
@ -1,6 +1,6 @@
|
|||||||
/* ------------------------------ */
|
/* ------------------------------ */
|
||||||
/* Wavelovers styles */
|
/* Wavelovers styles */
|
||||||
/* version: dated 2022.07.25 */
|
/* version: dated 2022.08.07 */
|
||||||
/* author: Eugene Serb */
|
/* author: Eugene Serb */
|
||||||
/* ------------------------------ */
|
/* ------------------------------ */
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ fieldset {
|
|||||||
padding: 8px;
|
padding: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
button, input, textarea, select {
|
button, textarea, select, input {
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
border: 2px solid var(--color-link);
|
border: 2px solid var(--color-link);
|
||||||
border-radius: var(--number-border-radius);
|
border-radius: var(--number-border-radius);
|
||||||
@ -215,7 +215,6 @@ button, input, textarea, select {
|
|||||||
line-height: 1.382em;
|
line-height: 1.382em;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
button:hover, input:hover,
|
button:hover, input:hover,
|
||||||
textarea:hover, select:hover {
|
textarea:hover, select:hover {
|
||||||
border: 2px solid var(--color-link-hover);
|
border: 2px solid var(--color-link-hover);
|
||||||
@ -234,6 +233,114 @@ option {
|
|||||||
color: var(--color-white);
|
color: var(--color-white);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type=range] {
|
||||||
|
width: 100%;
|
||||||
|
margin: 8px 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0px solid var(--color-link);
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]:hover {
|
||||||
|
margin: 8px 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0px solid var(--color-link-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-webkit-slider-runnable-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
|
||||||
|
background: var(--color-b);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 0px solid #000101;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-webkit-slider-thumb {
|
||||||
|
box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
|
||||||
|
border: 0px solid #000000;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: var(--color-a);
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin-top: -4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]:focus::-webkit-slider-runnable-track {
|
||||||
|
background: var(--color-b);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-moz-range-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
animate: 0.2s;
|
||||||
|
box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
|
||||||
|
background: var(--color-b);
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 0px solid #000101;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-moz-range-thumb {
|
||||||
|
box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
|
||||||
|
border: 0px solid #000000;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: var(--color-a);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-track {
|
||||||
|
width: 100%;
|
||||||
|
height: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
animate: 0.2s;
|
||||||
|
background: transparent;
|
||||||
|
border-color: transparent;
|
||||||
|
border-width: 8px 0;
|
||||||
|
color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-fill-lower {
|
||||||
|
background: var(--color-b);
|
||||||
|
border: 0px solid #000101;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-fill-upper {
|
||||||
|
background: var(--color-b);
|
||||||
|
border: 0px solid #000101;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-ms-thumb {
|
||||||
|
box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
|
||||||
|
border: 0px solid #000000;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: var(--color-a);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]:focus::-ms-fill-lower {
|
||||||
|
background: var(--color-b);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]:focus::-ms-fill-upper {
|
||||||
|
background: var(--color-b);
|
||||||
|
}
|
||||||
|
|
||||||
/* ------ */
|
/* ------ */
|
||||||
/* TABLES */
|
/* TABLES */
|
||||||
/* ------ */
|
/* ------ */
|
||||||
|
41
src/App.vue
41
src/App.vue
@ -1,12 +1,53 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div class="wavelovers">
|
||||||
|
<NavigationList />
|
||||||
<router-view />
|
<router-view />
|
||||||
|
<GamepadList v-if="gamepads.length > 0"
|
||||||
|
:gamepads="gamepads" />
|
||||||
|
<MessageItem v-else>Press any gamepad button or connect a new gamepad to vibrate.</MessageItem>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import store from '@/store/index';
|
||||||
|
import NavigationList from '@/components/NavigationList.vue';
|
||||||
|
import GamepadList from '@/components/GamepadList.vue';
|
||||||
|
import MessageItem from '@/components/MessageItem.vue';
|
||||||
|
import Vibrator from '@/models/Vibrator';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'App',
|
name: 'App',
|
||||||
|
components: {
|
||||||
|
NavigationList: NavigationList,
|
||||||
|
GamepadList: GamepadList,
|
||||||
|
MessageItem: MessageItem,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
gamepads: function (): Vibrator[] {
|
||||||
|
return store.getters.gamepads as Vibrator[];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addEventListeners(): void {
|
||||||
|
window.addEventListener('gamepadconnected', (event: GamepadEvent) => store.dispatch('addGamepad', event));
|
||||||
|
window.addEventListener('gamepaddisconnected', (event: GamepadEvent) => store.dispatch('deleteGamepad', event));
|
||||||
|
},
|
||||||
|
removeEventListeners(): void {
|
||||||
|
window.removeEventListener('gamepadconnected', (event: GamepadEvent) => store.dispatch('addGamepad', event));
|
||||||
|
window.removeEventListener('gamepaddisconnected', (event: GamepadEvent) => store.dispatch('deleteGamepad', event));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.addEventListeners();
|
||||||
|
},
|
||||||
|
unmounted() {
|
||||||
|
this.removeEventListeners();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
84
src/components/AppManual.vue
Normal file
84
src/components/AppManual.vue
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<template>
|
||||||
|
<div class="content-item app-manual">
|
||||||
|
<fieldset class="manual-form">
|
||||||
|
<label class="manual-form__inputs">
|
||||||
|
<span>Start Delay (ms)</span>
|
||||||
|
<input v-model="startDelay"
|
||||||
|
type="number" placeholder="Start Delay"
|
||||||
|
min="0" max="1000" step="25" required />
|
||||||
|
</label>
|
||||||
|
<label class="manual-form__inputs">
|
||||||
|
<span>Duration (ms)</span>
|
||||||
|
<input v-model="duration"
|
||||||
|
type="number" placeholder="Duration"
|
||||||
|
min="0" max="1000" step="25" required />
|
||||||
|
</label>
|
||||||
|
<label class="manual-form__inputs">
|
||||||
|
<span>Weak Magnitude</span>
|
||||||
|
<input v-model="weakMagnitude"
|
||||||
|
type="range" placeholder="Weak Magnitude"
|
||||||
|
min="0.0" max="1.0" step="0.01" required />
|
||||||
|
</label>
|
||||||
|
<label class="manual-form__inputs">
|
||||||
|
<span>Strong Magnitude</span>
|
||||||
|
<input v-model="strongMagnitude"
|
||||||
|
type="range" placeholder="Strong Magnitude"
|
||||||
|
min="0.0" max="1.0" step="0.01" required />
|
||||||
|
</label>
|
||||||
|
<button @click="start">Start</button>
|
||||||
|
<button @click="stop">Stop</button>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import store from '@/store/index';
|
||||||
|
import TPatternUnit from '@/models/TPatternUnit';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'AppManual',
|
||||||
|
data: () => {
|
||||||
|
return {
|
||||||
|
startDelay: 250 as number,
|
||||||
|
duration: 250 as number,
|
||||||
|
weakMagnitude: 1 as number,
|
||||||
|
strongMagnitude: 1 as number,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
createPatternUnit: function (): TPatternUnit[] {
|
||||||
|
const patternUnit: TPatternUnit[] = [{
|
||||||
|
startDelay: this.startDelay,
|
||||||
|
duration: this.duration,
|
||||||
|
weakMagnitude: this.weakMagnitude,
|
||||||
|
strongMagnitude: this.strongMagnitude,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return patternUnit as TPatternUnit[];
|
||||||
|
},
|
||||||
|
start: function (): void {
|
||||||
|
store.dispatch('startCustom', this.createPatternUnit());
|
||||||
|
},
|
||||||
|
stop: function (): void {
|
||||||
|
store.dispatch('reset');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.manual-form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manual-form__inputs {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
46
src/components/AppPatterns.vue
Normal file
46
src/components/AppPatterns.vue
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<template>
|
||||||
|
<div class="app-patterns">
|
||||||
|
<PatternList v-if="patterns.length > 0"
|
||||||
|
:patterns="patterns"
|
||||||
|
:mode="mode"
|
||||||
|
:isActive="isActive"
|
||||||
|
@change="change" />
|
||||||
|
<MessageItem v-else>Loading...</MessageItem>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import store from '@/store/index';
|
||||||
|
import PatternList from '@/components/PatternList.vue';
|
||||||
|
import MessageItem from '@/components/MessageItem.vue';
|
||||||
|
import TPattern from '@/models/TPattern';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'AppPatterns',
|
||||||
|
components: {
|
||||||
|
PatternList: PatternList,
|
||||||
|
MessageItem: MessageItem,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
patterns: function (): TPattern[] {
|
||||||
|
return store.getters.patterns as TPattern[];
|
||||||
|
},
|
||||||
|
mode: function (): number {
|
||||||
|
return store.getters.mode as number;
|
||||||
|
},
|
||||||
|
isActive: function (): boolean {
|
||||||
|
return store.getters.isActive as boolean;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
change(index: number): void {
|
||||||
|
store.dispatch('change', index as number);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
store.dispatch('loadPatterns');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
32
src/components/NavigationList.vue
Normal file
32
src/components/NavigationList.vue
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<template>
|
||||||
|
<div class="content-item navigation-list">
|
||||||
|
<router-link to="/manual" class="navigation-item">Manual</router-link>
|
||||||
|
<router-link to="/" class="navigation-item">Patterns</router-link>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'NavigationList',
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.navigation-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-start;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navigation-item.router-link-active,
|
||||||
|
.navigation-item.router-link-exact-active {
|
||||||
|
border-bottom: 2px solid var(--color-link-hover);
|
||||||
|
color: var(--color-link-hover);
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -52,7 +52,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
cursor: default;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media only screen and (min-width: 540px) {
|
@media only screen and (min-width: 540px) {
|
||||||
|
@ -1,82 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="wavelovers">
|
|
||||||
<PatternList v-if="patterns.length > 0"
|
|
||||||
:patterns="patterns"
|
|
||||||
:mode="mode"
|
|
||||||
:isActive="isActive"
|
|
||||||
@change="change" />
|
|
||||||
<MessageItem v-else>Loading...</MessageItem>
|
|
||||||
<GamepadList v-if="gamepads.length > 0"
|
|
||||||
:gamepads="gamepads" />
|
|
||||||
<MessageItem v-else>Press any gamepad button or connect a new gamepad to vibrate.</MessageItem>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { defineComponent } from 'vue';
|
|
||||||
import PatternList from '@/components/PatternList.vue';
|
|
||||||
import GamepadList from '@/components/GamepadList.vue';
|
|
||||||
import MessageItem from '@/components/MessageItem.vue';
|
|
||||||
import TPattern from '@/models/TPattern';
|
|
||||||
import Vibrator from '@/models/Vibrator';
|
|
||||||
import store from '@/store/index';
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'WaveloversApp',
|
|
||||||
components: {
|
|
||||||
PatternList: PatternList,
|
|
||||||
GamepadList: GamepadList,
|
|
||||||
MessageItem: MessageItem,
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
gamepads: function (): Vibrator[] {
|
|
||||||
return store.getters.gamepads as Vibrator[];
|
|
||||||
},
|
|
||||||
patterns: function (): TPattern[] {
|
|
||||||
return store.getters.patterns as TPattern[];
|
|
||||||
},
|
|
||||||
mode: function (): number {
|
|
||||||
return store.getters.mode as number;
|
|
||||||
},
|
|
||||||
isActive: function (): boolean {
|
|
||||||
return store.getters.isActive as boolean;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
addEventListeners(): void {
|
|
||||||
window.addEventListener('gamepadconnected', (event: GamepadEvent) => store.dispatch('addGamepad', event));
|
|
||||||
window.addEventListener('gamepaddisconnected', (event: GamepadEvent) => store.dispatch('deleteGamepad', event));
|
|
||||||
},
|
|
||||||
removeEventListeners(): void {
|
|
||||||
window.removeEventListener('gamepadconnected', (event: GamepadEvent) => store.dispatch('addGamepad', event));
|
|
||||||
window.removeEventListener('gamepaddisconnected', (event: GamepadEvent) => store.dispatch('deleteGamepad', event));
|
|
||||||
},
|
|
||||||
change(index: number): void {
|
|
||||||
store.dispatch('change', index as number);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
store.dispatch('loadPatterns');
|
|
||||||
this.addEventListeners();
|
|
||||||
},
|
|
||||||
unmounted() {
|
|
||||||
this.removeEventListeners();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.wavelovers {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column-reverse;
|
|
||||||
justify-content: flex-start;
|
|
||||||
gap: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (min-width: 540px) {
|
|
||||||
.wavelovers {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,11 +1,17 @@
|
|||||||
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
|
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';
|
||||||
import HomeView from '@/views/HomeView.vue';
|
import PatternsView from '@/views/PatternsView.vue';
|
||||||
|
import ManualView from '@/views/ManualView.vue';
|
||||||
|
|
||||||
const routes: Array<RouteRecordRaw> = [
|
const routes: Array<RouteRecordRaw> = [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
name: 'home',
|
name: 'patterns-view',
|
||||||
component: HomeView,
|
component: PatternsView,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/manual',
|
||||||
|
name: 'manual-view',
|
||||||
|
component: ManualView,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import { createStore, Store } from 'vuex';
|
|||||||
import IRootState from './models/IRootState';
|
import IRootState from './models/IRootState';
|
||||||
import MGamepads from '@/store/modules/MGamepads';
|
import MGamepads from '@/store/modules/MGamepads';
|
||||||
import MPatterns from '@/store/modules/MPatterns';
|
import MPatterns from '@/store/modules/MPatterns';
|
||||||
|
import TPatternUnit from '../models/TPatternUnit';
|
||||||
|
|
||||||
const store: Store<IRootState> = createStore({
|
const store: Store<IRootState> = createStore({
|
||||||
state: () => ({
|
state: () => ({
|
||||||
@ -46,11 +47,20 @@ const store: Store<IRootState> = createStore({
|
|||||||
}
|
}
|
||||||
if (context.getters.isActive === true) {
|
if (context.getters.isActive === true) {
|
||||||
context.dispatch('reset');
|
context.dispatch('reset');
|
||||||
context.dispatch('vibrate');
|
context.dispatch(
|
||||||
|
'vibrate',
|
||||||
|
context.getters.patterns[context.getters.mode].pattern
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
context.dispatch('reset');
|
context.dispatch('reset');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
startCustom: function (context, pattern: TPatternUnit[]): void {
|
||||||
|
context.dispatch('setIsActive', false);
|
||||||
|
context.dispatch('setMode', 0);
|
||||||
|
context.dispatch('reset');
|
||||||
|
context.dispatch('vibrate', pattern);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
modules: {
|
modules: {
|
||||||
MGamepads: MGamepads,
|
MGamepads: MGamepads,
|
||||||
|
@ -46,10 +46,11 @@ const MGamepads: Module<IGamepadsState, IRootState> = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
vibrate: function (
|
vibrate: function (
|
||||||
context: ActionContext<IGamepadsState, IRootState>
|
context: ActionContext<IGamepadsState, IRootState>,
|
||||||
|
pattern: TPatternUnit[]
|
||||||
): void {
|
): void {
|
||||||
context.getters.gamepads.forEach((gamepad: Vibrator) => {
|
context.getters.gamepads.forEach((gamepad: Vibrator) => {
|
||||||
gamepad.vibrate(context.getters.patterns[context.getters.mode].pattern as TPatternUnit[]);
|
gamepad.vibrate(pattern);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
reset: function (
|
reset: function (
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<WaveloversApp />
|
<AppManual />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import WaveloversApp from '@/components/WaveloversApp.vue';
|
import AppManual from '@/components/AppManual.vue';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'HomeView',
|
name: 'ManualView',
|
||||||
components: {
|
components: {
|
||||||
WaveloversApp: WaveloversApp,
|
AppManual: AppManual,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
16
src/views/PatternsView.vue
Normal file
16
src/views/PatternsView.vue
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<template>
|
||||||
|
<AppPatterns />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import AppPatterns from '@/components/AppPatterns.vue';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'PatternsView',
|
||||||
|
components: {
|
||||||
|
AppPatterns: AppPatterns,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user