Skip to content

Commit

Permalink
Re-implemented scrollbar for timeline
Browse files Browse the repository at this point in the history
Re-implemented vertical scrolling for timeline
Fixed timeline build
  • Loading branch information
Joery-M committed Mar 24, 2024
1 parent cade89e commit dcce030
Show file tree
Hide file tree
Showing 12 changed files with 276 additions and 173 deletions.
44 changes: 0 additions & 44 deletions packages/safelight/src/components/Editor/Timeline/Timeline.vue

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
</template>
<template #content>
<div style="min-height: 250px">
<Timeline :items="items" />
<Timeline :items="items" invert- />
</div>
</template>
</Card>
Expand Down Expand Up @@ -56,7 +56,7 @@ const items = reactive<TimelineItem[]>([
name: '30 start',
start: 30,
duration: 770,
layer: 7
layer: 17
},
{
id: uuidv4(),
Expand Down Expand Up @@ -88,3 +88,7 @@ body {
overscroll-behavior-x: none;
}
</style>

<route lang="json">
{ "path": "/dev/timeline" }
</route>
1 change: 1 addition & 0 deletions packages/safelight/tsconfig.app.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"compilerOptions": {
"composite": true,
"noEmit": false,
"moduleResolution": "Bundler",

"verbatimModuleSyntax": true,
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
Expand Down
35 changes: 14 additions & 21 deletions packages/timeline/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,28 @@
"author": "Joery Münninghoff",
"license": "MIT",
"type": "module",
"typings": "dist/src/index.d.ts",
"main": "src/index.ts",
"browser": "src/index.ts",
"module": "src/index.ts",
"files": [
"dist"
],
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"exports": {
".": {
"types": "./dist/src/index.d.ts",
"import": [
"./src/index.ts",
"./dist/index.mjs"
],
"require": [
"./src/index.ts",
"./dist/index.cjs"
]
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
},
"./*": [
"./packages/timeline/src/*",
"./src/*"
]
],
"./style.css": "./dist/style.css"
},
"files": [
"dist",
"src"
],
"types": "./dist/index.d.ts",
"scripts": {
"dev": "pnpm \"/build:/\" --watch",
"build": "pnpm \"/build:/\"",
"build:vite": "vite build --emptyOutDir"
"build:vite": "vite build",
"build:tsc": "vue-tsc --emitDeclarationOnly"
},
"dependencies": {
"@safelight/shared": "workspace:*",
Expand All @@ -51,7 +44,7 @@
"jsdom": "^24.0.0",
"typescript": "^5.4.3",
"vite": "^5.2.4",
"vite-plugin-dts": "^3.7.3",
"vitest": "^1.4.0"
"vitest": "^1.4.0",
"vue-tsc": "^2.0.7"
}
}
4 changes: 1 addition & 3 deletions packages/timeline/src/LayerControl.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
</template>

<script setup lang="ts">
import { useEventListener } from '@vueuse/core';
import { computed, inject, ref } from 'vue';
import type { TimelineViewport } from '.';
Expand All @@ -41,8 +40,7 @@ const startHeight = ref(0);
const minHeight = 22;
useEventListener('mousemove', resizing);
useEventListener('mouseup', endResize);
defineExpose({ resizing, endResize });
function startResize(ev: MouseEvent) {
isResizing.value = true;
Expand Down
146 changes: 104 additions & 42 deletions packages/timeline/src/Timeline.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,32 @@
<Splitter id="horizontalContainer">
<SplitterPanel id="layerControls" :min-size="2" :size="10">
<template v-for="i in viewport.highestLayer.value + 1" :key="i">
<LayerControl :layer="i - 1" />
<LayerControl ref="layerControls" :layer="i - 1" />
</template>
</SplitterPanel>
<SplitterPanel id="verticalContainer" :size="90">
<div id="timelineItemContainer" ref="target">
<template v-for="item in props.items" :key="item.id">
<TimelineItemComponent :item="item" @item-change="updateItem" />
<TimelineItemComponent
v-if="viewport.isItemVisible(item)"
:item="item"
@item-change="updateItem"
/>
</template>
</div>
<div class="scrollbarContainer horizontal">
<div
ref="horizontalScroll"
:style="{
left: scrollbarLeft + '%',
width: scrollbarWidth + '%'
}"
@mousedown="startResize"
></div>
</div>
</SplitterPanel>
</Splitter>
<p>{{ useRound(viewport.getTimePosition(0)) }}</p>
<p>{{ useRound(viewport.getTimePosition(100)) }}</p>
<p>{{ useRound(bounds.width) }} px</p>
<input
v-model.number="viewport.startTime.value"
Expand All @@ -39,41 +53,39 @@ import { useWheel } from '@vueuse/gesture';
import { useRound } from '@vueuse/math';
import Splitter from 'primevue/splitter';
import SplitterPanel from 'primevue/splitterpanel';
import { provide, ref, watch } from 'vue';
import { TimelineViewport, type TimelineAlignment, type TimelineItem } from './index';
import { computed, provide, ref, watch } from 'vue';
import { TimelineViewport, type TimelineProps, type TimelineItem } from './index';
import LayerControl from './LayerControl.vue';
import TimelineItemComponent from './TimelineItemComponent.vue';
const target = ref<HTMLDivElement>();
const horizontalScroll = ref<HTMLDivElement>();
const pointerOut = useMouseInElement(target).isOutside;
const props = withDefaults(
defineProps<{
items: { [id: string]: TimelineItem };
alignment?: TimelineAlignment;
zoomFactor?: number;
invertScrollAxes?: boolean;
}>(),
{
items: () => ({}),
alignment: 'bottom',
zoomFactor: 1.02,
invertScrollAxes: false
}
);
const props = withDefaults(defineProps<TimelineProps>(), {
items: () => ({}),
alignment: 'bottom',
zoomFactor: 2,
invertScrollAxes: false,
invertHorizontalScroll: false,
invertVerticalScroll: false
});
const emit = defineEmits<{
'update:modelValue': any[];
}>();
const items = useVModel(props, 'items', emit);
const layerControls = ref<(typeof LayerControl)[]>([]);
const viewport = new TimelineViewport();
provide('viewport', viewport);
watch(props, () => {
watchImmediate(props, () => {
viewport.alignment.value = props.alignment;
viewport.zoomFactor.value = props.zoomFactor;
});
watchImmediate(items.value, () => {
Expand Down Expand Up @@ -111,14 +123,19 @@ useWheel(
if (ev.ctrlKey) {
// Zooming
const mouseX = ev.event.clientX - bounds.left.value;
const mouseXPerc = mouseX / bounds.width.value;
console.log(mouseXPerc);
viewport.zoom(ev.delta[1], mouseXPerc);
} else {
// Scrolling
viewport.move(ev.delta[1]);
const shift = props.invertScrollAxes ? !ev.shiftKey : ev.shiftKey;
if (shift) {
const invert = props.invertVerticalScroll ? -1 : 1;
viewport.moveY(ev.delta[1] * invert);
} else {
const invert = props.invertHorizontalScroll ? -1 : 1;
viewport.move(ev.delta[1] * invert);
}
}
},
{
Expand All @@ -137,6 +154,47 @@ function updateItem(newItem: TimelineItem) {
items.value[newItem.id] = newItem;
}
//#endregion
//#region Scrollbar
const scrollbarLeft = computed(
() => (viewport.startTime.value / (viewport.maxTime.value + viewport.endPadding)) * 100
);
const scrollbarWidth = computed(
() =>
((viewport.endTime.value - viewport.startTime.value) /
(viewport.maxTime.value + viewport.endPadding)) *
100
);
useEventListener('mousemove', resizing);
useEventListener('mouseup', endResize);
const isHoldingHorizontal = ref(false);
const horizontalLastX = ref(0);
function startResize(ev: MouseEvent) {
isHoldingHorizontal.value = true;
horizontalLastX.value = ev.clientX;
}
function resizing(ev: MouseEvent) {
layerControls.value.forEach((lc) => lc.resizing(ev));
if (isHoldingHorizontal.value) {
window.getSelection()?.removeAllRanges();
// Feels hacky, but it works
viewport.move(viewport.getTimePosition(ev.clientX - horizontalLastX.value) * 2.175);
horizontalLastX.value = ev.clientX;
}
}
function endResize(ev: MouseEvent) {
layerControls.value.forEach((lc) => lc.endResize(ev));
if (isHoldingHorizontal.value) {
isHoldingHorizontal.value = false;
}
}
//#endregion
</script>

Expand All @@ -145,6 +203,9 @@ function updateItem(newItem: TimelineItem) {
#horizontalContainer {
display: flex;
resize: both;
overflow: auto;
height: 250px;
}
#verticalContainer {
flex-grow: 1;
Expand All @@ -156,7 +217,6 @@ function updateItem(newItem: TimelineItem) {
height: 100%;
width: 100%;
overflow: hidden;
min-height: 250px;
scroll-behavior: smooth;
}
Expand All @@ -178,22 +238,24 @@ function updateItem(newItem: TimelineItem) {
// }
// TODO: Add scrollbars
// .scrollbarContainer {
// background-color: color.change(white, $alpha: 0.05);
// overflow: hidden;
// &.horizontal {
// height: 0.5rem;
// }
// &.vertical {
// width: 0.5rem;
// }
// > div {
// background-color: color.change(white, $alpha: 0.5);
// border-radius: 0.25rem;
// height: 100%;
// }
// }
.scrollbarContainer {
background-color: color.change(white, $alpha: 0.05);
overflow: hidden;
position: relative;
&.horizontal {
height: 0.25rem;
}
&.vertical {
width: 0.25rem;
}
> div {
background-color: color.change(white, $alpha: 0.5);
border-radius: 0.25rem;
height: 100%;
position: absolute;
}
}
</style>
Loading

0 comments on commit dcce030

Please sign in to comment.