205 lines
6.5 KiB
JavaScript
205 lines
6.5 KiB
JavaScript
import { globalLookup } from '../global';
|
|
import WebGL2WaveRender from './render-wave';
|
|
|
|
import renderCursor from './render-cursor';
|
|
import genResizeHandler from './gen-resize-handler';
|
|
import mTree from './mount-tree';
|
|
|
|
const setTime = (pstate, str) => {
|
|
// const { sidebarOffset, time, timescale, tgcd, xOffset } = pstate;
|
|
// pstate.xOffset = .5; // (2 * (pstate.width - pstate.sidebarWidth)) / pstate.time;
|
|
const m = str.match(/(\d+)(\w+)/); if (m) {
|
|
// const time1 = parseInt(m[1]);
|
|
// const timescale1 = ({s: 0, ms: -3, us: -6, ns: -9, ps: -12, fs: -15})[m[2]] || 0;
|
|
// pstate.xOffset = -1;
|
|
}
|
|
};
|
|
|
|
const mouseMoveHandler = (cursor, content, pstate /* , render */) => {
|
|
// 这是上面展示当前 time 的圆角矩形框框的宽度
|
|
const xmargin = 160;
|
|
// 这是上面展示当前 time 的圆角矩形内的字体大小
|
|
const fontHeight = 20;
|
|
const fontWidth = fontHeight / 2;
|
|
const handler = event => {
|
|
const x = pstate.xCursor = event.clientX;
|
|
cursor.style.left = (x - xmargin) + 'px';
|
|
cursor.innerHTML = renderCursor({ xmargin, fontWidth, fontHeight }, pstate);
|
|
};
|
|
// 添加初始鼠标位置
|
|
handler({ clientX: pstate.width / 2 });
|
|
content.addEventListener('mousemove', handler);
|
|
};
|
|
|
|
|
|
const getFullView = desc => {
|
|
// console.log(desc);
|
|
if (desc.waveql) {
|
|
return;
|
|
}
|
|
|
|
const arr = [];
|
|
|
|
const rec = ero => {
|
|
if (ero.kind === 'scope') {
|
|
arr.push(ero.name);
|
|
ero.body.map(rec);
|
|
arr.push('..');
|
|
return;
|
|
}
|
|
if (ero.kind === 'var') {
|
|
arr.push(ero.name);
|
|
return;
|
|
}
|
|
console.error(ero);
|
|
throw new Error();
|
|
};
|
|
|
|
rec(desc.wires);
|
|
|
|
desc.waveql = arr.join('\n');
|
|
};
|
|
|
|
|
|
class DomContainer {
|
|
/**
|
|
* @param {{
|
|
* sidebarWidth: number,
|
|
* fontHeight: number,
|
|
* xScaleMax: number,
|
|
* xScaleMin: number
|
|
* }} renderConfig
|
|
* @param {Array} renderPlugins
|
|
*/
|
|
constructor(renderConfig, renderPlugins) {
|
|
renderConfig = renderConfig || {};
|
|
const sidebarWidth = renderConfig.sidebarWidth || 256;
|
|
const fontHeight = renderConfig.fontHeight || 16;
|
|
const xScaleMax = renderConfig.xScaleMax || 1000;
|
|
const xScaleMin = renderConfig.xScaleMin || 0.001;
|
|
this.elementInfos = {
|
|
container: { tag: 'div', class: 'vcd-container', id: 'vcd-container' }, // 外部的 wrapper
|
|
grid: { tag: 'div', class: 'vcd-vline', id: 'vcd-vline' }, // 和时间点对应的竖线
|
|
view: { tag: 'div', class: 'vcd-view', id: 'vcd-view' }, // 用于渲染主要波形
|
|
values: { tag: 'div', class: 'vcd-values', id: 'vcd-values' }, // 展示每关键点的值
|
|
cursor: { tag: 'div', class: 'vcd-cursor', id: 'vcd-cursor' } // 随着光标移动的竖线
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* @description 创建用于展示波形的基本元素和组件
|
|
*/
|
|
createElements() {
|
|
const elementInfos = this.elementInfos;
|
|
for (const elName of Reflect.ownKeys(elementInfos)) {
|
|
const elementInfo = elementInfos[elName];
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
const domContainer = (obj) => {
|
|
const sidebarWidth = 280;
|
|
const fontHeight = 20;
|
|
|
|
const elo = mTree.createElemento(obj.elemento);
|
|
const container = mTree.createContainer(elo, obj.layers);
|
|
// elo.container.tabIndex = '0';
|
|
|
|
const pstate = {
|
|
fontHeight,
|
|
width: 1024, // [px] window width
|
|
height: 1024, // [px] window height
|
|
xScaleMax: 1000,
|
|
xScaleMin: 0.001,
|
|
topBarHeight: fontHeight * 1.5, // [px]
|
|
botBarHeight: fontHeight * 1.5, // [px]
|
|
xOffset: sidebarWidth,
|
|
yOffset: -20, // [px]
|
|
yStep: 54, // = 24 // [px] wave lane height
|
|
yDuty: 0.6,
|
|
|
|
// for animation
|
|
oldXOffset: sidebarWidth,
|
|
oldYOffset: -20,
|
|
oldYStep: 54,
|
|
oldYDuty: 0.6,
|
|
|
|
sidebarWidth,
|
|
container
|
|
};
|
|
|
|
globalLookup.pstate = pstate;
|
|
|
|
return {
|
|
elo,
|
|
pstate,
|
|
start: (deso /* , opt */) => {
|
|
|
|
// content.appendChild(container);
|
|
// content.appendChild(elo.rightPanel);
|
|
// getFullView(deso);
|
|
|
|
deso.t0 = deso.t0 || 0;
|
|
// desc.xScale |= 8;
|
|
|
|
Object.assign(pstate, {
|
|
tgcd: deso.tgcd,
|
|
timescale: deso.timescale,
|
|
xScale: deso.xScale || 8,
|
|
oldXScale: deso.xScale || 8,
|
|
numLanes: deso.currentWires.size,
|
|
t0: deso.t0,
|
|
time: deso.time
|
|
});
|
|
|
|
|
|
// TODO : 增加已有波形的保存和读取
|
|
try {
|
|
const str = localStorage.getItem('dide');
|
|
const obj = JSON.parse(str);
|
|
Object.assign(pstate, obj);
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
|
|
// const {timetopSVG, timebotSVG} = timeline(deso);
|
|
|
|
if (deso.timeOpt) {
|
|
setTime(pstate, deso.timeOpt.value);
|
|
}
|
|
|
|
|
|
const waveRender = new WebGL2WaveRender(elo, deso, pstate, obj.renderPlugins);
|
|
deso.render = waveRender.render.bind(waveRender);
|
|
deso.waveRender = waveRender;
|
|
globalLookup.waveRender = waveRender;
|
|
|
|
const resizeHandler = genResizeHandler(pstate);
|
|
|
|
// 通过 resize 完成 height 和 width 的初始化
|
|
const resizeObserver = new ResizeObserver(entries => {
|
|
for (let entry of entries) {
|
|
// TODO : 使用更新的属性替换 contentRect
|
|
// 未来版本 contentRect 可能会被丢弃
|
|
let { width, height } = entry.contentRect;
|
|
// console.log(width, height);
|
|
// height = height || 888;
|
|
// console.log('resizeObserver', width, height);
|
|
resizeHandler(width, height);
|
|
}
|
|
deso.render({ type: 'action' });
|
|
});
|
|
|
|
resizeObserver.observe(document.body);
|
|
|
|
resizeHandler(elo.container.clientWidth, elo.container.clientHeight);
|
|
mouseMoveHandler(elo.cursor, elo.container, pstate, deso.render);
|
|
deso.render();
|
|
}
|
|
};
|
|
};
|
|
|
|
export default domContainer; |