diff --git a/public/iconfont.css b/public/iconfont.css index 3872182..1552658 100644 --- a/public/iconfont.css +++ b/public/iconfont.css @@ -1,6 +1,6 @@ @font-face { font-family: "iconfont"; /* Project id 4440655 */ - src: url('iconfont.woff2?t=1723382481292') format('woff2'); + src: url('iconfont.woff2?t=1725033317914') format('woff2'); } .iconfont { @@ -11,6 +11,10 @@ -moz-osx-font-smoothing: grayscale; } +.icon-axis:before { + content: "\ed1f"; +} + .icon-add-line:before { content: "\e7b0"; } diff --git a/public/iconfont.woff2 b/public/iconfont.woff2 index 11a952b..1e1f7fe 100644 Binary files a/public/iconfont.woff2 and b/public/iconfont.woff2 differ diff --git a/src/App.vue b/src/App.vue index 9c40918..7fbf1a9 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2,8 +2,8 @@ - - + + @@ -27,7 +27,7 @@ import { getCrossOriginWorkerURL } from '@/hook/network'; import ToolBar from '@/components/toolbar'; import Sidebar from '@/components/sidebar'; import RightNav from '@/components/right-nav.vue'; -import MainRender from '@/components/render'; +import Pivot from '@/components/pivot'; const { t } = useI18n(); diff --git a/src/components/render/cursor.js b/src/components/pivot/cursor.js similarity index 57% rename from src/components/render/cursor.js rename to src/components/pivot/cursor.js index 3889446..f49e923 100644 --- a/src/components/render/cursor.js +++ b/src/components/pivot/cursor.js @@ -2,30 +2,53 @@ import { globalLookup } from '@/hook/global'; import formatTime from '@/hook/wave-view/format-time'; import { reactive } from 'vue'; -export const StaticCursor = reactive({ +/** + * @typedef {(event: MouseEvent) => void} MousemoveFn + */ + +export const MovingPivot = reactive({ + color: '#CB81DA', + label: '', + left: 0, + currentTime: 0, + show: true, + + /** + * @type {import('./pivot-view').UserPivot | undefined} + */ + currentTakenPivot: undefined, + dragEnable: false +}); + +export const SystemPivot = reactive({ label: '', show: false, currentTime: 0, left: 0, + color: '#CB81DA', updateLabel(timescale) { this.label = formatTime(this.currentTime, timescale); - this.show = true; }, updateLeft() { this.left = calcCursorLeft(this.currentTime); - this.show = true; } }); -export function changeCursorLocation() { - StaticCursor.show = true; +/** + * @description 左击改变系统信标的位置 + */ +export function changeCursorLocation() { + if (MovingPivot.dragEnable) { + return; + } + SystemPivot.show = true; const pstate = globalLookup.pstate; if (pstate) { const { xCursor, xOffset, xScale, tgcd, timescale } = pstate; const currentTime = Math.round((xCursor - xOffset) / xScale) * tgcd; - StaticCursor.currentTime = currentTime; - StaticCursor.updateLabel(timescale); - StaticCursor.updateLeft(); + SystemPivot.currentTime = currentTime; + SystemPivot.updateLabel(timescale); + SystemPivot.updateLeft(); } } @@ -44,6 +67,7 @@ export function calcCursorLeft(currentTime) { return 0; } -export const MovingCursor = reactive({ - -}); \ No newline at end of file +/** + * @type {Map} + */ +export const mousemoveEventPipes = new Map(); \ No newline at end of file diff --git a/src/components/render/index.vue b/src/components/pivot/index.vue similarity index 56% rename from src/components/render/index.vue rename to src/components/pivot/index.vue index b3c54c5..15c698b 100644 --- a/src/components/render/index.vue +++ b/src/components/pivot/index.vue @@ -1,18 +1,47 @@ - \ No newline at end of file diff --git a/src/components/pivot/pivot-view.js b/src/components/pivot/pivot-view.js new file mode 100644 index 0000000..f9fd09a --- /dev/null +++ b/src/components/pivot/pivot-view.js @@ -0,0 +1,138 @@ +import { reactive, ref } from "vue"; +import { calcCursorLeft, SystemPivot } from "./cursor"; +import { globalLookup } from "@/hook/global"; +import formatTime from "@/hook/wave-view/format-time"; + +/** + * @description 每一个动态信标 + * @typedef {Object} UserPivot + * @property {number} id + * @property {string} label + * @property {number} x + * @property {number} time + * @property {boolean} show + */ + + +/** + * @description 该数据结构描述了所有通过 makePivot 创建的 用户信标 + * @type {Map} + */ +export const UserPivots = reactive(new Map()); +export const orderedTimes = []; + +export const UserPivotColor = ref('#1e90ff'); + +/** + * @description 创建一个信标 + * @param {number} time 需要创建的轴的时间点 + */ +export function createPivot(time) { + if (UserPivots.has(time)) { + return; + } + + const id = Date.now(); + const x = calcCursorLeft(time); + const timescale = globalLookup.timescale; + const label = formatTime(time, timescale); + const show = true; + + UserPivots.set(time, { time, x, id, label, show }); + orderedTimes.push(time); + orderedTimes.sort((a, b) => a < b); +} + +export function searchOrderedTimeIndex(time) { + for (let i = 0; i < orderedTimes.length; ++ i) { + if (orderedTimes[i] === time) { + return i; + } + } + return undefined; +} + +export function deletePivot(time) { + if (!UserPivots.has(time)) { + return; + } + + UserPivots.delete(time); + const i = searchOrderedTimeIndex(time); + if (i !== undefined) { + orderedTimes.splice(i, 1); + } +} + +export function updateAllPivots() { + // 更新系统信标 + SystemPivot.updateLeft(); + + // 更新所有用户信标 + for (const time of UserPivots.keys()) { + const pivot = UserPivots.get(time); + pivot.x = calcCursorLeft(time); + } +} + +/** + * + * @param {number[]} times + * @param {number} target 目标时间 + * @returns + */ +function bisearch(times, target) { + let i = 0, j = times.length - 1; + while (i < j) { + if (times[i] === target) { + break; + } + if (times[j] <= target) { + i = j; + break; + } + if (j - i === 1) { + break; + } + const mid = (i + j) >> 1; + if (times[mid] > target) { + j = mid; + } else { + i = mid; + } + } + + return i; +} + +/** + * @description 高效获取距离 time 最近的时间点 t,时间复杂度 O(logn) + * @param {number} time + * @returns {UserPivot | undefined} + */ +export function getNearestUserPivot(time) { + const pivotNum = UserPivots.size; + if (pivotNum === 0) { + return undefined; + } + + if (pivotNum === 1) { + for (const [time, pivot] of UserPivots) { + return pivot; + } + } + + const i = bisearch(orderedTimes, time); + // console.log(i, orderedTimes, time); + + if (i === pivotNum - 1) { + return UserPivots.get(orderedTimes[i]); + } + + const prevT = orderedTimes[i]; + const nextT = orderedTimes[i + 1]; + if (nextT - time > time - prevT) { + return UserPivots.get(prevT); + } + return UserPivots.get(nextT); +} diff --git a/src/components/pivot/pivot-view.vue b/src/components/pivot/pivot-view.vue new file mode 100644 index 0000000..db85156 --- /dev/null +++ b/src/components/pivot/pivot-view.vue @@ -0,0 +1,27 @@ + + + \ No newline at end of file diff --git a/src/components/render/cursor.vue b/src/components/pivot/system-pivot.vue similarity index 75% rename from src/components/render/cursor.vue rename to src/components/pivot/system-pivot.vue index 9089329..7ae627e 100644 --- a/src/components/render/cursor.vue +++ b/src/components/pivot/system-pivot.vue @@ -1,48 +1,65 @@ \ No newline at end of file diff --git a/src/components/pivot/user-pivot.vue b/src/components/pivot/user-pivot.vue new file mode 100644 index 0000000..0d9691d --- /dev/null +++ b/src/components/pivot/user-pivot.vue @@ -0,0 +1,232 @@ + + + + + \ No newline at end of file diff --git a/src/components/render/time-scale.vue b/src/components/render/time-scale.vue deleted file mode 100644 index 229f79d..0000000 --- a/src/components/render/time-scale.vue +++ /dev/null @@ -1,135 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/components/setting/index.vue b/src/components/setting/index.vue index 57e6067..9255d50 100644 --- a/src/components/setting/index.vue +++ b/src/components/setting/index.vue @@ -10,6 +10,7 @@ name="language-setting" class="language-setting" v-model="locale" + @change="onlanguagechange" > + + + {{ t('setting.language.change-dialog') }} + +