增加对于 mac 的支持 | 重构按键映射代码
This commit is contained in:
parent
703ba8a58c
commit
55f0c5c93b
26
README.md
26
README.md
@ -1,24 +1,6 @@
|
||||
# digital-wavetrace
|
||||
|
||||
## Project setup
|
||||
```
|
||||
npm install
|
||||
```
|
||||
## build
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||
```bash
|
||||
python scripts/vscode-package.py
|
||||
```
|
13
package-lock.json
generated
13
package-lock.json
generated
@ -26,6 +26,7 @@
|
||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"ignore-loader": "^0.1.2",
|
||||
"unplugin-auto-import": "^0.17.5",
|
||||
"unplugin-vue-components": "^0.26.0"
|
||||
}
|
||||
@ -6991,6 +6992,12 @@
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/ignore-loader": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore-loader/-/ignore-loader-0.1.2.tgz",
|
||||
"integrity": "sha512-yOJQEKrNwoYqrWLS4DcnzM7SEQhRKis5mB+LdKKh4cPmGYlLPR0ozRzHV5jmEk2IxptqJNQA5Cc0gw8Fj12bXA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/import-fresh": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||
@ -17333,6 +17340,12 @@
|
||||
"integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
|
||||
"dev": true
|
||||
},
|
||||
"ignore-loader": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore-loader/-/ignore-loader-0.1.2.tgz",
|
||||
"integrity": "sha512-yOJQEKrNwoYqrWLS4DcnzM7SEQhRKis5mB+LdKKh4cPmGYlLPR0ozRzHV5jmEk2IxptqJNQA5Cc0gw8Fj12bXA==",
|
||||
"dev": true
|
||||
},
|
||||
"import-fresh": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||
|
@ -26,6 +26,7 @@
|
||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"ignore-loader": "^0.1.2",
|
||||
"unplugin-auto-import": "^0.17.5",
|
||||
"unplugin-vue-components": "^0.26.0"
|
||||
},
|
||||
|
@ -1,16 +1,43 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4440655 */
|
||||
src: url('iconfont.woff2?t=1713691301672') format('woff2');
|
||||
src: url('iconfont.woff2?t=1715948037690') format('woff2');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-arrow-right:before {
|
||||
content: "\eb08";
|
||||
}
|
||||
|
||||
.icon-arrow-left:before {
|
||||
content: "\eb09";
|
||||
}
|
||||
|
||||
.icon-arrow-down:before {
|
||||
content: "\eb0a";
|
||||
}
|
||||
|
||||
.icon-arrow-up:before {
|
||||
content: "\eb0b";
|
||||
}
|
||||
|
||||
.icon-command:before {
|
||||
content: "\e604";
|
||||
}
|
||||
|
||||
.icon-minus:before {
|
||||
content: "\e656";
|
||||
}
|
||||
|
||||
.icon-equal:before {
|
||||
content: "\e701";
|
||||
}
|
||||
|
||||
.icon-ctrl:before {
|
||||
content: "\e605";
|
||||
}
|
||||
|
Binary file not shown.
@ -11,11 +11,12 @@
|
||||
<link rel="stylesheet" href="vscode.css">
|
||||
<link rel="stylesheet" href="vcd.css">
|
||||
<link rel="stylesheet" href="iconfont.css">
|
||||
<script src="vcd.js"></script>
|
||||
<!-- <script src="vcd.js"></script> -->
|
||||
<script></script>
|
||||
|
||||
<script>
|
||||
window.readVcdFile = async () => {
|
||||
const response = await fetch('pe_tb.vcd');
|
||||
const response = await fetch('test.vcd');
|
||||
const blob = await response.blob();
|
||||
const reader = new FileReader();
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -26,6 +27,8 @@
|
||||
reader.readAsArrayBuffer(blob);
|
||||
});
|
||||
}
|
||||
window.workerPath = 'worker.js';
|
||||
window.workerRoot = '';
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
BIN
public/vcd.wasm
BIN
public/vcd.wasm
Binary file not shown.
@ -1,9 +1,18 @@
|
||||
importScripts('vcd.js');
|
||||
|
||||
self.onmessage = async event => {
|
||||
const arrayBuffer = event.data;
|
||||
const { arrayBuffer, workerRoot } = event.data;
|
||||
|
||||
self.locateFile = wasmBinaryFile => {
|
||||
if (workerRoot) {
|
||||
return workerRoot + (workerRoot.endsWith('/') ? '': '/') + wasmBinaryFile;
|
||||
} else {
|
||||
return wasmBinaryFile;
|
||||
}
|
||||
};
|
||||
|
||||
importScripts('vcd.js');
|
||||
|
||||
const vcdstream = await makeVcdStream();
|
||||
vcdstream.consume(arrayBuffer);
|
||||
const info = vcdstream.getBasicInfo();
|
||||
self.postMessage(info);
|
||||
}
|
||||
};
|
14
scripts/vscode-package.py
Normal file
14
scripts/vscode-package.py
Normal file
@ -0,0 +1,14 @@
|
||||
import os
|
||||
|
||||
os.system('npm run build')
|
||||
for file in os.listdir('dist'):
|
||||
if file.endswith('.vcd'):
|
||||
os.remove('dist/' + file)
|
||||
|
||||
with open('./dist/index.html', 'r', encoding='utf-8') as fp:
|
||||
html = fp.read()
|
||||
|
||||
html = html.replace("''", "'<workerRoot>'")
|
||||
|
||||
with open('./dist/index.html', 'w', encoding='utf-8') as fp:
|
||||
fp.write(html)
|
@ -22,6 +22,7 @@ import { ElLoading } from 'element-plus';
|
||||
|
||||
import { emitter, globalLookup, globalSetting } from '@/hook/global';
|
||||
import { makeWaveView } from '@/hook/render';
|
||||
import { getCrossOriginWorkerURL } from '@/hook/network';
|
||||
|
||||
import Sidebar from '@/components/sidebar.vue';
|
||||
import RightNav from '@/components/right-nav.vue';
|
||||
@ -83,13 +84,13 @@ onMounted(async () => {
|
||||
|
||||
// 初始化载入 vcd 文件
|
||||
const arrayBuffer = await window.readVcdFile();
|
||||
|
||||
const worker = new Worker('worker.js', {
|
||||
const url = await getCrossOriginWorkerURL(window.workerPath);
|
||||
const worker = new Worker(url, {
|
||||
name: 'vcd-stream',
|
||||
type: 'classic'
|
||||
});
|
||||
|
||||
worker.postMessage(arrayBuffer, [arrayBuffer]);
|
||||
worker.postMessage({ arrayBuffer, workerRoot: window.workerRoot }, [arrayBuffer]);
|
||||
|
||||
worker.addEventListener('message', event => {
|
||||
const workerVars = event.data;
|
||||
|
@ -3,17 +3,42 @@
|
||||
<div class="usermanual">
|
||||
<h2>{{ t('usermanual') }}</h2>
|
||||
<div class="usermanual-item">
|
||||
<div v-html="t('usermanual.left-right-scroll.title')"></div>
|
||||
<div><span class="iconfont icon-mouse"/><span class="iconfont icon-up-down"/></div>
|
||||
<div>{{ t('usermanual.left-right-scroll.caption') }}</div>
|
||||
</div>
|
||||
<div class="usermanual-item">
|
||||
<div v-html="t('usermanual.up-down-scroll.title')"></div>
|
||||
<div><span class="iconfont icon-mouse"/><span class="iconfont icon-left-right"/></div>
|
||||
<div>{{ t('usermanual.up-down-scroll.caption') }}</div>
|
||||
</div>
|
||||
<div class="usermanual-item">
|
||||
<div v-html="t('usermanual.xscale.title')"></div>
|
||||
<div><span class="iconfont icon-ctrl"/> + <span class="iconfont icon-mouse"/><span class="iconfont icon-up-down"/></div>
|
||||
<div>{{ t('usermanual.xscale.caption') }}</div>
|
||||
</div>
|
||||
<div class="usermanual-item">
|
||||
<div><span class="iconfont icon-shift"/> + <span class="iconfont icon-mouse"/><span class="iconfont icon-up-down"/></div>
|
||||
<div>{{ t('usermanual.up-down-scroll.caption') }}</div>
|
||||
</div>
|
||||
|
||||
<div class="usermanual-item" v-if="platform.startsWith('Mac')">
|
||||
<div><span class="iconfont icon-command"/> + <span class="iconfont icon-mouse"/><span class="iconfont icon-up-down"/></div>
|
||||
<div>{{ t('usermanual.xscale.caption') }}</div>
|
||||
</div>
|
||||
<div class="usermanual-item" v-else>
|
||||
<div><span class="iconfont icon-ctrl"/> + <span class="iconfont icon-equal"/> / <span class="iconfont icon-minus"/></div>
|
||||
<div>{{ t('usermanual.xscale.caption') }}</div>
|
||||
</div>
|
||||
|
||||
<div class="usermanual-item">
|
||||
<div><span class="iconfont icon-shift"/> + <span class="iconfont icon-arrow-up"/> / <span class="iconfont icon-arrow-down"/></div>
|
||||
<div>{{ t('usermanual.left-right-scroll.caption') }}</div>
|
||||
</div>
|
||||
|
||||
<div class="usermanual-item">
|
||||
<div><span class="iconfont icon-shift"/> + <span class="iconfont icon-arrow-left"/> / <span class="iconfont icon-arrow-right"/></div>
|
||||
<div>{{ t('usermanual.up-down-scroll.caption') }}</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<br>
|
||||
@ -44,11 +69,14 @@ export default {
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
|
||||
const platform = navigator.platform;
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
return {
|
||||
goto,
|
||||
t
|
||||
t,
|
||||
platform
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +126,6 @@ export default {
|
||||
/* 沿着纵轴(垂直方向)对齐 */
|
||||
}
|
||||
|
||||
.time-scale-value {}
|
||||
|
||||
.time-scale-line {
|
||||
width: 1px;
|
||||
|
@ -52,7 +52,6 @@ export default {
|
||||
emitter.emit('tree-view', signals);
|
||||
// color change into selected
|
||||
globalLookup.currentModule = module;
|
||||
console.log(module);
|
||||
}
|
||||
|
||||
const expandManage = reactive({
|
||||
|
@ -107,6 +107,7 @@ export default {
|
||||
padding-left: 3px;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
|
||||
|
51
src/hook/network.js
Normal file
51
src/hook/network.js
Normal file
@ -0,0 +1,51 @@
|
||||
const type = 'application/javascript';
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} originalWorkerUrl
|
||||
* @param {{
|
||||
* useBlob?: boolean
|
||||
* skipSameOrigin?: boolean
|
||||
* }} options
|
||||
* @returns {Promise<string>}
|
||||
*/
|
||||
async function getCrossOriginWorkerURL (originalWorkerUrl, options = {}) {
|
||||
const skipSameOrigin = options.skipSameOrigin || true;
|
||||
const useBlob = options.useBlob || true;
|
||||
|
||||
// 本来就是同源的,不需要额外进行处理,直接返回
|
||||
if (!originalWorkerUrl.includes('://') || originalWorkerUrl.includes(window.location.origin)) {
|
||||
return originalWorkerUrl;
|
||||
}
|
||||
|
||||
// 获取 worker 的 js 代码
|
||||
const res = await fetch(originalWorkerUrl);
|
||||
const workerJsCode = await res.text();
|
||||
|
||||
// worker 所在的文件夹 url
|
||||
const workerPath = new URL(originalWorkerUrl).href.split('/');
|
||||
workerPath.pop();
|
||||
|
||||
// 给 importScripts 的每一个引入的js文件增加 workerPath 组成绝对路径
|
||||
const importScriptsFix = `const _importScripts = importScripts;
|
||||
const _fixImports = (url) => new URL(url, '${workerPath.join('/') + '/'}').href;
|
||||
|
||||
importScripts = (...urls) => _importScripts(...urls.map(_fixImports));
|
||||
`;
|
||||
|
||||
// 以 MIME 协议组成 blob,从而进行装载
|
||||
let resultURL = `data:${type},` + encodeURIComponent(importScriptsFix + workerJsCode);
|
||||
if (useBlob) {
|
||||
// 在外面再套一层 importScripts,这样第二次请求得到的 worker 就不是 blob worker 了
|
||||
// 直接使用 createObjectURL 请求一个 worker 的源码是不行的,因为这样得到的 blob worker
|
||||
// 会有原本 worker 的 feature 无法使用
|
||||
resultURL = URL.createObjectURL(
|
||||
new Blob([`importScripts("${resultURL}")`], { type })
|
||||
);
|
||||
}
|
||||
return resultURL;
|
||||
}
|
||||
|
||||
export {
|
||||
getCrossOriginWorkerURL
|
||||
}
|
@ -1,8 +1,13 @@
|
||||
import { globalLookup, globalSetting } from "./global";
|
||||
import { domContainer, pluginRenderTimeGrid, pluginRenderValues, mountTree,
|
||||
genOnWheel, genKeyHandler, keyEvent } from './wave-view';
|
||||
eventHandler } from './wave-view';
|
||||
|
||||
import registerWheelEvent from "./wave-view/wheel-event";
|
||||
import { registerTouchendEvent, registerTouchmoveEvent, registerTouchstartEvent } from "./wave-view/touch-event";
|
||||
|
||||
|
||||
import { findCurrentSignalValue } from './utils';
|
||||
import { registerKeyEvent } from "./wave-view/key-event";
|
||||
|
||||
let mainRenderEl = null;
|
||||
const canvasMap = new Map();
|
||||
@ -36,6 +41,8 @@ function pluginLocalStore(desc, pstate /* , els */) {
|
||||
* @param {HTMLElement} parentElement
|
||||
*/
|
||||
function makeWaveView(parentElement) {
|
||||
const platform = navigator.platform;
|
||||
|
||||
if (!parentElement) {
|
||||
parentElement = getMainRenderEl();
|
||||
}
|
||||
@ -57,7 +64,29 @@ function makeWaveView(parentElement) {
|
||||
console.log('updater');
|
||||
};
|
||||
|
||||
container.elo.container.addEventListener('wheel', genOnWheel(parentElement, container.pstate, globalLookup, keyEvent));
|
||||
// 注册基本的响应事件
|
||||
container.elo.container.addEventListener('wheel',
|
||||
registerWheelEvent(parentElement, container.pstate, globalLookup, eventHandler)
|
||||
);
|
||||
|
||||
// 好像必须是 document
|
||||
document.addEventListener('keydown',
|
||||
registerKeyEvent(parentElement, container.pstate, globalLookup, eventHandler)
|
||||
);
|
||||
|
||||
// TODO: 触控支持
|
||||
// container.elo.container.addEventListener('touchstart',
|
||||
// registerTouchstartEvent(parentElement, container.pstate, globalLookup, eventHandler)
|
||||
// );
|
||||
|
||||
// container.elo.container.addEventListener('touchmove',
|
||||
// registerTouchmoveEvent(parentElement, container.pstate, globalLookup, eventHandler)
|
||||
// );
|
||||
|
||||
// container.elo.container.addEventListener('touchend',
|
||||
// registerTouchendEvent(parentElement, container.pstate, globalLookup, eventHandler)
|
||||
// );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -78,7 +107,7 @@ function toggleRender(signal) {
|
||||
} else {
|
||||
globalLookup.currentWires.add(signal);
|
||||
const signalItem = globalLookup.chango[signal.link];
|
||||
console.log(signalItem, signal.link);
|
||||
// console.log(signalItem, signal.link);
|
||||
|
||||
const { wave, kind } = signalItem;
|
||||
const time = globalLookup.currentTime;
|
||||
|
@ -183,7 +183,7 @@ const domContainer = (obj) => {
|
||||
// TODO : 使用更新的属性替换 contentRect
|
||||
// 未来版本 contentRect 可能会被丢弃
|
||||
let { width, height } = entry.contentRect;
|
||||
console.log(width, height);
|
||||
// console.log(width, height);
|
||||
// height = height || 888;
|
||||
// console.log('resizeObserver', width, height);
|
||||
resizeHandler(width, height);
|
||||
|
@ -16,10 +16,10 @@ const xScaleLevels = {
|
||||
|
||||
// TODO: 优化横向滚动体验
|
||||
const xOffsetLevel = {
|
||||
1: 500,
|
||||
2: 20,
|
||||
3: 5,
|
||||
4: 1,
|
||||
1: 0.035,
|
||||
2: 0.1,
|
||||
3: 0.2,
|
||||
4: 0.4,
|
||||
5: 0.5
|
||||
};
|
||||
|
||||
@ -31,12 +31,12 @@ const yOffsetLevel = {
|
||||
5: 320
|
||||
};
|
||||
|
||||
const pluso = {
|
||||
const scaleUp = {
|
||||
desc: 'Zoom in time',
|
||||
fn: pstate => xScaleUpdate(pstate, () => pstate.xScale * xScaleLevels[globalSetting.HorizontalScalingRatio])
|
||||
};
|
||||
|
||||
const minuso = {
|
||||
const scaleDown = {
|
||||
desc: 'Zoom out time',
|
||||
fn: pstate => xScaleUpdate(pstate, () => pstate.xScale / xScaleLevels[globalSetting.HorizontalScalingRatio])
|
||||
};
|
||||
@ -49,11 +49,19 @@ const fullo = {
|
||||
const scroll = {
|
||||
left: {
|
||||
desc: 'Scroll into the past',
|
||||
fn: pstate => xOffsetUpdate(pstate, () => pstate.xOffset + pstate.time / xOffsetLevel[globalSetting.HorizontalRollRatio])
|
||||
fn: pstate => {
|
||||
const offset = xOffsetLevel[globalSetting.HorizontalRollRatio] * pstate.width;
|
||||
// console.log(`change from ${pstate.xOffset} to ${pstate.xOffset + pstate.time / xOffsetLevel[globalSetting.HorizontalRollRatio]}`);
|
||||
return xOffsetUpdate(pstate, () => pstate.xOffset + offset);
|
||||
}
|
||||
},
|
||||
right: {
|
||||
desc: 'Scroll into the future',
|
||||
fn: pstate => xOffsetUpdate(pstate, () => pstate.xOffset - pstate.time / xOffsetLevel[globalSetting.HorizontalRollRatio])
|
||||
fn: pstate => {
|
||||
// console.log(`change from ${pstate.xOffset} to ${pstate.xOffset - pstate.time / xOffsetLevel[globalSetting.HorizontalRollRatio]}`);
|
||||
const offset = xOffsetLevel[globalSetting.HorizontalRollRatio] * pstate.width;
|
||||
return xOffsetUpdate(pstate, () => pstate.xOffset - offset)
|
||||
}
|
||||
},
|
||||
up: {
|
||||
desc: 'scroll up',
|
||||
@ -73,31 +81,16 @@ const editable = {
|
||||
};
|
||||
|
||||
export default {
|
||||
// Alt + <, >. left / right
|
||||
// 'Alt+,': scroll.left,
|
||||
// 'Alt+.': scroll.right,
|
||||
|
||||
// // Alt + [ ] home / end
|
||||
// 'Alt+[': { desc: 'Jump to beginning of time', fn: pstate => xOffsetUpdate(pstate, pstate.sidebarWidth) }, // Home
|
||||
|
||||
// 'Alt+]': { desc: 'Jump to end time', fn: pstate => xOffsetUpdate(pstate, pstate.width - pstate.xScale * pstate.time) }, // End
|
||||
|
||||
// // ALT + - +
|
||||
// 'Alt+=': pluso, // '+': pluso, '=': pluso,
|
||||
// 'Alt+-': minuso, // '-': minuso, '_': minuso,
|
||||
// 'Alt+0': fullo, // 'Shift+f': fullo, F: fullo, 'Shift+F': fullo,
|
||||
|
||||
// wheel
|
||||
scrollLeft: scroll.left,
|
||||
scrollRight: scroll.right,
|
||||
scrollUp: scroll.up,
|
||||
scrollDown: scroll.down,
|
||||
scaleUp: scaleUp,
|
||||
scaleDown: scaleDown,
|
||||
|
||||
'Shift+icon:scrollUp': scroll.left,
|
||||
'Shift+icon:scrollDown': scroll.right,
|
||||
'Ctrl+icon:scrollUp': pluso,
|
||||
'Ctrl+icon:scrollDown': minuso,
|
||||
|
||||
// key
|
||||
|
||||
|
||||
nop: { fn: () => false }
|
||||
};
|
@ -1,31 +0,0 @@
|
||||
const { keyName } = require('w3c-keyname');
|
||||
|
||||
const executeKeyHandler = (key, keyEvent, pstate, cm) => {
|
||||
return (keyEvent[key] || keyEvent.nop).fn(pstate, cm);
|
||||
};
|
||||
|
||||
const genKeyHandler = (div, pstate, deso, cm, keyEvent, plugins) => {
|
||||
return event => {
|
||||
|
||||
const modifier = (
|
||||
(event.ctrlKey ? 'Ctrl+' : '') +
|
||||
(event.shiftKey ? 'Shift+' : '') +
|
||||
(event.altKey ? 'Alt+' : '')
|
||||
);
|
||||
// const key = modifier + event.key;
|
||||
const key = modifier + keyName(event);
|
||||
|
||||
if (executeKeyHandler(key, keyEvent, pstate, cm)) {
|
||||
event.stopPropagation();
|
||||
if (plugins != undefined) {
|
||||
plugins.map(fn => fn(key, event));
|
||||
}
|
||||
deso.render();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export default {
|
||||
executeKeyHandler,
|
||||
genKeyHandler
|
||||
};
|
@ -1,45 +0,0 @@
|
||||
const genOnWheel = (element, pstate, deso, keyEvent, plugins) =>
|
||||
event => {
|
||||
const { deltaX, deltaY } = event;
|
||||
if (event.ctrlKey) {
|
||||
const key = (deltaY < 0)
|
||||
? 'Ctrl+icon:scrollUp'
|
||||
: ((deltaY > 0) ? 'Ctrl+icon:scrollDown' : 'nop');
|
||||
if (keyEvent[key].fn(pstate)) {
|
||||
if (plugins != undefined) {
|
||||
plugins.map(fn => fn(key, event));
|
||||
}
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
} else if (event.shiftKey) {
|
||||
const key = (deltaY < 0) ? 'Shift+icon:scrollUp' : ((deltaY > 0) ? 'Shift+icon:scrollDown' : 'nop');
|
||||
if (keyEvent[key].fn(pstate)) {
|
||||
if (plugins != undefined) {
|
||||
plugins.map(fn => fn(key, event));
|
||||
}
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
} else if (deltaX !== 0 && deltaY === 0) {
|
||||
const key = (deltaX < 0) ? 'scrollLeft': 'scrollRight';
|
||||
if (keyEvent[key].fn(pstate)) {
|
||||
if (plugins != undefined) {
|
||||
plugins.map(fn => fn(key, event));
|
||||
}
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
} else if (deltaX === 0 && deltaY !== 0) {
|
||||
const key = (deltaY < 0) ? 'scrollUp': 'scrollDown';
|
||||
if (keyEvent[key].fn(pstate)) {
|
||||
if (plugins != undefined) {
|
||||
plugins.map(fn => fn(key, event));
|
||||
}
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
export default genOnWheel;
|
@ -3,10 +3,9 @@ import getListing from './get-listing';
|
||||
import domContainer from './dom-container';
|
||||
import pluginRenderValues from './plugin-render-values';
|
||||
import pluginRenderTimeGrid from './plugin-render-time-grid';
|
||||
import keyEvent from './keyEvent';
|
||||
import eventHandler from './event-handler';
|
||||
import mountTree from './mount-tree';
|
||||
import genKeyHandler from './gen-key-handler';
|
||||
import genOnWheel from './gen-on-wheel';
|
||||
import registerWheelEvent from './wheel-event';
|
||||
import xOffsetUpdate from './x-offset-update';
|
||||
import getX from './get-x';
|
||||
import getT from './get-t';
|
||||
@ -18,10 +17,9 @@ export {
|
||||
domContainer,
|
||||
pluginRenderValues,
|
||||
pluginRenderTimeGrid,
|
||||
keyEvent,
|
||||
eventHandler,
|
||||
mountTree,
|
||||
genKeyHandler,
|
||||
genOnWheel,
|
||||
registerWheelEvent,
|
||||
xOffsetUpdate,
|
||||
getX,
|
||||
getT
|
||||
|
101
src/hook/wave-view/jsdoc.js
Normal file
101
src/hook/wave-view/jsdoc.js
Normal file
@ -0,0 +1,101 @@
|
||||
/**
|
||||
* @description
|
||||
* @typedef {Object} WaveElements
|
||||
* @property {HTMLDivElement} grid
|
||||
* @property {HTMLDivElement} view
|
||||
* @property {HTMLDivElement} values
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description
|
||||
* @typedef {Object} ChangoItem
|
||||
* @property {string} kind
|
||||
* @property {Array<number | string>} wave
|
||||
* @property {WebGLVertexArrayObject} lineVao
|
||||
* @property {WebGLVertexArrayObject} maskVao
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description 装载在 globalLookup 中的记录 vcd 数据的字典
|
||||
* @typedef {Record<string, ChangoItem>} Chango
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description
|
||||
* @typedef {Object} WireItem
|
||||
* @property {string} kind
|
||||
* @property {string} link
|
||||
* @property {string} name
|
||||
* @property {number} size
|
||||
* @property {WireItem} parent
|
||||
* @property {string} type
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description
|
||||
* @typedef {Array<{ ref: string }>} View
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description
|
||||
* @typedef {Set<WireItem>} CurrentWires
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description
|
||||
* @typedef {Object} GlobalLookup
|
||||
* @property {Chango} chango
|
||||
* @property {View} view
|
||||
* @property {CurrentWires} currentWires
|
||||
* @property {number} time
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description
|
||||
* @typedef {Object} Pstate
|
||||
* @property {number} width
|
||||
* @property {number} height
|
||||
* @property {number} xScale
|
||||
* @property {number} xOffset
|
||||
* @property {number} yOffset
|
||||
* @property {number} yStep
|
||||
* @property {number} yDuty
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description
|
||||
* @typedef {Object} Rgba
|
||||
* @property {number} red
|
||||
* @property {number} green
|
||||
* @property {number} blue
|
||||
* @property {number} alpha
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description
|
||||
* @typedef {Object} Updater
|
||||
* @property {number} index
|
||||
* @property {Rgba} rgba
|
||||
*/
|
||||
|
||||
/**
|
||||
* @description
|
||||
* @typedef {Object} RenderConfig
|
||||
* @property {'common' | 'action' | undefined} type
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Handler
|
||||
* @property {string} desc
|
||||
* @property {(arg1: Pstate, arg2: any) => boolean} fn
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} Deso
|
||||
* @property {(config: RenderConfig) => void} render
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {'scrollLeft' | 'scrollRight' | 'scrollUp' | 'scrollDown' | 'scaleUp' | 'scaleDown'} EventHandlerKind
|
||||
*/
|
163
src/hook/wave-view/key-event.js
Normal file
163
src/hook/wave-view/key-event.js
Normal file
@ -0,0 +1,163 @@
|
||||
|
||||
const platform = navigator.platform;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {WaveElements} element
|
||||
* @param {Pstate} pstate
|
||||
* @param {Deso} deso
|
||||
* @param {Record<EventHandlerKind, Handler>} eventHandler
|
||||
* @param {KeyboardEvent} event
|
||||
*/
|
||||
function windowsKeydown(element, pstate, deso, eventHandler, event) {
|
||||
if (event.ctrlKey) {
|
||||
if (event.key === '=') {
|
||||
eventHandler['scaleUp'].fn(pstate);
|
||||
deso.render();
|
||||
} else if (event.key === '-') {
|
||||
eventHandler['scaleDown'].fn(pstate);
|
||||
deso.render();
|
||||
}
|
||||
}
|
||||
|
||||
if (event.shiftKey) {
|
||||
switch (event.key) {
|
||||
case 'ArrowLeft':
|
||||
eventHandler['scrollLeft'].fn(pstate);
|
||||
deso.render();
|
||||
break;
|
||||
case 'ArrowRight':
|
||||
eventHandler['scrollRight'].fn(pstate);
|
||||
deso.render();
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
eventHandler['scrollUp'].fn(pstate);
|
||||
deso.render();
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
eventHandler['scrollDown'].fn(pstate);
|
||||
deso.render();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {WaveElements} element
|
||||
* @param {Pstate} pstate
|
||||
* @param {Deso} deso
|
||||
* @param {Record<EventHandlerKind, Handler>} eventHandler
|
||||
* @param {KeyboardEvent} event
|
||||
*/
|
||||
function linuxKeydown(element, pstate, deso, eventHandler, event) {
|
||||
if (event.ctrlKey) {
|
||||
if (event.key === '=') {
|
||||
eventHandler['scaleUp'].fn(pstate);
|
||||
deso.render();
|
||||
} else if (event.key === '-') {
|
||||
eventHandler['scaleDown'].fn(pstate);
|
||||
deso.render();
|
||||
}
|
||||
}
|
||||
|
||||
if (event.shiftKey) {
|
||||
switch (event.key) {
|
||||
case 'ArrowLeft':
|
||||
eventHandler['scrollLeft'].fn(pstate);
|
||||
deso.render();
|
||||
break;
|
||||
case 'ArrowRight':
|
||||
eventHandler['scrollRight'].fn(pstate);
|
||||
deso.render();
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
eventHandler['scrollUp'].fn(pstate);
|
||||
deso.render();
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
eventHandler['scrollDown'].fn(pstate);
|
||||
deso.render();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
event.preventDefault();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {WaveElements} element
|
||||
* @param {Pstate} pstate
|
||||
* @param {Deso} deso
|
||||
* @param {Record<EventHandlerKind, Handler>} eventHandler
|
||||
* @param {KeyboardEvent} event
|
||||
*/
|
||||
function macOsKeydown(element, pstate, deso, eventHandler, event) {
|
||||
if (event.metaKey) {
|
||||
if (event.key === '=') {
|
||||
eventHandler['scaleUp'].fn(pstate);
|
||||
deso.render();
|
||||
} else if (event.key === '-') {
|
||||
eventHandler['scaleDown'].fn(pstate);
|
||||
deso.render();
|
||||
}
|
||||
}
|
||||
|
||||
if (event.shiftKey) {
|
||||
switch (event.key) {
|
||||
case 'ArrowLeft':
|
||||
eventHandler['scrollLeft'].fn(pstate);
|
||||
deso.render();
|
||||
break;
|
||||
case 'ArrowRight':
|
||||
eventHandler['scrollRight'].fn(pstate);
|
||||
deso.render();
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
eventHandler['scrollUp'].fn(pstate);
|
||||
deso.render();
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
eventHandler['scrollDown'].fn(pstate);
|
||||
deso.render();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
event.preventDefault();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {WaveElements} element
|
||||
* @param {Pstate} pstate
|
||||
* @param {Deso} deso
|
||||
* @param {Record<string, Handler>} eventHandler
|
||||
* @returns {(event: KeyboardEvent) => void}
|
||||
*/
|
||||
function registerKeyEvent(element, pstate, deso, eventHandler) {
|
||||
const platform = navigator.platform;
|
||||
if (platform.startsWith('Win')) {
|
||||
return event => windowsKeydown(element, pstate, deso, eventHandler, event);
|
||||
} else if (platform.startsWith('Linux')) {
|
||||
return event => linuxKeydown(element, pstate, deso, eventHandler, event);
|
||||
} else if (platform.startsWith('Mac')) {
|
||||
return event => macOsKeydown(element, pstate, deso, eventHandler, event);
|
||||
} else {
|
||||
throw Error('不支持的操作系统!');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export {
|
||||
registerKeyEvent
|
||||
};
|
@ -3,46 +3,15 @@ import { globalSetting, globalStyle } from '../global';
|
||||
import { gl_Colors, gl_Shifts, gl_Shifts_for_bar, gl_Shifts_map, gl_WidthShifts, barShift, getRatio, screenHeightPixel } from './render-utils.js';
|
||||
import { vertexShader, fragmentShader } from './render-shader.js';
|
||||
|
||||
|
||||
// const { ChangoItem } = require('./types.d.ts');
|
||||
|
||||
|
||||
class WebGL2WaveRender {
|
||||
/**
|
||||
*
|
||||
* @param {{
|
||||
* grid: HTMLDivElement,
|
||||
* view: HTMLDivElement,
|
||||
* values: HTMLDivElement
|
||||
* }} elements
|
||||
* @param {{
|
||||
* chango: Record<string, {
|
||||
* kind: string,
|
||||
* wave: Array<number | string>,
|
||||
* lineVao: WebGLVertexArrayObject
|
||||
* maskVao: WebGLVertexArrayObject
|
||||
* }>
|
||||
* view: Array<{ ref: string }>,
|
||||
* currentWires: Set<{
|
||||
* kind: string,
|
||||
* link: string,
|
||||
* name: string,
|
||||
* size: number,
|
||||
* parent: object,
|
||||
* type: string
|
||||
* }>,
|
||||
* time: number
|
||||
* }} globalLookup
|
||||
* @param {{
|
||||
* width: number,
|
||||
* height: number,
|
||||
* xScale: number,
|
||||
* xOffset: number,
|
||||
* yOffset: number,
|
||||
* yStep: number,
|
||||
* yDuty: number
|
||||
* }} pstate
|
||||
* @param { Array } plugins
|
||||
* @param {WaveElements} elements
|
||||
* @param {GlobalLookup} globalLookup
|
||||
* @param {Pstate} pstate
|
||||
* @param {Array} plugins
|
||||
*/
|
||||
constructor(elements, globalLookup, pstate, plugins) {
|
||||
const canvas = document.createElement('canvas');
|
||||
@ -144,9 +113,6 @@ class WebGL2WaveRender {
|
||||
} else if (kind === 'vec') {
|
||||
const { lineVertices, maskVertices } = this.makeVecVertex(wave, time);
|
||||
return { lineVertices, maskVertices };
|
||||
} else if (kind === '') {
|
||||
const { lineVertices, maskVertices } = this.makeVecVertex(wave, time);
|
||||
return { lineVertices, maskVertices };
|
||||
}
|
||||
return {
|
||||
lineVertices: undefined,
|
||||
@ -277,7 +243,7 @@ class WebGL2WaveRender {
|
||||
perspectivePoints.push({ x: t1, y: renderParam1.y, color: renderParam1.color });
|
||||
perspectivePoints.push({ x: t2, y: renderParam1.y, color: renderParam1.color });
|
||||
} else {
|
||||
const lastPoint = perspectivePoints.at(-1);
|
||||
const lastPoint = perspectivePoints[perspectivePoints.length - 1];
|
||||
if ((lastPoint.y !== renderParam1.y) || (lastPoint.color !== renderParam1.color)) {
|
||||
perspectivePoints.push({ x: t1, y: renderParam1.y, color: renderParam1.color });
|
||||
}
|
||||
@ -288,7 +254,7 @@ class WebGL2WaveRender {
|
||||
}
|
||||
|
||||
// 确保最后一个点延申到了 time
|
||||
const lastPoint = perspectivePoints.at(-1);
|
||||
const lastPoint = perspectivePoints[perspectivePoints.length - 1];
|
||||
if (lastPoint.x < time) {
|
||||
perspectivePoints.push({ x: time, y: lastPoint.y, color: lastPoint.color });
|
||||
}
|
||||
@ -520,15 +486,7 @@ class WebGL2WaveRender {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Array<{
|
||||
* index: number
|
||||
* rgba: {
|
||||
* red: number,
|
||||
* green: number,
|
||||
* blue: number,
|
||||
* alpha: number
|
||||
* }
|
||||
* }>} updaters
|
||||
* @param {Array<Updater>} updaters
|
||||
* @param {{
|
||||
* updateMask: boolean
|
||||
* }} config
|
||||
@ -559,9 +517,7 @@ class WebGL2WaveRender {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {{
|
||||
* type: 'common' | 'action'
|
||||
* } | undefined} renderConfig
|
||||
* @param {RenderConfig} renderConfig
|
||||
*/
|
||||
render(renderConfig) {
|
||||
renderConfig = renderConfig || { type: 'common' };
|
||||
|
127
src/hook/wave-view/touch-event.js
Normal file
127
src/hook/wave-view/touch-event.js
Normal file
@ -0,0 +1,127 @@
|
||||
// 触控事件
|
||||
|
||||
|
||||
const platform = navigator.platform;
|
||||
const touchState = {
|
||||
startX: undefined,
|
||||
startY: undefined
|
||||
};
|
||||
|
||||
|
||||
// TODO: 完成这个 和 手势控制
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {WaveElements} element
|
||||
* @param {Pstate} pstate
|
||||
* @param {Deso} deso
|
||||
* @param {Record<string, Handler>} eventHandler
|
||||
* @param {TouchEvent} event
|
||||
*/
|
||||
function macTouchmove(element, pstate, deso, eventHandler, event) {
|
||||
const touch = event.touches[0];
|
||||
if (touch) {
|
||||
const { pageX, pageY } = touch;
|
||||
const deltaX = pageX - touchState.startX;
|
||||
const deltaY = pageY - touchState.startY;
|
||||
|
||||
const updownKey = (deltaY < 0) ? 'scrollDown' : 'scrollUp';
|
||||
const leftrightKey = (deltaX < 0) ? 'scrollRight' : 'scrollLeft';
|
||||
|
||||
eventHandler[updownKey].fn(pstate);
|
||||
deso.render();
|
||||
|
||||
// eventHandler[leftrightKey].fn(pstate);
|
||||
// deso.render();
|
||||
}
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {WaveElements} element
|
||||
* @param {Pstate} pstate
|
||||
* @param {Deso} deso
|
||||
* @param {Record<string, Handler>} eventHandler
|
||||
* @param {TouchEvent} event
|
||||
*/
|
||||
function macTouchstart(element, pstate, deso, eventHandler, event) {
|
||||
const touch = event.touches[0];
|
||||
if (touch) {
|
||||
const { pageX, pageY } = touch;
|
||||
touchState.startX = pageX;
|
||||
touchState.startY = pageY;
|
||||
}
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {WaveElements} element
|
||||
* @param {Pstate} pstate
|
||||
* @param {Deso} deso
|
||||
* @param {Record<string, Handler>} eventHandler
|
||||
* @param {TouchEvent} event
|
||||
*/
|
||||
function macTouchend(element, pstate, deso, eventHandler, event) {
|
||||
touchState.startX = undefined;
|
||||
touchState.startY = undefined;
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {WaveElements} element
|
||||
* @param {Pstate} pstate
|
||||
* @param {Deso} deso
|
||||
* @param {Record<string, Handler>} eventHandler
|
||||
* @returns {(event: TouchEvent) => void}
|
||||
*/
|
||||
function registerTouchmoveEvent(element, pstate, deso, eventHandler) {
|
||||
if (platform.startsWith('Mac')) {
|
||||
// IOS
|
||||
return event => macTouchmove(element, pstate, deso, eventHandler, event);
|
||||
} else {
|
||||
return event => {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {WaveElements} element
|
||||
* @param {Pstate} pstate
|
||||
* @param {Deso} deso
|
||||
* @param {Record<string, Handler>} eventHandler
|
||||
* @returns {(event: TouchEvent) => void}
|
||||
*/
|
||||
function registerTouchstartEvent(element, pstate, deso, eventHandler) {
|
||||
if (platform.startsWith('Mac')) {
|
||||
return event => macTouchstart(element, pstate, deso, eventHandler, event);
|
||||
} else {
|
||||
return event => {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {WaveElements} element
|
||||
* @param {Pstate} pstate
|
||||
* @param {Deso} deso
|
||||
* @param {Record<string, Handler>} eventHandler
|
||||
* @returns {(event: TouchEvent) => void}
|
||||
*/
|
||||
function registerTouchendEvent(element, pstate, deso, eventHandler) {
|
||||
if (platform.startsWith('Mac')) {
|
||||
return event => macTouchend(element, pstate, deso, eventHandler, event);
|
||||
} else {
|
||||
return event => {}
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
registerTouchstartEvent,
|
||||
registerTouchmoveEvent,
|
||||
registerTouchendEvent
|
||||
};
|
136
src/hook/wave-view/wheel-event.js
Normal file
136
src/hook/wave-view/wheel-event.js
Normal file
@ -0,0 +1,136 @@
|
||||
// 鼠标滚轮事件
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {WaveElements} element
|
||||
* @param {Pstate} pstate
|
||||
* @param {Deso} deso
|
||||
* @param {Record<string, Handler>} eventHandler
|
||||
* @param {WheelEvent} event
|
||||
*/
|
||||
function windowsWheel(element, pstate, deso, eventHandler, event) {
|
||||
const { deltaX, deltaY } = event;
|
||||
if (event.ctrlKey) {
|
||||
const key = (deltaY < 0)
|
||||
? 'scaleUp'
|
||||
: ((deltaY > 0) ? 'scaleDown' : 'nop');
|
||||
|
||||
if (eventHandler[key].fn(pstate)) {
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
} else if (event.shiftKey) {
|
||||
const key = (deltaY < 0) ? 'scrollLeft' : ((deltaY > 0) ? 'scrollRight' : 'nop');
|
||||
if (eventHandler[key].fn(pstate)) {
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
} else if (deltaX !== 0 && deltaY === 0) {
|
||||
const key = (deltaX < 0) ? 'scrollLeft' : 'scrollRight';
|
||||
if (eventHandler[key].fn(pstate)) {
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
} else if (deltaX === 0 && deltaY !== 0) {
|
||||
const key = (deltaY < 0) ? 'scrollUp' : 'scrollDown';
|
||||
if (eventHandler[key].fn(pstate)) {
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {WaveElements} element
|
||||
* @param {Pstate} pstate
|
||||
* @param {Deso} deso
|
||||
* @param {Record<string, Handler>} eventHandler
|
||||
* @param {WheelEvent} event
|
||||
*/
|
||||
function macOsWheel(element, pstate, deso, eventHandler, event) {
|
||||
let { deltaX, deltaY } = event;
|
||||
if (event.ctrlKey) {
|
||||
const key = (deltaY < 0)
|
||||
? 'scaleUp'
|
||||
: ((deltaY > 0) ? 'scaleDown' : 'nop');
|
||||
if (eventHandler[key].fn(pstate)) {
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
} else if (event.shiftKey) {
|
||||
const key = (deltaX < 0) ? 'scrollLeft' : ((deltaX > 0) ? 'scrollRight' : 'nop');
|
||||
if (eventHandler[key].fn(pstate)) {
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
}else if (deltaX !== 0 && deltaY === 0) {
|
||||
const key = (deltaX < 0) ? 'scrollLeft' : 'scrollRight';
|
||||
if (eventHandler[key].fn(pstate)) {
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
} else if (deltaX === 0 && deltaY !== 0) {
|
||||
const key = (deltaY < 0) ? 'scrollUp' : 'scrollDown';
|
||||
if (eventHandler[key].fn(pstate)) {
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {WaveElements} element
|
||||
* @param {Pstate} pstate
|
||||
* @param {Deso} deso
|
||||
* @param {Record<string, Handler>} eventHandler
|
||||
* @param {WheelEvent} event
|
||||
*/
|
||||
function linuxWheel(element, pstate, deso, eventHandler, event) {
|
||||
const { deltaX, deltaY } = event;
|
||||
if (event.ctrlKey) {
|
||||
const key = (deltaY < 0)
|
||||
? 'scaleUp'
|
||||
: ((deltaY > 0) ? 'scaleDown' : 'nop');
|
||||
if (eventHandler[key].fn(pstate)) {
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
} else if (event.shiftKey) {
|
||||
const key = (deltaY < 0) ? 'scrollLeft' : ((deltaY > 0) ? 'scrollRight' : 'nop');
|
||||
if (eventHandler[key].fn(pstate)) {
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
} else if (deltaX !== 0 && deltaY === 0) {
|
||||
const key = (deltaX < 0) ? 'scrollLeft' : 'scrollRight';
|
||||
if (eventHandler[key].fn(pstate)) {
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
} else if (deltaX === 0 && deltaY !== 0) {
|
||||
const key = (deltaY < 0) ? 'scrollUp' : 'scrollDown';
|
||||
if (eventHandler[key].fn(pstate)) {
|
||||
deso.render({ type: 'action' });
|
||||
}
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
function registerWheelEvent(element, pstate, deso, eventHandler) {
|
||||
const platform = navigator.platform;
|
||||
if (platform.startsWith('Win')) {
|
||||
return event => windowsWheel(element, pstate, deso, eventHandler, event);
|
||||
} else if (platform.startsWith('Linux')) {
|
||||
return event => linuxWheel(element, pstate, deso, eventHandler, event);
|
||||
} else if (platform.startsWith('Mac')) {
|
||||
return event => macOsWheel(element, pstate, deso, eventHandler, event);
|
||||
} else {
|
||||
throw Error('不支持的操作系统!');
|
||||
}
|
||||
}
|
||||
|
||||
export default registerWheelEvent;
|
@ -6,7 +6,7 @@ const yOffsetUpdate = (pstate, nextOffsetYFn) => {
|
||||
|
||||
const currentRenderHeight = globalLookup.currentWires.size * pstate.yStep;
|
||||
const canvasHeight = pstate.height - pstate.topBarHeight - pstate.botBarHeight;
|
||||
console.log(currentRenderHeight, canvasHeight);
|
||||
// console.log(currentRenderHeight, canvasHeight);
|
||||
const maxOffsetX = Math.max(-40, currentRenderHeight - canvasHeight); // maximum offset
|
||||
nextOffsetY = Math.min(nextOffsetY, maxOffsetX);
|
||||
|
||||
|
@ -46,7 +46,8 @@
|
||||
"usermanual": "User Manual",
|
||||
"usermanual.left-right-scroll.title": "<span class=\"iconfont icon-mouse\"/> + <span class=\"iconfont icon-up-down\"/>",
|
||||
"usermanual.left-right-scroll.caption": "move up and down",
|
||||
"usermanual.up-down-scroll.title": "<span class=\"iconfont icon-mouse\"/> + <span class=\"iconfont icon-left-right\"/> / <span class=\"iconfont icon-shift\"/> + <span class=\"iconfont icon-mouse\"/> + <span class=\"iconfont icon-up-down\"/>",
|
||||
"usermanual.up-down-scroll.title.wheel": "<span class=\"iconfont icon-mouse\"/> + <span class=\"iconfont icon-left-right\"/> / <span class=\"iconfont icon-shift\"/> + <span class=\"iconfont icon-mouse\"/> + <span class=\"iconfont icon-up-down\"/>",
|
||||
"usermanual.up-down-scroll.title.shift": "<span class=\"iconfont icon-mouse\"/> + <span class=\"iconfont icon-left-right\"/> / <span class=\"iconfont icon-shift\"/> + <span class=\"iconfont icon-mouse\"/> + <span class=\"iconfont icon-up-down\"/>",
|
||||
"usermanual.up-down-scroll.caption": "move left and right",
|
||||
"usermanual.xscale.title": "<span class=\"iconfont icon-ctrl\"/> + <span class=\"iconfont icon-mouse\"/> + <span class=\"iconfont icon-up-down\"/>",
|
||||
"usermanual.xscale.caption": "scale along x axis",
|
||||
|
@ -12,4 +12,9 @@ module.exports = {
|
||||
}),
|
||||
],
|
||||
devtool: 'none',
|
||||
}
|
||||
module: {
|
||||
loader: [
|
||||
{ test: /\.vcd$/, loader: 'ignore-loader' }
|
||||
]
|
||||
}
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user