From f17dcd3346c6e22f4a2de0b6c743941b6d06f5d0 Mon Sep 17 00:00:00 2001 From: Eugene Serb <46799701+eugene-serb@users.noreply.github.com> Date: Thu, 21 Jul 2022 17:22:33 +0300 Subject: [PATCH] Decomposited global imports, fixed warnings, updates --- README.md | 2 +- docs/README.md | 2 +- docs/index.html | 2 +- docs/js/app.5a72835e.js | 2 -- docs/js/app.5a72835e.js.map | 1 - docs/js/app.65320b71.js | 2 ++ docs/js/app.65320b71.js.map | 1 + package.json | 1 + public/README.md | 2 +- src/components/Vibrator.d.ts | 1 - src/components/WaveloversApp.vue | 25 ++++++++------- src/main.ts | 6 ++-- src/models/IGamepad.ts | 10 ++++++ src/models/IGamepadEvent.ts | 6 ++++ src/models/IVibrationActuator.ts | 8 +++++ src/models/IVibrator.ts | 15 +++++++++ src/models/TPattern.ts | 9 ++++++ src/models/TPatternUnit.ts | 7 ++++ src/{components => models}/Vibrator.ts | 44 ++++---------------------- src/shims-vue.d.ts | 8 ++--- 20 files changed, 89 insertions(+), 65 deletions(-) delete mode 100644 docs/js/app.5a72835e.js delete mode 100644 docs/js/app.5a72835e.js.map create mode 100644 docs/js/app.65320b71.js create mode 100644 docs/js/app.65320b71.js.map delete mode 100644 src/components/Vibrator.d.ts create mode 100644 src/models/IGamepad.ts create mode 100644 src/models/IGamepadEvent.ts create mode 100644 src/models/IVibrationActuator.ts create mode 100644 src/models/IVibrator.ts create mode 100644 src/models/TPattern.ts create mode 100644 src/models/TPatternUnit.ts rename src/{components => models}/Vibrator.ts (60%) diff --git a/README.md b/README.md index fd7d1c4..0794102 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Wavelovers -Wavelovers in ***VueJS***, ***Typescript***, ***Javascript***, ***HTML*** and ***CSS*** **[[rep](https://github.com/eugene-serb/wavelovers/), [site](https://wavelovers.ru/)]**. +Wavelovers in ***VueJS***, ***Typescript***, ***Javascript***, ***HTML***, ***CSS*** and ***SCSS*** **[[rep](https://github.com/eugene-serb/wavelovers/), [site](https://wavelovers.ru/)]**. This is Wavelovers, which can make a vibrating massager out of a gamepad. It has 16 free vibration patterns to play with. diff --git a/docs/README.md b/docs/README.md index fd7d1c4..0794102 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,5 @@ # Wavelovers -Wavelovers in ***VueJS***, ***Typescript***, ***Javascript***, ***HTML*** and ***CSS*** **[[rep](https://github.com/eugene-serb/wavelovers/), [site](https://wavelovers.ru/)]**. +Wavelovers in ***VueJS***, ***Typescript***, ***Javascript***, ***HTML***, ***CSS*** and ***SCSS*** **[[rep](https://github.com/eugene-serb/wavelovers/), [site](https://wavelovers.ru/)]**. This is Wavelovers, which can make a vibrating massager out of a gamepad. It has 16 free vibration patterns to play with. diff --git a/docs/index.html b/docs/index.html index 9e25039..2fa257a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -15,4 +15,4 @@ trackLinks: true, accurateTrackBounce: true, webvisor: true - });

Wavelovers

\ No newline at end of file + });

Wavelovers

