Adds playground

This commit is contained in:
Daniel Svitan 2024-03-04 21:44:09 +01:00
parent 180faecddf
commit 39b3d2711c
8 changed files with 169 additions and 56 deletions

View File

@ -5,16 +5,21 @@
<link rel="icon" type="image/png" href="/binary.png"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<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>
<body>
<div id="app"></div>
<div id="app">
<router-view></router-view>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
<style>
html, body {
margin: 0;
padding: 0;
}
</style>

View File

@ -9,7 +9,8 @@
"preview": "vite preview"
},
"dependencies": {
"vue": "^3.4.19"
"vue": "^3.4.19",
"vue-router": "4"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.0.4",

View File

@ -1,7 +1,6 @@
<template>
<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" />
<p v-else class="text-emerald-100 text-3xl">{{ bit }}</p>
</template>
<script setup lang="ts">

View 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>

View 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,
}));

View File

@ -1,5 +1,19 @@
import { createApp } from "vue";
import App from "./App.vue";
import { createApp } from "vue/dist/vue.esm-bundler";
import Home from "./pages/Home.vue";
import * as VueRouter from "vue-router";
import Playground from "./pages/Playground.vue";
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");

View File

@ -38,16 +38,7 @@
</div>
</div>
<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>
<Settings>
<button
v-if="shown"
@click="next"
@ -62,49 +53,22 @@
>
Show
</button>
</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>
</Settings>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from "vue";
import { levels, Problem } from "./composables/levels.ts";
import Number from "./components/Number.vue";
import { onMounted, ref } from "vue";
import { levels, Problem } from "../composables/levels.ts";
import Number from "../components/Number.vue";
import { options } from "../composables/options.ts";
import Settings from "../components/Settings.vue";
const level = ref(0);
const problem = ref<Problem | undefined>();
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() {
problem.value = levels[level.value].generate();
shown.value = false;

64
src/pages/Playground.vue Normal file
View 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>