feat: Add configurable transition speed for route animations

This commit introduces a new feature allowing you to control the speed
of route transitions.

Changes include:
- Added `transitionSpeed` state (defaulting to 1 for normal) and a
  `setTransitionSpeed` action to `ui/src/stores/useUi.js`. The speed
  is a multiplier for the base transition duration.
- `transitionSpeed` is now persisted to local storage.
- Modified `ui/src/App.vue` to dynamically calculate and apply the
  transition duration using a CSS variable (`--current-transition-duration`)
  based on the `transitionSpeed` from the store. The base duration for
  normal speed is 0.3s.
- Added a new "Animation Speed" setting in `ui/src/views/SettingsView.vue`
  with options (Slow, Normal, Fast) using radio buttons. This control
  updates the `transitionSpeed` in the UI store.

This allows you to customize the feel of the application's navigation
transitions to your preference.
This commit is contained in:
google-labs-jules[bot]
2025-05-31 08:31:45 +00:00
parent 5edc9da769
commit cd2f62c89d
3 changed files with 47 additions and 4 deletions

View File

@@ -26,6 +26,26 @@
<input type="checkbox" id="desktopNavbarPersistent" v-model="ui.desktopNavbarPersistent" @change="ui.setDesktopNavbarPersistent($event.target.checked)"
class="custom-checkbox relative w-10 h-5 appearance-none bg-gray-300 dark:bg-gray-600 rounded-full cursor-pointer transition-colors duration-300 ease-in-out checked:bg-[var(--primary-color)] focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-[var(--primary-color)] focus:ring-offset-[var(--background-color)]">
</div>
<!-- Animation Speed Setting -->
<div class="setting-item mt-6 md:col-span-2"> <!-- md:col-span-2 to make it take full width on medium screens if the grid has 2 columns -->
<label class="block text-sm font-medium mb-1 text-[var(--text-color)]">Animation Speed</label>
<p class="text-xs text-gray-500 dark:text-gray-400 mb-2">
Adjust the speed of screen transitions (applied if animations are enabled).
</p>
<div class="flex flex-col space-y-1 sm:flex-row sm:space-y-0 sm:space-x-4">
<label v-for="option in speedOptions" :key="option.value"
class="flex items-center p-2 rounded-md hover:bg-gray-200/50 dark:hover:bg-gray-700/50 cursor-pointer transition-colors duration-150 ease-in-out border border-gray-300 dark:border-gray-600 hover:border-[var(--primary-color)]">
<input type="radio"
name="transitionSpeed"
:value="option.value"
:checked="ui.transitionSpeed === option.value"
@change="ui.setTransitionSpeed(option.value)"
class="form-radio h-4 w-4 text-[var(--primary-color)] focus:ring-1 focus:ring-[var(--primary-color)] border-gray-300 dark:border-gray-500 bg-white dark:bg-gray-800 focus:ring-offset-white dark:focus:ring-offset-gray-900">
<span class="ml-2 text-sm text-[var(--text-color)]">{{ option.label }} <span class="text-xs text-gray-500 dark:text-gray-400">({{ option.value }}x)</span></span>
</label>
</div>
</div>
</div>
</section>
@@ -211,6 +231,12 @@ onMounted(() => {
isMounted.value = true
}, 50)
})
const speedOptions = [
{ label: 'Slow', value: 2 },
{ label: 'Normal', value: 1 },
{ label: 'Fast', value: 0.5 },
]
</script>
<style scoped>