Skip to content

Commit

Permalink
Now there is a brush slider and simulation can be stepped
Browse files Browse the repository at this point in the history
  • Loading branch information
Nrosa01 committed May 10, 2024
1 parent ab2ee01 commit ef6827c
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 23 deletions.
Binary file modified src/assets/app.wasm
Binary file not shown.
96 changes: 96 additions & 0 deletions src/components/BrushSlider.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<script setup>
import { ref, computed, watch, onMounted, onUnmounted } from "vue";
import { useSound } from "@vueuse/sound";
import slider from "../assets/sounds/hover.wav";
const { play: playSlider } = useSound(slider, { volume: 0.5, interrupt: false });
const value = ref(25);
const brush_size = computed(() => {
let diagonal = 800 * Math.sqrt(2);
let maxRadius = diagonal / 2;
let fraction = value.value / 100;
let radius = Math.pow(fraction, 2) * maxRadius;
let minRadius = 10; // This is the minimum radius of the brush at wich we can paint
radius = Math.max(minRadius, radius);
return Math.round(radius);
});
const thumbSize = computed(() => {
let minSize = 15;
let maxSize = 30;
let size = ((value.value / 100) * (maxSize - minSize)) + minSize;
return Math.round(size) + 'px';
});
let sliderValueChangeTimer = null;
watch(brush_size, (newSize) => {
const delta = Math.max(-1, Math.min(1, brush_size.value - value.value));
// If a timer is already running, don't start another one
if (sliderValueChangeTimer) return;
// Start a timer to play the slider after 75ms
sliderValueChangeTimer = setTimeout(() => {
playSlider({ playbackRate: delta > 0 ? 0.8 : 0.75 });
// Clear the timer
sliderValueChangeTimer = null;
}, 15)
wasm_exports.set_brush_size(js_object(newSize.toString()));
});
function onWheel(event) {
const sensitivity = 2.5;
let valueInt = parseInt(value.value);
let newValue = valueInt + (event.deltaY > 0 ? -sensitivity : sensitivity);
value.value = Math.min(100, Math.max(1, newValue));
}
onMounted(() => {
document.addEventListener("wheel", onWheel)
wasm_exports.set_brush_size(js_object(brush_size.value.toString()));
});
onUnmounted(() => document.removeEventListener("wheel", onWheel))
</script>

<style scoped>
.slider {
-webkit-appearance: none;
appearance: none;
height: 0.5rem;
background: #d3d3d3;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: v-bind(thumbSize);
height: v-bind(thumbSize);
border-radius: 50%;
background: #97a2b1;
border: 2px solid #000000;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: v-bind(thumbSize);
height: v-bind(thumbSize);
border-radius: 50%;
background: #97a2b1;
border: 2px solid #000000;
cursor: pointer;
}
</style>

<template>
<input type="range" min="1" max="100" v-model="value" class="slider">
</template>
21 changes: 0 additions & 21 deletions src/components/Canvas.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
import { onMounted, onUnmounted, ref } from "vue";
import { useSound } from "@vueuse/sound";
import click from "../assets/sounds/add_particle.wav";
import slider from "../assets/sounds/hover.wav";
const playbackRate = ref(1.0);
const { play } = useSound(click, { volume: 0.5, playbackRate, interrupt: false });
const { play: playSlider } = useSound(slider, { volume: 0.5, interrupt: false });
let timer = null;
Expand Down Expand Up @@ -83,23 +81,6 @@ const onPointerEnter = () => {
}
};
let mouseWheelTimer = null;
const onMouseWheel = (event) => {
const delta = Math.max(-1, Math.min(1, event.deltaY));
// If a timer is already running, don't start another one
if (mouseWheelTimer) return;
// Start a timer to play the slider after 75ms
mouseWheelTimer = setTimeout(() => {
playSlider({ playbackRate: delta > 0 ? 0.8 : 0.75 });
// Clear the timer
mouseWheelTimer = null;
}, 15);
};
onMounted(() => {
// There is an existing canvas with id glcanvas. I want to move that canvas to this component
const glcanvas = document.getElementById("glcanvas");
Expand All @@ -112,7 +93,6 @@ onMounted(() => {
canvas.value.addEventListener("pointerup", onPointerUp);
canvas.value.addEventListener("pointerout", onPointerOut);
canvas.value.addEventListener("pointerenter", onPointerEnter);
canvas.value.addEventListener("wheel", onMouseWheel);
// Trigger windows resize event to make the canvas resize
window.dispatchEvent(new Event("resize"));
Expand All @@ -123,7 +103,6 @@ onUnmounted(() => {
canvas.value.removeEventListener("pointerup", onPointerUp);
canvas.value.removeEventListener("pointerout", onPointerOut);
canvas.value.removeEventListener("pointerenter", onPointerEnter);
canvas.value.removeEventListener("wheel", onMouseWheel);
});
</script>
Expand Down
15 changes: 13 additions & 2 deletions src/components/CanvasControls.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import click from "../assets/sounds/select.wav";
import hover from "../assets/sounds/hover.wav";
import { useSimulationStore } from "../stores/simulation";
import BlockDialog from "./BlockDialog.vue";
import BrushSlider from "./BrushSlider.vue";
const { play } = useSound(click, { volume: 0.5, interrupt: true });
const { play: playHover } = useSound(hover, { volume: 0.5, interrupt: false });
Expand Down Expand Up @@ -53,6 +54,7 @@ async function resize_simulation(previous_size, new_size, duration) {
var t = (Date.now() - start) / duration;
var value = lerp(current, new_size, t);
wasm_exports.resize_simulation(js_object(Math.round(value).toString()));
store.canvas_size = Math.round(value);
await new Promise((r) => setTimeout(r, 1000 / 60));
}
Expand Down Expand Up @@ -80,17 +82,25 @@ function playHoverSound() {
}
}
function stepSimulation() {
wasm_exports.step_simulation();
play();
}
function showModal(e) {
modal.value.showModal();
}
</script>

<template>
<div class="flex w-full gap-2 flex-wrap justify-between items-center bg-slate-600/50 rounded-xl mb-4 p-2">
<div class="flex gap-2 flex-wrap justify-start items-center grow">
<button @mouseenter="playHoverSound" :class="buttonClass" @click="togglePause">
<div class="flex gap-2 flex-wrap justify-start items-center grow" v-auto-animate="{ duration: 100 }">
<button @mouseenter="playHoverSound" :class="buttonClass" @click="togglePause" :title="[paused ? 'Unpause the simulation' : 'Pause the simulation']">
<i :class="['ph-duotone', paused ? 'ph-play' : 'ph-pause']"></i>
</button>
<button @mouseenter="playHoverSound" v-if="paused" :class="buttonClass" @click="stepSimulation" title="Run the simulation once">
<i class="ph ph-caret-line-right font-black"></i>
</button>
<button @mouseenter="playHoverSound" :class="buttonClass" title="Clear all the particles" @click="clear"><i
class="ph-duotone ph-broom"></i></button>
<button @mouseenter="playHoverSound" :class="buttonClass"
Expand All @@ -110,6 +120,7 @@ function showModal(e) {
<option value="150" selected>Normal</option>
<option value="300">Big</option>
</select>
<BrushSlider></BrushSlider>
</div>

<button @mouseenter="playHoverSound" :class="buttonClass" title="Clear all the particles" @click="showModal"><i class="text-orange-400 ph-duotone ph-question"></i></button>
Expand Down

0 comments on commit ef6827c

Please sign in to comment.