✨ Adds playground
This commit is contained in:
parent
180faecddf
commit
39b3d2711c
21
index.html
21
index.html
@ -5,16 +5,21 @@
|
|||||||
<link rel="icon" type="image/png" href="/binary.png"/>
|
<link rel="icon" type="image/png" href="/binary.png"/>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
<title>Binary</title>
|
<title>Binary</title>
|
||||||
|
<script src="https://unpkg.com/vue@3"></script>
|
||||||
|
<script src="https://unpkg.com/vue-router@4"></script>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
|
||||||
|
<div id="app">
|
||||||
|
<router-view></router-view>
|
||||||
|
</div>
|
||||||
<script type="module" src="/src/main.ts"></script>
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
<style>
|
|
||||||
html, body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"vue": "^3.4.19"
|
"vue": "^3.4.19",
|
||||||
|
"vue-router": "4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^5.0.4",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="bit === '1'" class="w-2 h-8 bg-emerald-100 rounded-t-full" />
|
<div v-if="bit === '1'" class="w-2 h-8 bg-emerald-100 rounded-t-full" />
|
||||||
<div v-else-if="bit === '0'" class="w-2 h-3 bg-emerald-100 rounded-t-full" />
|
<div v-else-if="bit === '0'" class="w-2 h-3 bg-emerald-100 rounded-t-full" />
|
||||||
<p v-else class="text-emerald-100 text-3xl">{{ bit }}</p>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
56
src/components/Settings.vue
Normal file
56
src/components/Settings.vue
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex w-full items-center justify-between mt-4">
|
||||||
|
<button @click="() => (openSettings = !openSettings)" class="ml-4">
|
||||||
|
<img
|
||||||
|
:data-open="openSettings"
|
||||||
|
src="/chevron.svg"
|
||||||
|
alt="Chevron"
|
||||||
|
class="data-[open=true]:rotate-180"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="openSettings" class="flex gap-x-2 mt-4">
|
||||||
|
<label for="spacing" class="text-emerald-100">Spacing:</label>
|
||||||
|
|
||||||
|
<select
|
||||||
|
v-model="spacing"
|
||||||
|
name="spacing"
|
||||||
|
id="spacing"
|
||||||
|
class="text-emerald-100 bg-transparent"
|
||||||
|
>
|
||||||
|
<option value="2">2</option>
|
||||||
|
<option value="3">3</option>
|
||||||
|
<option value="4" selected>4</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="openSettings" class="flex gap-x-2">
|
||||||
|
<input v-model="fill" type="checkbox" id="fill" name="fill" checked />
|
||||||
|
<label for="fill" class="text-emerald-100">Fill</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<router-link
|
||||||
|
v-if="openSettings && route.fullPath === '/'"
|
||||||
|
to="/playground"
|
||||||
|
class="text-emerald-100 underline"
|
||||||
|
>
|
||||||
|
Open playground
|
||||||
|
</router-link>
|
||||||
|
<router-link
|
||||||
|
v-else-if="openSettings"
|
||||||
|
to="/"
|
||||||
|
class="text-emerald-100 underline"
|
||||||
|
>
|
||||||
|
Open home
|
||||||
|
</router-link>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { fill, openSettings, spacing } from "../composables/options.ts";
|
||||||
|
import { useRoute } from "vue-router";
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
</script>
|
10
src/composables/options.ts
Normal file
10
src/composables/options.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { computed, ref } from "vue";
|
||||||
|
|
||||||
|
export const openSettings = ref(false);
|
||||||
|
export const spacing = ref("4");
|
||||||
|
export const fill = ref(true);
|
||||||
|
export const options = computed(() => ({
|
||||||
|
spacing: +spacing.value,
|
||||||
|
fill: fill.value,
|
||||||
|
prefix: undefined,
|
||||||
|
}));
|
20
src/main.ts
20
src/main.ts
@ -1,5 +1,19 @@
|
|||||||
import { createApp } from "vue";
|
import { createApp } from "vue/dist/vue.esm-bundler";
|
||||||
import App from "./App.vue";
|
import Home from "./pages/Home.vue";
|
||||||
|
import * as VueRouter from "vue-router";
|
||||||
|
import Playground from "./pages/Playground.vue";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
|
|
||||||
createApp(App).mount("#app");
|
const routes = [
|
||||||
|
{ path: "/", component: Home },
|
||||||
|
{ path: "/playground", component: Playground },
|
||||||
|
];
|
||||||
|
|
||||||
|
const router = VueRouter.createRouter({
|
||||||
|
history: VueRouter.createWebHistory(),
|
||||||
|
routes: routes,
|
||||||
|
});
|
||||||
|
|
||||||
|
const app = createApp({});
|
||||||
|
app.use(router);
|
||||||
|
app.mount("#app");
|
||||||
|
@ -38,16 +38,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex w-full items-center justify-between mt-4">
|
<Settings>
|
||||||
<button @click="() => (openSettings = !openSettings)" class="ml-4">
|
|
||||||
<img
|
|
||||||
:data-open="openSettings"
|
|
||||||
src="/chevron.svg"
|
|
||||||
alt="Chevron"
|
|
||||||
class="data-[open=true]:rotate-180"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
<button
|
||||||
v-if="shown"
|
v-if="shown"
|
||||||
@click="next"
|
@click="next"
|
||||||
@ -62,49 +53,22 @@
|
|||||||
>
|
>
|
||||||
Show
|
Show
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</Settings>
|
||||||
|
|
||||||
<div v-if="openSettings" class="flex gap-x-2 mt-4">
|
|
||||||
<label for="spacing" class="text-emerald-100">Spacing:</label>
|
|
||||||
|
|
||||||
<select
|
|
||||||
v-model="spacing"
|
|
||||||
name="spacing"
|
|
||||||
id="spacing"
|
|
||||||
class="text-emerald-100 bg-transparent"
|
|
||||||
>
|
|
||||||
<option value="2">2</option>
|
|
||||||
<option value="3">3</option>
|
|
||||||
<option value="4" selected>4</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="openSettings" class="flex gap-x-2">
|
|
||||||
<input v-model="fill" type="checkbox" id="fill" name="fill" checked />
|
|
||||||
<label for="fill" class="text-emerald-100">Fill</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, ref } from "vue";
|
import { onMounted, ref } from "vue";
|
||||||
import { levels, Problem } from "./composables/levels.ts";
|
import { levels, Problem } from "../composables/levels.ts";
|
||||||
import Number from "./components/Number.vue";
|
import Number from "../components/Number.vue";
|
||||||
|
import { options } from "../composables/options.ts";
|
||||||
|
import Settings from "../components/Settings.vue";
|
||||||
|
|
||||||
const level = ref(0);
|
const level = ref(0);
|
||||||
const problem = ref<Problem | undefined>();
|
const problem = ref<Problem | undefined>();
|
||||||
const shown = ref(false);
|
const shown = ref(false);
|
||||||
|
|
||||||
const openSettings = ref(false);
|
|
||||||
const spacing = ref("4");
|
|
||||||
const fill = ref(true);
|
|
||||||
const options = computed(() => ({
|
|
||||||
spacing: +spacing.value,
|
|
||||||
fill: fill.value,
|
|
||||||
prefix: undefined,
|
|
||||||
}));
|
|
||||||
|
|
||||||
function next() {
|
function next() {
|
||||||
problem.value = levels[level.value].generate();
|
problem.value = levels[level.value].generate();
|
||||||
shown.value = false;
|
shown.value = false;
|
64
src/pages/Playground.vue
Normal file
64
src/pages/Playground.vue
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex items-center justify-center w-screen h-screen bg-gray-900">
|
||||||
|
<div class="flex items-center justify-center flex-col gap-y-2">
|
||||||
|
<input
|
||||||
|
v-if="forward"
|
||||||
|
v-model="number"
|
||||||
|
type="number"
|
||||||
|
placeholder="Number..."
|
||||||
|
class="rounded-full py-2 px-4 bg-transparent border border-emerald-100 text-emerald-100 focus:outline-none"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Number v-if="forward" :number="number" :options="options" class="mt-2" />
|
||||||
|
|
||||||
|
<div v-if="!forward" class="flex flex-row-reverse gap-x-2 h-[2.375rem]">
|
||||||
|
<div
|
||||||
|
v-for="i in 24 / +spacing"
|
||||||
|
class="flex flex-row-reverse items-end gap-x-1 border-b-[0.375rem] border-b-emerald-100 border-solid w-fit rounded-md"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
v-for="j in +spacing"
|
||||||
|
@click="setBit(i, j)"
|
||||||
|
:data-bit="(number & (2 ** (i * 4 + j))).toString()"
|
||||||
|
:class="`w-2 ${getBit(i, j) ? 'h-8' : 'h-3'} bg-emerald-100 rounded-t-full`"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p v-if="!forward" class="text-emerald-100 text-lg font-semibold">
|
||||||
|
{{ number }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<Settings>
|
||||||
|
<button
|
||||||
|
@click="swap"
|
||||||
|
class="text-emerald-100 border border-emerald-100 rounded-full px-4 py-2"
|
||||||
|
>
|
||||||
|
Swap
|
||||||
|
</button>
|
||||||
|
</Settings>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import Number from "../components/Number.vue";
|
||||||
|
import { options, spacing } from "../composables/options.ts";
|
||||||
|
import { ref } from "vue";
|
||||||
|
import Settings from "../components/Settings.vue";
|
||||||
|
|
||||||
|
const number = ref(0);
|
||||||
|
const forward = ref(true);
|
||||||
|
|
||||||
|
function getBit(i: number, j: number) {
|
||||||
|
return number.value & (2 ** ((i - 1) * 4 + j - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
function setBit(i: number, j: number) {
|
||||||
|
number.value ^= 2 ** ((i - 1) * 4 + j - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function swap() {
|
||||||
|
forward.value = !forward.value;
|
||||||
|
}
|
||||||
|
</script>
|
Loading…
x
Reference in New Issue
Block a user