\ No newline at end of file diff --git a/docs/js/app.5a72835e.js b/docs/js/app.5a72835e.js deleted file mode 100644 index 6c8e3c6..0000000 --- a/docs/js/app.5a72835e.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(){"use strict";var t={2466:function(t,e,n){var a=n(9242),i=n(3396);function s(t,e,n,a,s,r){const o=(0,i.up)("WaveloversApp");return(0,i.wg)(),(0,i.j4)(o)}const r={class:"wavelovers"},o=(0,i.Uk)("Loading..."),c=(0,i.Uk)("Press any gamepad's button or connect new gamepad.");function d(t,e,n,a,s,d){const p=(0,i.up)("PatternList"),u=(0,i.up)("MessageItem"),h=(0,i.up)("GamepadList");return(0,i.wg)(),(0,i.iD)("div",r,[t.patterns.length>0?((0,i.wg)(),(0,i.j4)(p,{key:0,patterns:t.patterns,mode:t.mode,isActive:t.isActive,onChange:t.change},null,8,["patterns","mode","isActive","onChange"])):((0,i.wg)(),(0,i.j4)(u,{key:1},{default:(0,i.w5)((()=>[o])),_:1})),t.gamepads.length>0?((0,i.wg)(),(0,i.j4)(h,{key:2,gamepads:t.gamepads},null,8,["gamepads"])):((0,i.wg)(),(0,i.j4)(u,{key:3},{default:(0,i.w5)((()=>[c])),_:1}))])}const p={class:"pattern-list"};function u(t,e,n,a,s,r){const o=(0,i.up)("PatternItem");return(0,i.wg)(),(0,i.iD)("div",p,[((0,i.wg)(!0),(0,i.iD)(i.HY,null,(0,i.Ko)(t.patterns,((e,n)=>((0,i.wg)(),(0,i.j4)(o,{key:e.name,pattern:e,index:n,mode:t.mode,isActive:t.isActive,onChange:t.change},null,8,["pattern","index","mode","isActive","onChange"])))),128))])}var h=n(7139);const l=["textContent"],m=["textContent"];function v(t,e,n,a,s,r){return(0,i.wg)(),(0,i.iD)("div",{onClick:e[0]||(e[0]=e=>t.change(t.index)),class:(0,h.C_)(["pattern-item",t.index===t.mode&&!0===t.isActive?"pattern-item_selected":""])},[(0,i._)("span",{class:"pattern-item__icon",textContent:(0,h.zw)(t.pattern.icon)},null,8,l),(0,i._)("span",{class:"pattern-item__name",textContent:(0,h.zw)(t.pattern.name)},null,8,m)],2)}var g=(0,i.aZ)({name:"PatternItem",props:{pattern:{type:Object},index:{type:Number},mode:{type:Number},isActive:{type:Boolean}},methods:{change(t){this.$emit("change",t)}}}),f=n(89);const w=(0,f.Z)(g,[["render",v]]);var b=w,y=(0,i.aZ)({name:"PatternList",props:{patterns:{type:Array},mode:{type:Number},isActive:{type:Boolean}},components:{PatternItem:b},methods:{change(t){this.$emit("change",t)}}});const A=(0,f.Z)(y,[["render",u]]);var Z=A;const j={class:"device-list"};function x(t,e,n,a,s,r){const o=(0,i.up)("GamepadItem");return(0,i.wg)(),(0,i.iD)("div",j,[((0,i.wg)(!0),(0,i.iD)(i.HY,null,(0,i.Ko)(t.gamepads,(t=>((0,i.wg)(),(0,i.j4)(o,{key:t.id,textContent:(0,h.zw)(t.unit.id)},null,8,["textContent"])))),128))])}const k={class:"list-item"};function C(t,e,n,a,s,r){return(0,i.wg)(),(0,i.iD)("div",k)}var _=(0,i.aZ)({name:"GamepadItem"});const O=(0,f.Z)(_,[["render",C]]);var P=O,G=(0,i.aZ)({name:"GamepadList",props:{gamepads:{type:Array}},components:{GamepadItem:P}});const I=(0,f.Z)(G,[["render",x]]);var L=I;const D={class:"message"};function E(t,e,n,a,s,r){return(0,i.wg)(),(0,i.iD)("div",D,[(0,i._)("span",null,[(0,i.WI)(t.$slots,"default")])])}var V=(0,i.aZ)({name:"MessageItem"});const M=(0,f.Z)(V,[["render",E]]);var W=M,z=n(2482);class N{constructor(t){(0,z.Z)(this,"id",void 0),(0,z.Z)(this,"canVibrate",void 0),(0,z.Z)(this,"isVibrating",void 0),(0,z.Z)(this,"unit",void 0),(0,z.Z)(this,"pattern",void 0),this.unit=t,this.id=Date.now(),this.canVibrate=!!this.unit.vibrationActuator,this.isVibrating=!1,this.pattern=[]}update(){const t=navigator.getGamepads();this.unit=t[this.unit.index]}reset(){this.isVibrating=!1,this.unit.vibrationActuator.reset()}async vibrate(t){this.isVibrating=!0,this.pattern=t;while(!0===this.isVibrating)for(let t=0;tsetTimeout(e,t)))}}var T=(0,i.aZ)({name:"WaveloversApp",components:{PatternList:Z,GamepadList:L,MessageItem:W},data:()=>({gamepads:[],patterns:[],isActive:!1,mode:0}),methods:{loadPatterns:async function(){const t="https://wavelovers.ru/assets/patterns.json";try{const e=await fetch(t);if(e.ok){let t=await e.json();this.patterns=t}else console.log("Connect to the Internet for download more patterns...")}catch(e){console.log("[error]",e)}},addEventListeners(){window.addEventListener("gamepadconnected",(t=>this.addGamepad(t))),window.addEventListener("gamepaddisconnected",(t=>this.deleteGamepad(t)))},addGamepad(t){this.gamepads.length>=1||this.gamepads.push(new N(t.gamepad))},deleteGamepad(t){this.gamepads.forEach(((e,n)=>{e.unit.id===t.gamepad.id&&this.gamepads.splice(n,1)}))},change(t){this.mode===t?(this.isActive=!this.isActive,this.reset()):(this.isActive=!0,this.mode=t),!0===this.isActive&&(this.reset(),this.vibrate())},vibrate(){this.gamepads.forEach((t=>{t.vibrate(this.patterns[this.mode].pattern)}))},reset(){this.gamepads.forEach((t=>{t.reset()}))}},mounted(){this.loadPatterns(),this.addEventListeners()}});const $=(0,f.Z)(T,[["render",d]]);var B=$,H=(0,i.aZ)({name:"App",components:{WaveloversApp:B}});const K=(0,f.Z)(H,[["render",s]]);var U=K;(0,a.ri)(U).mount("#app")}},e={};function n(a){var i=e[a];if(void 0!==i)return i.exports;var s=e[a]={exports:{}};return t[a](s,s.exports,n),s.exports}n.m=t,function(){var t=[];n.O=function(e,a,i,s){if(!a){var r=1/0;for(p=0;p=s)&&Object.keys(n.O).every((function(t){return n.O[t](a[c])}))?a.splice(c--,1):(o=!1,s0&&t[p-1][2]>s;p--)t[p]=t[p-1];t[p]=[a,i,s]}}(),function(){n.n=function(t){var e=t&&t.__esModule?function(){return t["default"]}:function(){return t};return n.d(e,{a:e}),e}}(),function(){n.d=function(t,e){for(var a in e)n.o(e,a)&&!n.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:e[a]})}}(),function(){n.g=function(){if("object"===typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"===typeof window)return window}}()}(),function(){n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)}}(),function(){var t={143:0};n.O.j=function(e){return 0===t[e]};var e=function(e,a){var i,s,r=a[0],o=a[1],c=a[2],d=0;if(r.some((function(e){return 0!==t[e]}))){for(i in o)n.o(o,i)&&(n.m[i]=o[i]);if(c)var p=c(n)}for(e&&e(a);d 0)\n ? (_openBlock(), _createBlock(_component_PatternList, {\n key: 0,\n patterns: _ctx.patterns,\n mode: _ctx.mode,\n isActive: _ctx.isActive,\n onChange: _ctx.change\n }, null, 8, [\"patterns\", \"mode\", \"isActive\", \"onChange\"]))\n : (_openBlock(), _createBlock(_component_MessageItem, { key: 1 }, {\n default: _withCtx(() => [\n _hoisted_2\n ]),\n _: 1\n })),\n (_ctx.gamepads.length > 0)\n ? (_openBlock(), _createBlock(_component_GamepadList, {\n key: 2,\n gamepads: _ctx.gamepads\n }, null, 8, [\"gamepads\"]))\n : (_openBlock(), _createBlock(_component_MessageItem, { key: 3 }, {\n default: _withCtx(() => [\n _hoisted_3\n ]),\n _: 1\n }))\n ]))\n}","import { renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, resolveComponent as _resolveComponent, createBlock as _createBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"pattern-list\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_PatternItem = _resolveComponent(\"PatternItem\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.patterns, (pattern, index) => {\n return (_openBlock(), _createBlock(_component_PatternItem, {\n key: pattern.name,\n pattern: pattern,\n index: index,\n mode: _ctx.mode,\n isActive: _ctx.isActive,\n onChange: _ctx.change\n }, null, 8, [\"pattern\", \"index\", \"mode\", \"isActive\", \"onChange\"]))\n }), 128))\n ]))\n}","import { toDisplayString as _toDisplayString, createElementVNode as _createElementVNode, normalizeClass as _normalizeClass, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = [\"textContent\"]\nconst _hoisted_2 = [\"textContent\"]\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"div\", {\n onClick: _cache[0] || (_cache[0] = ($event: any) => (_ctx.change(_ctx.index))),\n class: _normalizeClass(['pattern-item',\r\n _ctx.index === _ctx.mode && _ctx.isActive === true ?\r\n 'pattern-item_selected' : '',\r\n ])\n }, [\n _createElementVNode(\"span\", {\n class: \"pattern-item__icon\",\n textContent: _toDisplayString(_ctx.pattern.icon)\n }, null, 8, _hoisted_1),\n _createElementVNode(\"span\", {\n class: \"pattern-item__name\",\n textContent: _toDisplayString(_ctx.pattern.name)\n }, null, 8, _hoisted_2)\n ], 2))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'PatternItem',\r\n props: {\r\n pattern: {\r\n type: Object,\r\n },\r\n index: {\r\n type: Number,\r\n },\r\n mode: {\r\n type: Number,\r\n },\r\n isActive: {\r\n type: Boolean,\r\n },\r\n },\r\n methods: {\r\n change(index: number): void {\r\n this.$emit('change', index as number);\r\n },\r\n },\r\n });\r\n","import { render } from \"./PatternItem.vue?vue&type=template&id=e1c2f044&ts=true\"\nimport script from \"./PatternItem.vue?vue&type=script&lang=ts\"\nexport * from \"./PatternItem.vue?vue&type=script&lang=ts\"\n\nimport \"./PatternItem.vue?vue&type=style&index=0&id=e1c2f044&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import PatternItem from '@/components/PatternItem.vue';\r\n\r\n export default defineComponent({\r\n name: 'PatternList',\r\n props: {\r\n patterns: {\r\n type: Array,\r\n },\r\n mode: {\r\n type: Number,\r\n },\r\n isActive: {\r\n type: Boolean,\r\n },\r\n },\r\n components: {\r\n PatternItem: PatternItem,\r\n },\r\n methods: {\r\n change(index: number): void {\r\n this.$emit('change', index as number);\r\n },\r\n },\r\n });\r\n","import { render } from \"./PatternList.vue?vue&type=template&id=77356b3f&ts=true\"\nimport script from \"./PatternList.vue?vue&type=script&lang=ts\"\nexport * from \"./PatternList.vue?vue&type=script&lang=ts\"\n\nimport \"./PatternList.vue?vue&type=style&index=0&id=77356b3f&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, resolveComponent as _resolveComponent, toDisplayString as _toDisplayString, createBlock as _createBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"device-list\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_GamepadItem = _resolveComponent(\"GamepadItem\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.gamepads, (gamepad) => {\n return (_openBlock(), _createBlock(_component_GamepadItem, {\n key: gamepad.id,\n textContent: _toDisplayString(gamepad.unit.id)\n }, null, 8, [\"textContent\"]))\n }), 128))\n ]))\n}","import { openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"list-item\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'GamepadItem',\r\n });\r\n","import { render } from \"./GamepadItem.vue?vue&type=template&id=e6e6c988&ts=true\"\nimport script from \"./GamepadItem.vue?vue&type=script&lang=ts\"\nexport * from \"./GamepadItem.vue?vue&type=script&lang=ts\"\n\nimport \"./GamepadItem.vue?vue&type=style&index=0&id=e6e6c988&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import GamepadItem from '@/components/GamepadItem.vue';\r\n\r\n export default defineComponent({\r\n name: 'GamepadList',\r\n props: {\r\n gamepads: {\r\n type: Array,\r\n },\r\n },\r\n components: {\r\n GamepadItem: GamepadItem,\r\n },\r\n });\r\n ","import { render } from \"./GamepadList.vue?vue&type=template&id=1d58b1c0&ts=true\"\nimport script from \"./GamepadList.vue?vue&type=script&lang=ts\"\nexport * from \"./GamepadList.vue?vue&type=script&lang=ts\"\n\nimport \"./GamepadList.vue?vue&type=style&index=0&id=1d58b1c0&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { renderSlot as _renderSlot, createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"message\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n _createElementVNode(\"span\", null, [\n _renderSlot(_ctx.$slots, \"default\")\n ])\n ]))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'MessageItem',\r\n });\r\n","import { render } from \"./MessageItem.vue?vue&type=template&id=32e2819b&ts=true\"\nimport script from \"./MessageItem.vue?vue&type=script&lang=ts\"\nexport * from \"./MessageItem.vue?vue&type=script&lang=ts\"\n\nimport \"./MessageItem.vue?vue&type=style&index=0&id=32e2819b&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","export type TPattern = {\r\n pattern: TPatternUnit[];\r\n}\r\n\r\nexport type TPatternUnit = {\r\n startDelay: number,\r\n duration: number,\r\n weakMagnitude: number,\r\n strongMagnitude: number,\r\n}\r\n\r\nexport interface IVibrationActuator {\r\n type: string;\r\n reset(): void;\r\n playEffect(mode: string, pattern: TPatternUnit): void;\r\n}\r\n\r\nexport interface IGamepad {\r\n id: string;\r\n index: number;\r\n timestamp: number;\r\n connected: boolean;\r\n vibrationActuator: IVibrationActuator;\r\n}\r\n\r\nexport interface IVibrator {\r\n readonly id: number,\r\n readonly canVibrate: boolean;\r\n isVibrating: boolean;\r\n unit: IGamepad;\r\n pattern: TPatternUnit[];\r\n update(): void;\r\n reset(): void;\r\n vibrate(pattern: TPatternUnit[]): void;\r\n sleep(ms: number): Promise;\r\n}\r\n\r\nexport class Vibrator implements IVibrator {\r\n readonly id: number;\r\n readonly canVibrate: boolean;\r\n isVibrating: boolean;\r\n unit: IGamepad;\r\n pattern: TPatternUnit[];\r\n\r\n constructor(unit: IGamepad) {\r\n this.unit = unit;\r\n this.id = Date.now();\r\n this.canVibrate = (this.unit.vibrationActuator) ? true : false;\r\n this.isVibrating = false;\r\n this.pattern = [];\r\n }\r\n\r\n update(): void {\r\n const gamepads = navigator.getGamepads();\r\n this.unit = gamepads[this.unit.index];\r\n }\r\n\r\n reset(): void {\r\n this.isVibrating = false;\r\n this.unit.vibrationActuator.reset();\r\n }\r\n\r\n async vibrate(pattern: TPatternUnit[]) {\r\n this.isVibrating = true;\r\n this.pattern = pattern;\r\n\r\n while (this.isVibrating === true) {\r\n for (let i = 0; i < this.pattern.length; i++) {\r\n if (this.isVibrating === true) {\r\n this.unit.vibrationActuator.playEffect('dual-rumble', this.pattern[i]);\r\n await this.sleep(this.pattern[i].startDelay + this.pattern[i].duration + 100);\r\n } else {\r\n return;\r\n }\r\n }\r\n }\r\n }\r\n\r\n sleep(ms: number): Promise {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n }\r\n}","\r\n import { defineComponent } from 'vue';\r\n import PatternList from '@/components/PatternList.vue';\r\n import GamepadList from '@/components/GamepadList.vue';\r\n import MessageItem from '@/components/MessageItem.vue';\r\n import { Vibrator, IGamepad, TPattern, TPatternUnit } from '@/components/Vibrator';\r\n\r\n interface Event {\r\n gamepad: IGamepad | any;\r\n }\r\n\r\n export default defineComponent({\r\n name: 'WaveloversApp',\r\n components: {\r\n PatternList: PatternList,\r\n GamepadList: GamepadList,\r\n MessageItem: MessageItem,\r\n },\r\n data: () => {\r\n return {\r\n gamepads: [] as Vibrator[],\r\n patterns: [] as TPattern[],\r\n isActive: false,\r\n mode: 0,\r\n };\r\n },\r\n methods: {\r\n loadPatterns: async function () {\r\n const url = 'https://wavelovers.ru/assets/patterns.json';\r\n try {\r\n const response = await fetch(url);\r\n if (response.ok) {\r\n let json = await response.json();\r\n this.patterns = json;\r\n } else {\r\n console.log('Connect to the Internet for download more patterns...');\r\n }\r\n } catch (error) {\r\n console.log('[error]', error);\r\n }\r\n },\r\n addEventListeners(): void {\r\n window.addEventListener('gamepadconnected', (event: Event) => this.addGamepad(event));\r\n window.addEventListener('gamepaddisconnected', (event: Event) => this.deleteGamepad(event));\r\n },\r\n addGamepad(event: Event) {\r\n if (this.gamepads.length >= 1) {\r\n return;\r\n } else {\r\n this.gamepads.push(new Vibrator(event.gamepad));\r\n }\r\n },\r\n deleteGamepad(event: Event): void {\r\n this.gamepads.forEach((gamepad, index) => {\r\n if (gamepad.unit.id === event.gamepad.id) {\r\n this.gamepads.splice(index, 1);\r\n }\r\n });\r\n },\r\n change(index: number): void {\r\n if (this.mode === index) {\r\n this.isActive = !this.isActive;\r\n this.reset();\r\n } else {\r\n this.isActive = true;\r\n this.mode = index;\r\n }\r\n if (this.isActive === true) {\r\n this.reset();\r\n this.vibrate();\r\n }\r\n },\r\n vibrate(): void {\r\n this.gamepads.forEach(gamepad => {\r\n gamepad.vibrate(this.patterns[this.mode].pattern as TPatternUnit[]);\r\n });\r\n },\r\n reset(): void {\r\n this.gamepads.forEach(gamepad => {\r\n gamepad.reset();\r\n });\r\n },\r\n },\r\n mounted() {\r\n this.loadPatterns();\r\n this.addEventListeners();\r\n },\r\n });\r\n","import { render } from \"./WaveloversApp.vue?vue&type=template&id=be9f35fc&ts=true\"\nimport script from \"./WaveloversApp.vue?vue&type=script&lang=ts\"\nexport * from \"./WaveloversApp.vue?vue&type=script&lang=ts\"\n\nimport \"./WaveloversApp.vue?vue&type=style&index=0&id=be9f35fc&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import WaveloversApp from '@/components/WaveloversApp.vue';\r\n\r\n export default defineComponent({\r\n name: 'App',\r\n components: {\r\n WaveloversApp: WaveloversApp,\r\n },\r\n });\r\n","import { render } from \"./App.vue?vue&type=template&id=ffca9ffe&ts=true\"\nimport script from \"./App.vue?vue&type=script&lang=ts\"\nexport * from \"./App.vue?vue&type=script&lang=ts\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { createApp } from 'vue'\nimport App from './App.vue'\n\ncreateApp(App).mount('#app')\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","var deferred = [];\n__webpack_require__.O = function(result, chunkIds, fn, priority) {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t143: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkwavelovers\"] = self[\"webpackChunkwavelovers\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [998], function() { return __webpack_require__(2466); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["render","_ctx","_cache","$props","$setup","$data","$options","_component_WaveloversApp","_resolveComponent","_openBlock","_createBlock","_hoisted_1","class","_hoisted_2","_createTextVNode","_hoisted_3","_component_PatternList","_component_MessageItem","_component_GamepadList","_createElementBlock","patterns","length","key","mode","isActive","onChange","change","default","_withCtx","_","gamepads","_component_PatternItem","_Fragment","_renderList","pattern","index","name","onClick","$event","_normalizeClass","_createElementVNode","textContent","_toDisplayString","icon","defineComponent","props","type","Object","Number","Boolean","methods","this","$emit","__exports__","Array","components","PatternItem","_component_GamepadItem","gamepad","id","unit","GamepadItem","_renderSlot","$slots","Vibrator","constructor","Date","now","canVibrate","vibrationActuator","isVibrating","update","navigator","getGamepads","reset","i","playEffect","sleep","startDelay","duration","ms","Promise","resolve","setTimeout","PatternList","GamepadList","MessageItem","data","loadPatterns","async","url","response","fetch","ok","json","console","log","error","addEventListeners","window","addEventListener","event","addGamepad","deleteGamepad","push","forEach","splice","vibrate","mounted","WaveloversApp","createApp","App","mount","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","m","deferred","O","result","chunkIds","fn","priority","notFulfilled","Infinity","fulfilled","j","keys","every","r","n","getter","__esModule","d","a","definition","o","defineProperty","enumerable","get","g","globalThis","Function","e","obj","prop","prototype","hasOwnProperty","call","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","some","chunkLoadingGlobal","self","bind","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file diff --git a/docs/js/app.65320b71.js b/docs/js/app.65320b71.js new file mode 100644 index 0000000..5e84b0b --- /dev/null +++ b/docs/js/app.65320b71.js @@ -0,0 +1,2 @@ +(function(){"use strict";var t={958:function(t,e,n){var a=n(9242),i=n(3396);function s(t,e,n,a,s,r){const o=(0,i.up)("WaveloversApp");return(0,i.wg)(),(0,i.j4)(o)}const r={class:"wavelovers"},o=(0,i.Uk)("Loading..."),c=(0,i.Uk)("Press any gamepad's button or connect new gamepad.");function d(t,e,n,a,s,d){const p=(0,i.up)("PatternList"),u=(0,i.up)("MessageItem"),h=(0,i.up)("GamepadList");return(0,i.wg)(),(0,i.iD)("div",r,[t.patterns.length>0?((0,i.wg)(),(0,i.j4)(p,{key:0,patterns:t.patterns,mode:t.mode,isActive:t.isActive,onChange:t.change},null,8,["patterns","mode","isActive","onChange"])):((0,i.wg)(),(0,i.j4)(u,{key:1},{default:(0,i.w5)((()=>[o])),_:1})),t.gamepads.length>0?((0,i.wg)(),(0,i.j4)(h,{key:2,gamepads:t.gamepads},null,8,["gamepads"])):((0,i.wg)(),(0,i.j4)(u,{key:3},{default:(0,i.w5)((()=>[c])),_:1}))])}const p={class:"pattern-list"};function u(t,e,n,a,s,r){const o=(0,i.up)("PatternItem");return(0,i.wg)(),(0,i.iD)("div",p,[((0,i.wg)(!0),(0,i.iD)(i.HY,null,(0,i.Ko)(t.patterns,((e,n)=>((0,i.wg)(),(0,i.j4)(o,{key:e.name,pattern:e,index:n,mode:t.mode,isActive:t.isActive,onChange:t.change},null,8,["pattern","index","mode","isActive","onChange"])))),128))])}var h=n(7139);const l=["textContent"],m=["textContent"];function v(t,e,n,a,s,r){return(0,i.wg)(),(0,i.iD)("div",{onClick:e[0]||(e[0]=e=>t.change(t.index)),class:(0,h.C_)(["pattern-item",t.index===t.mode&&!0===t.isActive?"pattern-item_selected":""])},[(0,i._)("span",{class:"pattern-item__icon",textContent:(0,h.zw)(t.pattern.icon)},null,8,l),(0,i._)("span",{class:"pattern-item__name",textContent:(0,h.zw)(t.pattern.name)},null,8,m)],2)}var g=(0,i.aZ)({name:"PatternItem",props:{pattern:{type:Object},index:{type:Number},mode:{type:Number},isActive:{type:Boolean}},methods:{change(t){this.$emit("change",t)}}}),f=n(89);const w=(0,f.Z)(g,[["render",v]]);var b=w,y=(0,i.aZ)({name:"PatternList",props:{patterns:{type:Array},mode:{type:Number},isActive:{type:Boolean}},components:{PatternItem:b},methods:{change(t){this.$emit("change",t)}}});const A=(0,f.Z)(y,[["render",u]]);var Z=A;const j={class:"device-list"};function x(t,e,n,a,s,r){const o=(0,i.up)("GamepadItem");return(0,i.wg)(),(0,i.iD)("div",j,[((0,i.wg)(!0),(0,i.iD)(i.HY,null,(0,i.Ko)(t.gamepads,(t=>((0,i.wg)(),(0,i.j4)(o,{key:t.id,textContent:(0,h.zw)(t.unit.id)},null,8,["textContent"])))),128))])}const k={class:"list-item"};function C(t,e,n,a,s,r){return(0,i.wg)(),(0,i.iD)("div",k)}var _=(0,i.aZ)({name:"GamepadItem"});const O=(0,f.Z)(_,[["render",C]]);var P=O,G=(0,i.aZ)({name:"GamepadList",props:{gamepads:{type:Array}},components:{GamepadItem:P}});const I=(0,f.Z)(G,[["render",x]]);var L=I;const D={class:"message"};function E(t,e,n,a,s,r){return(0,i.wg)(),(0,i.iD)("div",D,[(0,i._)("span",null,[(0,i.WI)(t.$slots,"default")])])}var V=(0,i.aZ)({name:"MessageItem"});const M=(0,f.Z)(V,[["render",E]]);var W=M,z=n(2482);class N{constructor(t){(0,z.Z)(this,"id",void 0),(0,z.Z)(this,"canVibrate",void 0),(0,z.Z)(this,"isVibrating",void 0),(0,z.Z)(this,"unit",void 0),(0,z.Z)(this,"pattern",void 0),this.unit=t,this.id=Date.now(),this.canVibrate=!!this.unit.vibrationActuator,this.isVibrating=!1,this.pattern=[]}update(){const t=navigator.getGamepads();this.unit=t[this.unit.index]}reset(){this.isVibrating=!1,this.unit.vibrationActuator.reset()}async vibrate(t){this.isVibrating=!0,this.pattern=t;while(!0===this.isVibrating)for(let t=0;tsetTimeout(e,t)))}}var T=(0,i.aZ)({name:"WaveloversApp",components:{PatternList:Z,GamepadList:L,MessageItem:W},data:()=>({gamepads:[],patterns:[],isActive:!1,mode:0}),methods:{loadPatterns:async function(){const t="https://wavelovers.ru/assets/patterns.json";try{const e=await fetch(t);if(e.ok){let t=await e.json();this.patterns=t}else console.log("Connect to the Internet for download more patterns...")}catch(e){console.log(e)}},addEventListeners(){window.addEventListener("gamepadconnected",(t=>this.addGamepad(t))),window.addEventListener("gamepaddisconnected",(t=>this.deleteGamepad(t)))},addGamepad(t){const e=t;this.gamepads.length>=1||this.gamepads.push(new N(e.gamepad))},deleteGamepad(t){this.gamepads.forEach(((e,n)=>{e.unit.id===t.gamepad.id&&this.gamepads.splice(n,1)}))},change(t){this.mode===t?(this.isActive=!this.isActive,this.reset()):(this.isActive=!0,this.mode=t),!0===this.isActive&&(this.reset(),this.vibrate())},vibrate(){this.gamepads.forEach((t=>{t.vibrate(this.patterns[this.mode].pattern)}))},reset(){this.gamepads.forEach((t=>{t.reset()}))}},mounted(){this.loadPatterns(),this.addEventListeners()}});const $=(0,f.Z)(T,[["render",d]]);var B=$,H=(0,i.aZ)({name:"App",components:{WaveloversApp:B}});const K=(0,f.Z)(H,[["render",s]]);var U=K;(0,a.ri)(U).mount("#app")}},e={};function n(a){var i=e[a];if(void 0!==i)return i.exports;var s=e[a]={exports:{}};return t[a](s,s.exports,n),s.exports}n.m=t,function(){var t=[];n.O=function(e,a,i,s){if(!a){var r=1/0;for(p=0;p=s)&&Object.keys(n.O).every((function(t){return n.O[t](a[c])}))?a.splice(c--,1):(o=!1,s0&&t[p-1][2]>s;p--)t[p]=t[p-1];t[p]=[a,i,s]}}(),function(){n.n=function(t){var e=t&&t.__esModule?function(){return t["default"]}:function(){return t};return n.d(e,{a:e}),e}}(),function(){n.d=function(t,e){for(var a in e)n.o(e,a)&&!n.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:e[a]})}}(),function(){n.g=function(){if("object"===typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"===typeof window)return window}}()}(),function(){n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)}}(),function(){var t={143:0};n.O.j=function(e){return 0===t[e]};var e=function(e,a){var i,s,r=a[0],o=a[1],c=a[2],d=0;if(r.some((function(e){return 0!==t[e]}))){for(i in o)n.o(o,i)&&(n.m[i]=o[i]);if(c)var p=c(n)}for(e&&e(a);d 0)\n ? (_openBlock(), _createBlock(_component_PatternList, {\n key: 0,\n patterns: _ctx.patterns,\n mode: _ctx.mode,\n isActive: _ctx.isActive,\n onChange: _ctx.change\n }, null, 8, [\"patterns\", \"mode\", \"isActive\", \"onChange\"]))\n : (_openBlock(), _createBlock(_component_MessageItem, { key: 1 }, {\n default: _withCtx(() => [\n _hoisted_2\n ]),\n _: 1\n })),\n (_ctx.gamepads.length > 0)\n ? (_openBlock(), _createBlock(_component_GamepadList, {\n key: 2,\n gamepads: _ctx.gamepads\n }, null, 8, [\"gamepads\"]))\n : (_openBlock(), _createBlock(_component_MessageItem, { key: 3 }, {\n default: _withCtx(() => [\n _hoisted_3\n ]),\n _: 1\n }))\n ]))\n}","import { renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, resolveComponent as _resolveComponent, createBlock as _createBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"pattern-list\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_PatternItem = _resolveComponent(\"PatternItem\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.patterns, (pattern, index) => {\n return (_openBlock(), _createBlock(_component_PatternItem, {\n key: pattern.name,\n pattern: pattern,\n index: index,\n mode: _ctx.mode,\n isActive: _ctx.isActive,\n onChange: _ctx.change\n }, null, 8, [\"pattern\", \"index\", \"mode\", \"isActive\", \"onChange\"]))\n }), 128))\n ]))\n}","import { toDisplayString as _toDisplayString, createElementVNode as _createElementVNode, normalizeClass as _normalizeClass, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = [\"textContent\"]\nconst _hoisted_2 = [\"textContent\"]\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"div\", {\n onClick: _cache[0] || (_cache[0] = ($event: any) => (_ctx.change(_ctx.index))),\n class: _normalizeClass(['pattern-item',\r\n _ctx.index === _ctx.mode && _ctx.isActive === true ?\r\n 'pattern-item_selected' : '',\r\n ])\n }, [\n _createElementVNode(\"span\", {\n class: \"pattern-item__icon\",\n textContent: _toDisplayString(_ctx.pattern.icon)\n }, null, 8, _hoisted_1),\n _createElementVNode(\"span\", {\n class: \"pattern-item__name\",\n textContent: _toDisplayString(_ctx.pattern.name)\n }, null, 8, _hoisted_2)\n ], 2))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'PatternItem',\r\n props: {\r\n pattern: {\r\n type: Object,\r\n },\r\n index: {\r\n type: Number,\r\n },\r\n mode: {\r\n type: Number,\r\n },\r\n isActive: {\r\n type: Boolean,\r\n },\r\n },\r\n methods: {\r\n change(index: number): void {\r\n this.$emit('change', index as number);\r\n },\r\n },\r\n });\r\n","import { render } from \"./PatternItem.vue?vue&type=template&id=e1c2f044&ts=true\"\nimport script from \"./PatternItem.vue?vue&type=script&lang=ts\"\nexport * from \"./PatternItem.vue?vue&type=script&lang=ts\"\n\nimport \"./PatternItem.vue?vue&type=style&index=0&id=e1c2f044&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import PatternItem from '@/components/PatternItem.vue';\r\n\r\n export default defineComponent({\r\n name: 'PatternList',\r\n props: {\r\n patterns: {\r\n type: Array,\r\n },\r\n mode: {\r\n type: Number,\r\n },\r\n isActive: {\r\n type: Boolean,\r\n },\r\n },\r\n components: {\r\n PatternItem: PatternItem,\r\n },\r\n methods: {\r\n change(index: number): void {\r\n this.$emit('change', index as number);\r\n },\r\n },\r\n });\r\n","import { render } from \"./PatternList.vue?vue&type=template&id=77356b3f&ts=true\"\nimport script from \"./PatternList.vue?vue&type=script&lang=ts\"\nexport * from \"./PatternList.vue?vue&type=script&lang=ts\"\n\nimport \"./PatternList.vue?vue&type=style&index=0&id=77356b3f&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, resolveComponent as _resolveComponent, toDisplayString as _toDisplayString, createBlock as _createBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"device-list\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n const _component_GamepadItem = _resolveComponent(\"GamepadItem\")!\n\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n (_openBlock(true), _createElementBlock(_Fragment, null, _renderList(_ctx.gamepads, (gamepad) => {\n return (_openBlock(), _createBlock(_component_GamepadItem, {\n key: gamepad.id,\n textContent: _toDisplayString(gamepad.unit.id)\n }, null, 8, [\"textContent\"]))\n }), 128))\n ]))\n}","import { openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"list-item\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'GamepadItem',\r\n });\r\n","import { render } from \"./GamepadItem.vue?vue&type=template&id=e6e6c988&ts=true\"\nimport script from \"./GamepadItem.vue?vue&type=script&lang=ts\"\nexport * from \"./GamepadItem.vue?vue&type=script&lang=ts\"\n\nimport \"./GamepadItem.vue?vue&type=style&index=0&id=e6e6c988&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import GamepadItem from '@/components/GamepadItem.vue';\r\n\r\n export default defineComponent({\r\n name: 'GamepadList',\r\n props: {\r\n gamepads: {\r\n type: Array,\r\n },\r\n },\r\n components: {\r\n GamepadItem: GamepadItem,\r\n },\r\n });\r\n ","import { render } from \"./GamepadList.vue?vue&type=template&id=1d58b1c0&ts=true\"\nimport script from \"./GamepadList.vue?vue&type=script&lang=ts\"\nexport * from \"./GamepadList.vue?vue&type=script&lang=ts\"\n\nimport \"./GamepadList.vue?vue&type=style&index=0&id=1d58b1c0&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { renderSlot as _renderSlot, createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from \"vue\"\n\nconst _hoisted_1 = { class: \"message\" }\n\nexport function render(_ctx: any,_cache: any,$props: any,$setup: any,$data: any,$options: any) {\n return (_openBlock(), _createElementBlock(\"div\", _hoisted_1, [\n _createElementVNode(\"span\", null, [\n _renderSlot(_ctx.$slots, \"default\")\n ])\n ]))\n}","\r\n import { defineComponent } from 'vue';\r\n\r\n export default defineComponent({\r\n name: 'MessageItem',\r\n });\r\n","import { render } from \"./MessageItem.vue?vue&type=template&id=32e2819b&ts=true\"\nimport script from \"./MessageItem.vue?vue&type=script&lang=ts\"\nexport * from \"./MessageItem.vue?vue&type=script&lang=ts\"\n\nimport \"./MessageItem.vue?vue&type=style&index=0&id=32e2819b&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { TPatternUnit } from '@/models/TPatternUnit';\r\nimport { IGamepad } from '@/models/IGamepad';\r\nimport { IVibrator } from '@/models/IVibrator';\r\n\r\nexport class Vibrator implements IVibrator {\r\n readonly id: number;\r\n readonly canVibrate: boolean;\r\n isVibrating: boolean;\r\n unit: IGamepad;\r\n pattern: TPatternUnit[];\r\n\r\n constructor(unit: IGamepad) {\r\n this.unit = unit;\r\n this.id = Date.now();\r\n this.canVibrate = (this.unit.vibrationActuator) ? true : false;\r\n this.isVibrating = false;\r\n this.pattern = [];\r\n }\r\n\r\n update(): void {\r\n const gamepads = navigator.getGamepads();\r\n this.unit = gamepads[this.unit.index];\r\n }\r\n\r\n reset(): void {\r\n this.isVibrating = false;\r\n this.unit.vibrationActuator.reset();\r\n }\r\n\r\n async vibrate(pattern: TPatternUnit[]) {\r\n this.isVibrating = true;\r\n this.pattern = pattern;\r\n\r\n while (this.isVibrating === true) {\r\n for (let i = 0; i < this.pattern.length; i++) {\r\n if (this.isVibrating === true) {\r\n this.unit.vibrationActuator.playEffect('dual-rumble', this.pattern[i]);\r\n await this.sleep(this.pattern[i].startDelay + this.pattern[i].duration + 100);\r\n } else {\r\n return;\r\n }\r\n }\r\n }\r\n }\r\n\r\n sleep(ms: number): Promise {\r\n return new Promise(resolve => setTimeout(resolve, ms));\r\n }\r\n}\r\n\r\n","\r\n import { defineComponent } from 'vue';\r\n import PatternList from '@/components/PatternList.vue';\r\n import GamepadList from '@/components/GamepadList.vue';\r\n import MessageItem from '@/components/MessageItem.vue';\r\n import { IGamepadEvent } from '@/models/IGamepadEvent';\r\n import { IGamepad } from '@/models/IGamepad';\r\n import { TPattern } from '@/models/TPattern';\r\n import { TPatternUnit } from '@/models/TPatternUnit';\r\n import { Vibrator } from '@/models/Vibrator';\r\n \r\n export default defineComponent({\r\n name: 'WaveloversApp',\r\n components: {\r\n PatternList: PatternList,\r\n GamepadList: GamepadList,\r\n MessageItem: MessageItem,\r\n },\r\n data: () => {\r\n return {\r\n gamepads: [] as Vibrator[],\r\n patterns: [] as TPattern[],\r\n isActive: false,\r\n mode: 0,\r\n };\r\n },\r\n methods: {\r\n loadPatterns: async function () {\r\n const url = 'https://wavelovers.ru/assets/patterns.json';\r\n try {\r\n const response = await fetch(url);\r\n if (response.ok) {\r\n let json = await response.json();\r\n this.patterns = json;\r\n } else {\r\n console.log('Connect to the Internet for download more patterns...');\r\n }\r\n } catch (error) {\r\n console.log(error);\r\n }\r\n },\r\n addEventListeners(): void {\r\n window.addEventListener('gamepadconnected', (event: GamepadEvent) => this.addGamepad(event));\r\n window.addEventListener('gamepaddisconnected', (event: GamepadEvent) => this.deleteGamepad(event));\r\n },\r\n addGamepad(event: GamepadEvent) {\r\n const ievent: IGamepadEvent = event as unknown as IGamepadEvent;\r\n if (this.gamepads.length >= 1) {\r\n return;\r\n } else {\r\n this.gamepads.push(new Vibrator(ievent.gamepad as IGamepad));\r\n }\r\n },\r\n deleteGamepad(event: GamepadEvent): void {\r\n this.gamepads.forEach((gamepad, index) => {\r\n if (gamepad.unit.id === event.gamepad.id) {\r\n this.gamepads.splice(index, 1);\r\n }\r\n });\r\n },\r\n change(index: number): void {\r\n if (this.mode === index) {\r\n this.isActive = !this.isActive;\r\n this.reset();\r\n } else {\r\n this.isActive = true;\r\n this.mode = index;\r\n }\r\n if (this.isActive === true) {\r\n this.reset();\r\n this.vibrate();\r\n }\r\n },\r\n vibrate(): void {\r\n this.gamepads.forEach(gamepad => {\r\n gamepad.vibrate(this.patterns[this.mode].pattern as TPatternUnit[]);\r\n });\r\n },\r\n reset(): void {\r\n this.gamepads.forEach(gamepad => {\r\n gamepad.reset();\r\n });\r\n },\r\n },\r\n mounted() {\r\n this.loadPatterns();\r\n this.addEventListeners();\r\n },\r\n });\r\n","import { render } from \"./WaveloversApp.vue?vue&type=template&id=be83c6c8&ts=true\"\nimport script from \"./WaveloversApp.vue?vue&type=script&lang=ts\"\nexport * from \"./WaveloversApp.vue?vue&type=script&lang=ts\"\n\nimport \"./WaveloversApp.vue?vue&type=style&index=0&id=be83c6c8&lang=scss\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","\r\n import { defineComponent } from 'vue';\r\n import WaveloversApp from '@/components/WaveloversApp.vue';\r\n\r\n export default defineComponent({\r\n name: 'App',\r\n components: {\r\n WaveloversApp: WaveloversApp,\r\n },\r\n });\r\n","import { render } from \"./App.vue?vue&type=template&id=ffca9ffe&ts=true\"\nimport script from \"./App.vue?vue&type=script&lang=ts\"\nexport * from \"./App.vue?vue&type=script&lang=ts\"\n\nimport exportComponent from \"E:\\\\Sources\\\\Repos\\\\wavelovers\\\\node_modules\\\\vue-loader\\\\dist\\\\exportHelper.js\"\nconst __exports__ = /*#__PURE__*/exportComponent(script, [['render',render]])\n\nexport default __exports__","import { createApp } from 'vue';\nimport App from './App.vue';\n\ncreateApp(App).mount('#app');\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","var deferred = [];\n__webpack_require__.O = function(result, chunkIds, fn, priority) {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t143: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkwavelovers\"] = self[\"webpackChunkwavelovers\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [998], function() { return __webpack_require__(958); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["render","_ctx","_cache","$props","$setup","$data","$options","_component_WaveloversApp","_resolveComponent","_openBlock","_createBlock","_hoisted_1","class","_hoisted_2","_createTextVNode","_hoisted_3","_component_PatternList","_component_MessageItem","_component_GamepadList","_createElementBlock","patterns","length","key","mode","isActive","onChange","change","default","_withCtx","_","gamepads","_component_PatternItem","_Fragment","_renderList","pattern","index","name","onClick","$event","_normalizeClass","_createElementVNode","textContent","_toDisplayString","icon","defineComponent","props","type","Object","Number","Boolean","methods","this","$emit","__exports__","Array","components","PatternItem","_component_GamepadItem","gamepad","id","unit","GamepadItem","_renderSlot","$slots","Vibrator","constructor","Date","now","canVibrate","vibrationActuator","isVibrating","update","navigator","getGamepads","reset","i","playEffect","sleep","startDelay","duration","ms","Promise","resolve","setTimeout","PatternList","GamepadList","MessageItem","data","loadPatterns","async","url","response","fetch","ok","json","console","log","error","addEventListeners","window","addEventListener","event","addGamepad","deleteGamepad","ievent","push","forEach","splice","vibrate","mounted","WaveloversApp","createApp","App","mount","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","m","deferred","O","result","chunkIds","fn","priority","notFulfilled","Infinity","fulfilled","j","keys","every","r","n","getter","__esModule","d","a","definition","o","defineProperty","enumerable","get","g","globalThis","Function","e","obj","prop","prototype","hasOwnProperty","call","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","some","chunkLoadingGlobal","self","bind","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file diff --git a/package.json b/package.json index 8d8e07c..db52354 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "name": "wavelovers", + "description": "Wavelovers. Use your device vibration correctly. Make a massager out of a gamepad.", "version": "1.0.0", "author": "Eugene Serb", "license": "GNU GPL v3", diff --git a/public/README.md b/public/README.md index fd7d1c4..0794102 100644 --- a/public/README.md +++ b/public/README.md @@ -1,5 +1,5 @@ # Wavelovers -Wavelovers in ***VueJS***, ***Typescript***, ***Javascript***, ***HTML*** and ***CSS*** **[[rep](https://github.com/eugene-serb/wavelovers/), [site](https://wavelovers.ru/)]**. +Wavelovers in ***VueJS***, ***Typescript***, ***Javascript***, ***HTML***, ***CSS*** and ***SCSS*** **[[rep](https://github.com/eugene-serb/wavelovers/), [site](https://wavelovers.ru/)]**. This is Wavelovers, which can make a vibrating massager out of a gamepad. It has 16 free vibration patterns to play with. diff --git a/src/components/Vibrator.d.ts b/src/components/Vibrator.d.ts deleted file mode 100644 index da3ee86..0000000 --- a/src/components/Vibrator.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'Vibrator'; \ No newline at end of file diff --git a/src/components/WaveloversApp.vue b/src/components/WaveloversApp.vue index f645be4..bbff00f 100644 --- a/src/components/WaveloversApp.vue +++ b/src/components/WaveloversApp.vue @@ -17,12 +17,12 @@ import PatternList from '@/components/PatternList.vue'; import GamepadList from '@/components/GamepadList.vue'; import MessageItem from '@/components/MessageItem.vue'; - import { Vibrator, IGamepad, TPattern, TPatternUnit } from '@/components/Vibrator'; - - interface Event { - gamepad: IGamepad | any; - } - + import { IGamepadEvent } from '@/models/IGamepadEvent'; + import { IGamepad } from '@/models/IGamepad'; + import { TPattern } from '@/models/TPattern'; + import { TPatternUnit } from '@/models/TPatternUnit'; + import { Vibrator } from '@/models/Vibrator'; + export default defineComponent({ name: 'WaveloversApp', components: { @@ -50,21 +50,22 @@ console.log('Connect to the Internet for download more patterns...'); } } catch (error) { - console.log('[error]', error); + console.log(error); } }, addEventListeners(): void { - window.addEventListener('gamepadconnected', (event: Event) => this.addGamepad(event)); - window.addEventListener('gamepaddisconnected', (event: Event) => this.deleteGamepad(event)); + window.addEventListener('gamepadconnected', (event: GamepadEvent) => this.addGamepad(event)); + window.addEventListener('gamepaddisconnected', (event: GamepadEvent) => this.deleteGamepad(event)); }, - addGamepad(event: Event) { + addGamepad(event: GamepadEvent) { + const ievent: IGamepadEvent = event as unknown as IGamepadEvent; if (this.gamepads.length >= 1) { return; } else { - this.gamepads.push(new Vibrator(event.gamepad)); + this.gamepads.push(new Vibrator(ievent.gamepad as IGamepad)); } }, - deleteGamepad(event: Event): void { + deleteGamepad(event: GamepadEvent): void { this.gamepads.forEach((gamepad, index) => { if (gamepad.unit.id === event.gamepad.id) { this.gamepads.splice(index, 1); diff --git a/src/main.ts b/src/main.ts index 01433bc..684d042 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -import { createApp } from 'vue' -import App from './App.vue' +import { createApp } from 'vue'; +import App from './App.vue'; -createApp(App).mount('#app') +createApp(App).mount('#app'); diff --git a/src/models/IGamepad.ts b/src/models/IGamepad.ts new file mode 100644 index 0000000..cb2d03f --- /dev/null +++ b/src/models/IGamepad.ts @@ -0,0 +1,10 @@ +import { IVibrationActuator } from '@/models/IVibrationActuator'; + +export interface IGamepad { + id: string; + index: number; + timestamp: number; + connected: boolean; + vibrationActuator: IVibrationActuator; +} + diff --git a/src/models/IGamepadEvent.ts b/src/models/IGamepadEvent.ts new file mode 100644 index 0000000..46b7626 --- /dev/null +++ b/src/models/IGamepadEvent.ts @@ -0,0 +1,6 @@ +import { IGamepad } from '@/models/IGamepad'; + +export interface IGamepadEvent { + gamepad: IGamepad; +} + diff --git a/src/models/IVibrationActuator.ts b/src/models/IVibrationActuator.ts new file mode 100644 index 0000000..993d732 --- /dev/null +++ b/src/models/IVibrationActuator.ts @@ -0,0 +1,8 @@ +import { TPatternUnit } from '@/models/TPatternUnit'; + +export interface IVibrationActuator { + type: string; + reset(): void; + playEffect(mode: string, pattern: TPatternUnit): void; +} + diff --git a/src/models/IVibrator.ts b/src/models/IVibrator.ts new file mode 100644 index 0000000..c49e5ff --- /dev/null +++ b/src/models/IVibrator.ts @@ -0,0 +1,15 @@ +import { TPatternUnit } from '@/models/TPatternUnit'; +import { IGamepad } from '@/models/IGamepad'; + +export interface IVibrator { + readonly id: number, + readonly canVibrate: boolean; + isVibrating: boolean; + unit: IGamepad; + pattern: TPatternUnit[]; + update(): void; + reset(): void; + vibrate(pattern: TPatternUnit[]): void; + sleep(ms: number): Promise; +} + diff --git a/src/models/TPattern.ts b/src/models/TPattern.ts new file mode 100644 index 0000000..373ff07 --- /dev/null +++ b/src/models/TPattern.ts @@ -0,0 +1,9 @@ +import { TPatternUnit } from '@/models/TPatternUnit'; + +export type TPattern = { + name: string; + type: string; + icon: string; + pattern: TPatternUnit[]; +} + diff --git a/src/models/TPatternUnit.ts b/src/models/TPatternUnit.ts new file mode 100644 index 0000000..33be318 --- /dev/null +++ b/src/models/TPatternUnit.ts @@ -0,0 +1,7 @@ +export type TPatternUnit = { + startDelay: number, + duration: number, + weakMagnitude: number, + strongMagnitude: number, +} + diff --git a/src/components/Vibrator.ts b/src/models/Vibrator.ts similarity index 60% rename from src/components/Vibrator.ts rename to src/models/Vibrator.ts index 617440f..4bdd781 100644 --- a/src/components/Vibrator.ts +++ b/src/models/Vibrator.ts @@ -1,39 +1,6 @@ -export type TPattern = { - pattern: TPatternUnit[]; -} - -export type TPatternUnit = { - startDelay: number, - duration: number, - weakMagnitude: number, - strongMagnitude: number, -} - -export interface IVibrationActuator { - type: string; - reset(): void; - playEffect(mode: string, pattern: TPatternUnit): void; -} - -export interface IGamepad { - id: string; - index: number; - timestamp: number; - connected: boolean; - vibrationActuator: IVibrationActuator; -} - -export interface IVibrator { - readonly id: number, - readonly canVibrate: boolean; - isVibrating: boolean; - unit: IGamepad; - pattern: TPatternUnit[]; - update(): void; - reset(): void; - vibrate(pattern: TPatternUnit[]): void; - sleep(ms: number): Promise; -} +import { TPatternUnit } from '@/models/TPatternUnit'; +import { IGamepad } from '@/models/IGamepad'; +import { IVibrator } from '@/models/IVibrator'; export class Vibrator implements IVibrator { readonly id: number; @@ -52,7 +19,7 @@ export class Vibrator implements IVibrator { update(): void { const gamepads = navigator.getGamepads(); - this.unit = gamepads[this.unit.index]; + this.unit = gamepads[this.unit.index]; } reset(): void { @@ -79,4 +46,5 @@ export class Vibrator implements IVibrator { sleep(ms: number): Promise { return new Promise(resolve => setTimeout(resolve, ms)); } -} \ No newline at end of file +} + diff --git a/src/shims-vue.d.ts b/src/shims-vue.d.ts index 3804a43..f22603a 100644 --- a/src/shims-vue.d.ts +++ b/src/shims-vue.d.ts @@ -1,6 +1,6 @@ /* eslint-disable */ declare module '*.vue' { - import type { DefineComponent } from 'vue' - const component: DefineComponent<{}, {}, any> - export default component -} + import type { DefineComponent } from 'vue' + const component: DefineComponent<{}, {}, any> + export default component +};