完成 0.3.3 版本的开发打包
This commit is contained in:
parent
03c4d1b715
commit
a8ae1d6608
@ -1,7 +0,0 @@
|
||||
module.exports = {
|
||||
// ... 其他配置
|
||||
ignorePatterns: ['**/*.d.ts'],
|
||||
env: {
|
||||
es6: true
|
||||
}
|
||||
};
|
0
deploy.bat
Normal file
0
deploy.bat
Normal file
@ -1,6 +1,6 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram id="fareUikBvdjO0hJmng89" name="第 1 页">
|
||||
<mxGraphModel dx="1355" dy="695" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="1" shadow="0">
|
||||
<diagram id="fareUikBvdjO0hJmng89" name="makeBitVertex 原理图">
|
||||
<mxGraphModel dx="1529" dy="929" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="1" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
@ -566,203 +566,275 @@
|
||||
<mxCell id="136" value="\[w<br style="font-size: 18px;">\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#FFFFFF;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="550" y="1460" width="50" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="137" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1680" y="1000" as="sourcePoint"/>
|
||||
<mxPoint x="1640" y="1158.82" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="138" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1640" y="1160" as="sourcePoint"/>
|
||||
<mxPoint x="1680" y="1320" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="139" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="2040" y="1000" as="sourcePoint"/>
|
||||
<mxPoint x="1680" y="1000" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="140" value="\[p_0=(x_0, y_0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" vertex="1" parent="1">
|
||||
<mxGeometry x="1480" y="1120" width="160" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="141" value="\[p_1=(x_1, y_1)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" vertex="1" parent="1">
|
||||
<mxGeometry x="2160" y="1130" width="160" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="143" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="2040" y="1320" as="sourcePoint"/>
|
||||
<mxPoint x="1680" y="1320" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="144" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="2080" y="1160" as="sourcePoint"/>
|
||||
<mxPoint x="2040" y="1318.8199999999997" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="145" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="2040" y="1000" as="sourcePoint"/>
|
||||
<mxPoint x="2080" y="1160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="146" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="2070" y="1360" as="sourcePoint"/>
|
||||
<mxPoint x="1650" y="1360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="147" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="2120" y="1160" as="sourcePoint"/>
|
||||
<mxPoint x="2070" y="1360" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="149" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1650" y="1360" as="sourcePoint"/>
|
||||
<mxPoint x="1600" y="1160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="150" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="2120" y="1158.95" as="sourcePoint"/>
|
||||
<mxPoint x="2040" y="1159" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="151" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1680" y="1160" as="sourcePoint"/>
|
||||
<mxPoint x="1600" y="1160.05" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="152" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="2000" y="1280" as="sourcePoint"/>
|
||||
<mxPoint x="1720" y="1280" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="153" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1720" y="1280" as="sourcePoint"/>
|
||||
<mxPoint x="1680" y="1158.95" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="154" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="2040" y="1160" as="sourcePoint"/>
|
||||
<mxPoint x="2000" y="1280" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="155" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1650" y="1360" as="sourcePoint"/>
|
||||
<mxPoint x="1720" y="1280" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="156" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" edge="1" parent="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="2070" y="1360" as="sourcePoint"/>
|
||||
<mxPoint x="2000" y="1275" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="157" value="\[(\frac{w}{2}, 0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="1670" y="1130" width="110" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="158" value="\[(-\frac{w}{2}, 0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="1470" y="1175" width="120" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="159" value="\[(\frac{w}{2}, 0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="1700" y="1240" width="110" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="160" value="\[p_0=(x_0 + title, -1)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" vertex="1" parent="1">
|
||||
<mxGeometry x="1605" y="1370" width="190" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
<diagram id="ldzhMOmdS79g5s7hsVNb" name="第 2 页">
|
||||
<mxGraphModel dx="1345" dy="451" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="1" shadow="0">
|
||||
<diagram id="ldzhMOmdS79g5s7hsVNb" name="makeVecVertex 原理图">
|
||||
<mxGraphModel dx="-10" dy="250" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="1" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="0KlvA6460LBpeT4quUVe-1" value="\[p_0=(x_0,y_0)<br>\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
|
||||
<mxGeometry x="120" y="500" width="110" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0KlvA6460LBpeT4quUVe-2" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-1" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="120" y="520" as="sourcePoint"/>
|
||||
<mxPoint x="160" y="400" as="targetPoint"/>
|
||||
<mxPoint x="1160" y="600" as="sourcePoint"/>
|
||||
<mxPoint x="1120" y="758.8199999999997" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0KlvA6460LBpeT4quUVe-3" value="\[p_1=(x_1,y_1)<br>\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;" vertex="1" parent="1">
|
||||
<mxGeometry x="440" y="500" width="110" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0KlvA6460LBpeT4quUVe-4" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" vertex="1" parent="1">
|
||||
<mxGeometry x="100" y="810" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0KlvA6460LBpeT4quUVe-5" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" vertex="1" parent="1">
|
||||
<mxGeometry x="485" y="810" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0KlvA6460LBpeT4quUVe-6" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" vertex="1" parent="1">
|
||||
<mxGeometry x="100" y="690" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0KlvA6460LBpeT4quUVe-7" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fontColor=#F0B102;" vertex="1" parent="1">
|
||||
<mxGeometry x="485" y="690" width="20" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0KlvA6460LBpeT4quUVe-8" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-2" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="120" y="520" as="sourcePoint"/>
|
||||
<mxPoint x="160" y="640" as="targetPoint"/>
|
||||
<mxPoint x="1120" y="760" as="sourcePoint"/>
|
||||
<mxPoint x="1160" y="920" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0KlvA6460LBpeT4quUVe-9" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-3" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="160" y="400" as="sourcePoint"/>
|
||||
<mxPoint x="400" y="400" as="targetPoint"/>
|
||||
<mxPoint x="1520" y="600" as="sourcePoint"/>
|
||||
<mxPoint x="1160" y="600" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0KlvA6460LBpeT4quUVe-10" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-4" value="\[p_0=(x_0, y_0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" parent="1" vertex="1">
|
||||
<mxGeometry x="970" y="715" width="160" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-5" value="\[p_1=(x_1, y_1)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" parent="1" vertex="1">
|
||||
<mxGeometry x="1540" y="715" width="160" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-6" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="160" y="640" as="sourcePoint"/>
|
||||
<mxPoint x="400" y="640" as="targetPoint"/>
|
||||
<mxPoint x="1520" y="920" as="sourcePoint"/>
|
||||
<mxPoint x="1160" y="920" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0KlvA6460LBpeT4quUVe-11" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-7" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="400" y="400" as="sourcePoint"/>
|
||||
<mxPoint x="440" y="520" as="targetPoint"/>
|
||||
<mxPoint x="1560" y="760" as="sourcePoint"/>
|
||||
<mxPoint x="1520" y="918.8199999999997" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="YzxP9u1fmLVgk9Jru_4W-1" value="" style="endArrow=none;dashed=1;html=1;" edge="1" parent="1">
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-8" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;startArrow=none;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="-40" y="400" as="sourcePoint"/>
|
||||
<mxPoint x="140" y="400" as="targetPoint"/>
|
||||
<mxPoint x="1520" y="600" as="sourcePoint"/>
|
||||
<mxPoint x="1560" y="760" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="YzxP9u1fmLVgk9Jru_4W-2" value="" style="endArrow=none;dashed=1;html=1;" edge="1" parent="1">
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-9" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="-40" y="640" as="sourcePoint"/>
|
||||
<mxPoint x="120" y="639.9999999999999" as="targetPoint"/>
|
||||
<mxPoint x="1550" y="960" as="sourcePoint"/>
|
||||
<mxPoint x="1130" y="960" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="YzxP9u1fmLVgk9Jru_4W-3" value="" style="endArrow=classic;startArrow=classic;html=1;" edge="1" parent="1">
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-10" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="80" y="640" as="sourcePoint"/>
|
||||
<mxPoint x="80" y="400" as="targetPoint"/>
|
||||
<mxPoint x="1600" y="760" as="sourcePoint"/>
|
||||
<mxPoint x="1550" y="960" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="YzxP9u1fmLVgk9Jru_4W-4" value="\[w<br style="font-size: 18px;">\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#FFFFFF;fontSize=18;" vertex="1" parent="1">
|
||||
<mxGeometry x="20" y="480" width="50" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="YzxP9u1fmLVgk9Jru_4W-6" value="" style="endArrow=none;html=1;strokeWidth=2;fillColor=#f0a30a;strokeColor=#F0B102;" edge="1" parent="1">
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-11" value="" style="endArrow=none;html=1;strokeColor=#3700CC;strokeWidth=2;fontColor=#F0B102;dashed=1;fillColor=#6a00ff;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="400" y="640.0000000000001" as="sourcePoint"/>
|
||||
<mxPoint x="440" y="520" as="targetPoint"/>
|
||||
<mxPoint x="1130" y="960" as="sourcePoint"/>
|
||||
<mxPoint x="1080" y="760" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-12" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1600" y="758.9499999999998" as="sourcePoint"/>
|
||||
<mxPoint x="1520" y="759" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-13" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1480" y="880" as="sourcePoint"/>
|
||||
<mxPoint x="1200" y="880" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-14" value="" style="endArrow=none;html=1;strokeColor=#3700CC;strokeWidth=2;fontColor=#F0B102;dashed=1;fillColor=#6a00ff;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1200" y="880" as="sourcePoint"/>
|
||||
<mxPoint x="1160" y="758.9499999999998" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-15" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1520" y="760" as="sourcePoint"/>
|
||||
<mxPoint x="1480" y="880" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-16" value="" style="endArrow=none;html=1;strokeColor=#3700CC;strokeWidth=2;fontColor=#F0B102;dashed=1;fillColor=#6a00ff;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1130" y="960" as="sourcePoint"/>
|
||||
<mxPoint x="1200" y="880" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-17" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1550" y="960" as="sourcePoint"/>
|
||||
<mxPoint x="1480" y="875" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-18" value="\[(\frac{w}{2}, 0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1145" y="745" width="110" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-19" value="\[(-\frac{w}{2}, 0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="980" y="745" width="120" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-20" value="\[(\frac{w}{2},\frac{w}{2}<br>)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1160" y="840" width="150" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-21" value="\[a_0=(x_0 + bs, -1)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" parent="1" vertex="1">
|
||||
<mxGeometry x="1160" y="970" width="180" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-22" value="" style="endArrow=none;dashed=1;html=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1120" y="1019.3100000000004" as="sourcePoint"/>
|
||||
<mxPoint x="1120" y="970" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-23" value="" style="endArrow=none;dashed=1;html=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1160" y="970" as="sourcePoint"/>
|
||||
<mxPoint x="1160" y="1020" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-24" value="" style="endArrow=classic;startArrow=classic;html=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1120" y="989.3100000000004" as="sourcePoint"/>
|
||||
<mxPoint x="1160" y="990" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GijaLTcLDulYfw_Rey3C-25" value="\[bs<br style="font-size: 18px;">\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#FFFFFF;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="1120" y="980" width="50" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="AR7EaJVa85OL3mO77pCV-26" value="" style="endArrow=none;html=1;strokeColor=#3700CC;strokeWidth=2;fontColor=#F0B102;dashed=1;fillColor=#6a00ff;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1160" y="759.9999999999998" as="sourcePoint"/>
|
||||
<mxPoint x="1080" y="760.05" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-1" value="" style="endArrow=none;dashed=1;html=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="980" y="880.0000000000001" as="sourcePoint"/>
|
||||
<mxPoint x="1060" y="880.0000000000001" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-2" value="" style="endArrow=none;dashed=1;html=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="980" y="960" as="sourcePoint"/>
|
||||
<mxPoint x="1060" y="960" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-3" value="" style="endArrow=classic;startArrow=classic;html=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1020" y="960.58" as="sourcePoint"/>
|
||||
<mxPoint x="1020" y="880" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-4" value="\[w<br style="font-size: 18px;">\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#FFFFFF;fontSize=18;" parent="1" vertex="1">
|
||||
<mxGeometry x="970" y="890" width="50" height="60" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-5" value="\[a_2=(x_0 + bs, 1)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" parent="1" vertex="1">
|
||||
<mxGeometry x="1145" y="570" width="180" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-6" value="\[a_3=(x_0 - bs, 1)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" parent="1" vertex="1">
|
||||
<mxGeometry x="1520" y="580" width="170" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-7" value="\[a_1=(x_1 - bs, -1)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontColor=#F0B102;fontSize=17;" parent="1" vertex="1">
|
||||
<mxGeometry x="1450" y="970" width="180" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-8" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1550" y="560" as="sourcePoint"/>
|
||||
<mxPoint x="1130" y="559.22" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-9" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1080" y="760" as="sourcePoint"/>
|
||||
<mxPoint x="1130" y="560" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-10" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1160" y="760" as="sourcePoint"/>
|
||||
<mxPoint x="1200" y="640" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-11" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1480" y="640" as="sourcePoint"/>
|
||||
<mxPoint x="1200" y="640" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-12" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1550" y="560" as="sourcePoint"/>
|
||||
<mxPoint x="1480" y="640" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-13" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1130" y="560" as="sourcePoint"/>
|
||||
<mxPoint x="1200" y="640.0000000000001" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-14" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1520" y="760" as="sourcePoint"/>
|
||||
<mxPoint x="1480" y="638.9499999999999" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-15" value="" style="endArrow=none;html=1;strokeColor=#FFFFFF;strokeWidth=2;fontColor=#F0B102;dashed=1;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1600" y="760" as="sourcePoint"/>
|
||||
<mxPoint x="1550" y="560.0000000000001" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-16" value="\[b_0\]" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" parent="1" vertex="1">
|
||||
<mxGeometry x="1120" y="820" width="40" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-18" value="\[(-\frac{w}{2},-\frac{w}{2}<br>)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1000" y="960" width="150" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-19" value="\[(\frac{w}{2}, 0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1580" y="745" width="110" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-20" value="\[(-\frac{w}{2}, 0)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1420" y="745" width="120" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-21" value="\[(\frac{w}{2},\frac{w}{2}<br>)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1510" y="520" width="150" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-22" value="\[(-\frac{w}{2},-\frac{w}{2}<br>)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1360" y="640" width="150" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-23" value="\[(-\frac{w}{2},\frac{w}{2}<br>)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1370" y="840" width="150" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-24" value="\[(\frac{w}{2},-\frac{w}{2}<br>)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1520" y="940" width="150" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-25" value="\[(\frac{w}{2},-\frac{w}{2}<br>)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1160" y="640" width="150" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-26" value="\[(-\frac{w}{2},\frac{w}{2}<br>)\]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1040" y="520" width="150" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-27" value="6" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1225" y="745" width="30" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-28" value="7" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1250" y="810" width="30" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-29" value="1" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1400" y="810" width="30" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-30" value="2" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1420" y="745" width="30" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-31" value="3" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1400" y="680" width="30" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="0AE3MlXHRA_X4uAlCJMS-32" value="5" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="1250" y="680" width="30" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
243
package-lock.json
generated
243
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -10,14 +10,14 @@
|
||||
"dependencies": {
|
||||
"core-js": "^3.8.3",
|
||||
"element-plus": "^2.5.6",
|
||||
"lodash.get": "^4.4.2",
|
||||
"mitt": "^3.0.1",
|
||||
"onml": "^2.1.0",
|
||||
"stream": "^0.0.2",
|
||||
"vue": "^3.2.13",
|
||||
"vue-i18n": "^9.9.1",
|
||||
"waveql": "^1.8.0",
|
||||
"lodash.get": "^4.4.2",
|
||||
"onml": "^2.1.0",
|
||||
"w3c-keyname": "^2.2.8"
|
||||
"w3c-keyname": "^2.2.8",
|
||||
"waveql": "^1.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.16",
|
||||
@ -25,7 +25,6 @@
|
||||
"@vue/cli-plugin-babel": "~5.0.0",
|
||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"unplugin-auto-import": "^0.17.5",
|
||||
"unplugin-vue-components": "^0.26.0"
|
||||
|
42
public/icon.svg
Normal file
42
public/icon.svg
Normal file
@ -0,0 +1,42 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"
|
||||
width="126px" height="126px" viewBox="-0.5 -0.5 126 126"
|
||||
content="<mxfile><diagram id="E9SxX19eNgA6MUTyjjO6" name="Icon-黑白">7VnbktsoEP0aP0YlhG5+HF/GqVSS8pZrd2f3xcVIWGJXEiqEx3K+fsFCN8sXORnNuJL1g003TQN9DtDgEZzG+YKhNPxCfRyNDN3PR3A2MgzoOOJbKvaFwjDNQhEw4hcqUCtW5BtWSl1pt8THWcuQUxpxkraVHk0S7PGWDjFGd22zDY3avaYowB3FykNRV/sn8XmotMAe1xUfMQlC1bVrqAnHqDRWM8lC5NNdQwXnIzhllPKiFOdTHMnYlXHxJ7s5fqSf7OfpbvVp7cXpYv2hcPZ4S5NqCgwn/HVdw8L1C4q2Kl5qrnxfBnAXEo5XKfKkvBMcGcFJyONISEAUUZYWsG1IjkVXkw2JoimNKDs0h8YMGnAi9Bln9N8KA0ta0oQ3LDeHT2VZ1iQ0ET1PGN0mvuyg6JV5imrAFWLPAKlAvmDGcd6ghwrYAtMYc7YXJqrWtBX2JflLedegUsmPsMGiSokUfYPKdw2RKCiUbkDMfC/EYG/ERM104oLZwwXYLH1I2FyoOVYbuYaqAZ5jaFYXvVr76vDZ1+ETXsTmKDl/K5BtwIwutBUs5wELGPIJrmFWy2+4FeZobaSgVWmaq+wETGAokJx7B2koNCzrDtFw/0ejPn/eEo08X23Th+zzxPqbzBe7cGIbf/TZwAKx6adVXDrzrXI99Fy20G8J4fm9ZHzEXb17WlsnYgWHYu74eqxkdIjIVj+jZxwtaUY4oYmoeqac01jSrsw65YHpoyw8HKZSQBEJpKknYoZZm+el2wdlw2la+Eplv3EeyFxfw5FAgUk7LaIB8dYB4jhrlEUbmmKG1KBQMtySuUi23kumjLBiADA1B9quKW4jlmFDYHf4AOGJteNqVQvLccdD0QOA6/y4OZcTGdojikkkIzClMfGEvxVKMvHzZaUMVA7mdsAER2D6eIO2ER8CsOb+BU5gAIYKuvELB708RgzNAWNj7BqmZQNTh2b3THlTTJzuie6LW7wSKeMhDWiConmtbdws9DY8OCf8Sall+S9Zlsl/Ic7yRt1s3xCWmBExIbmXFrpETO6p9CqFwpVVirWrg1T6uoUOAB6a+w/yqaNOt4XmkcggHhye30e7e/FtnMnolnn4+hHGEQvwxZNZrSKJ20UKMhyJ4+Sl/TrzI4zS7309j2QiIj+nkKxqfsK1fvfH2zsh8wahPznCIR77XhuP3rnjiWtFP4juB48hnvJ+Bjzef+c6OVpriCSlLDcyi/M5SpmPVELRyriWkByk4+zmVqq8fpJylCt8P2F65xSHpmIWaN8wSClJeNbwvJSK+k4J7KNXGFuTbLR011H8bFLrenMw1mxzDAzD1R0dOJZpHVGzGOAZb6DHUKqpFemdcnFhjMfX5rEGWzdgs+22yAY7bg+rqoKl10Lzflt8s5++muuPH5bW+vf863LzT59z6h4e/K7seN/zgNV5DB/0wU+I9b+XBXj1X8Bw/h8=</diagram><diagram id="2oZjiazD9LnPP1Vpl2Fo" name="第 2 页">5ZZdb4IwFEB/DY8m0DLQV5m6h7nEuGXPDVToVigpVXC/fkUuX+Lilui2RF+k515u29ObBgN7cbGQJI2WIqDcQGZQGPjeQAiZeKL/SrKviGU6qCKhZAGwFqzZB60TgW5ZQLNeohKCK5b2oS+ShPqqx4iUIu+nbQTvz5qSEGY0W7D2CaeDtFcWqKiiY+S2/IGyMKpnthzYcUzqZCicRSQQeQfhmYE9KYSqnuLCo7y0V3up3pt/EW0WJmmivvNCulw+b3YrwlZPycub9Tgd52oEVXaEb2HDsFi1rw1IsU0CWhaxDDzNI6boOiV+Gc31oWsWqZhDeMM49wQXUo8TkeikaaakeG/kIVuj4dLrdVCpaNFBsJUFFTFVcq9TIDqyXPAKnYVtGOftMWEMLOocUQMJtEbYFG/t6QcQ+AOZ6NdlmheS6Y57Lm2MBi4t2xm6bODFXeLzLnUVfQvQ8x5JllZXw4YVpfsji+Mj1QbC88OvyTwVuUgP20c97A572D7Rwva1OvjuBqxP/plz5/acO+YfO3dvwPngdrmidT1sP2QOsc73IJ59Ag==</diagram></mxfile>">
|
||||
<defs />
|
||||
<g>
|
||||
<rect x="2" y="2" width="120" height="120" rx="21.6" ry="21.6" fill="#2d323b" stroke="none"
|
||||
pointer-events="all" />
|
||||
<rect x="25.75" y="25.75" width="72.5" height="72.5" rx="36.25" ry="36.25" fill="#2d323b"
|
||||
stroke="#cb81da" stroke-width="3" pointer-events="all" />
|
||||
<ellipse cx="17" cy="107" rx="7.500000000000001" ry="7.500000000000001" fill="#cb81da"
|
||||
stroke="#cb81da" stroke-width="2" pointer-events="all" />
|
||||
<ellipse cx="107" cy="107" rx="7.500000000000001" ry="7.500000000000001" fill="#cb81da"
|
||||
stroke="#cb81da" stroke-width="2" pointer-events="all" />
|
||||
<ellipse cx="107" cy="17" rx="7.500000000000001" ry="7.500000000000001" fill="#cb81da"
|
||||
stroke="#cb81da" stroke-width="2" pointer-events="all" />
|
||||
<path d="M 85.4 65.95 L 92 65.95 M 59 61.34 L 65.6 61.34 M 59 70.55 L 65.6 70.55"
|
||||
fill="none" stroke="#cb81da" stroke-width="2" stroke-miterlimit="10"
|
||||
pointer-events="none" />
|
||||
<path
|
||||
d="M 65.6 56.74 L 75.5 56.74 C 80.97 56.74 85.4 60.86 85.4 65.95 C 85.4 71.03 80.97 75.16 75.5 75.16 L 65.6 75.16 Z"
|
||||
fill="#cb81da" stroke="#cb81da" stroke-width="2" stroke-miterlimit="10"
|
||||
pointer-events="none" />
|
||||
<rect x="37" y="42" width="11" height="11" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)"
|
||||
pointer-events="none" />
|
||||
<rect x="37" y="64.72" width="11" height="11" fill="rgb(255, 255, 255)"
|
||||
stroke="rgb(0, 0, 0)" pointer-events="none" />
|
||||
<path d="M 59 70.55 L 48.01 70.6" fill="none" stroke="#cb81da" stroke-width="2"
|
||||
stroke-miterlimit="10" pointer-events="none" />
|
||||
<rect x="37" y="64.72" width="11" height="11" fill="#000000" stroke="#000000"
|
||||
pointer-events="none" />
|
||||
<rect x="37" y="42" width="11" height="11" fill="#000000" stroke="#000000"
|
||||
pointer-events="none" />
|
||||
<rect x="37" y="42" width="11" height="11" fill="#cb81da" stroke="#cb81da"
|
||||
pointer-events="none" />
|
||||
<rect x="37" y="64.72" width="11" height="11" fill="#cb81da" stroke="#cb81da"
|
||||
pointer-events="none" />
|
||||
<path d="M 48 48.14 L 53.51 48.09 L 53.51 61.31 L 59 61.34" fill="none" stroke="#cb81da"
|
||||
stroke-width="2" stroke-miterlimit="10" pointer-events="none" />
|
||||
<ellipse cx="17" cy="17" rx="7.500000000000001" ry="7.500000000000001" fill="#cb81da"
|
||||
stroke="#cb81da" stroke-width="2" pointer-events="none" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.9 KiB |
@ -1,8 +1,6 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4440655 */
|
||||
src: url('iconfont.woff2?t=1709378049768') format('woff2'),
|
||||
url('iconfont.woff?t=1709378049768') format('woff'),
|
||||
url('iconfont.ttf?t=1709378049768') format('truetype');
|
||||
src: url('iconfont.woff2?t=1713691301672') format('woff2');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@ -13,11 +11,35 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-ctrl:before {
|
||||
content: "\e605";
|
||||
}
|
||||
|
||||
.icon-shift:before {
|
||||
content: "\e626";
|
||||
}
|
||||
|
||||
.icon-mouse:before {
|
||||
content: "\e69e";
|
||||
}
|
||||
|
||||
.icon-left-right:before {
|
||||
content: "\e61c";
|
||||
}
|
||||
|
||||
.icon-up-down:before {
|
||||
content: "\e61d";
|
||||
}
|
||||
|
||||
.icon-help:before {
|
||||
content: "\e87a";
|
||||
}
|
||||
|
||||
.icon-parameter:before {
|
||||
content: "\e6be";
|
||||
}
|
||||
|
||||
.icon-task-:before {
|
||||
.icon-task:before {
|
||||
content: "\e602";
|
||||
}
|
||||
|
||||
@ -29,11 +51,11 @@
|
||||
content: "\e69d";
|
||||
}
|
||||
|
||||
.icon-Function:before {
|
||||
.icon-function:before {
|
||||
content: "\e90e";
|
||||
}
|
||||
|
||||
.icon-R:before {
|
||||
.icon-real:before {
|
||||
content: "\e6ec";
|
||||
}
|
||||
|
||||
@ -41,7 +63,7 @@
|
||||
content: "\e603";
|
||||
}
|
||||
|
||||
.icon-String:before {
|
||||
.icon-string:before {
|
||||
content: "\e614";
|
||||
}
|
||||
|
||||
@ -61,7 +83,7 @@
|
||||
content: "\e657";
|
||||
}
|
||||
|
||||
.icon-Collections:before {
|
||||
.icon-collections:before {
|
||||
content: "\e689";
|
||||
}
|
||||
|
||||
|
Binary file not shown.
@ -12,13 +12,25 @@
|
||||
<link rel="stylesheet" href="vcd.css">
|
||||
<link rel="stylesheet" href="iconfont.css">
|
||||
<script src="vcd.js"></script>
|
||||
|
||||
<script>
|
||||
window.readVcdFile = async () => {
|
||||
const response = await fetch('test.vcd');
|
||||
const blob = await response.blob();
|
||||
const reader = new FileReader();
|
||||
return new Promise((resolve, reject) => {
|
||||
reader.onload = event => {
|
||||
const fileContent = event.target.result;
|
||||
const unintarray = new Uint8Array(fileContent);
|
||||
resolve(unintarray);
|
||||
};
|
||||
reader.readAsArrayBuffer(blob);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
|
||||
Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
|
||||
|
@ -192,7 +192,7 @@
|
||||
--vscode-symbolIcon-fieldForeground: #75beff;
|
||||
--vscode-symbolIcon-fileForeground: #cccccc;
|
||||
--vscode-symbolIcon-folderForeground: #cccccc;
|
||||
--vscode-symbolIcon-functionForeground: #b180d7;
|
||||
--vscode-symbolicon-functionForeground: #b180d7;
|
||||
--vscode-symbolIcon-interfaceForeground: #75beff;
|
||||
--vscode-symbolIcon-keyForeground: #cccccc;
|
||||
--vscode-symbolIcon-keywordForeground: #cccccc;
|
||||
@ -205,9 +205,9 @@
|
||||
--vscode-symbolIcon-operatorForeground: #cccccc;
|
||||
--vscode-symbolIcon-packageForeground: #cccccc;
|
||||
--vscode-symbolIcon-propertyForeground: #cccccc;
|
||||
--vscode-symbolIcon-referenceForeground: #cccccc;
|
||||
--vscode-symbolicon-realeferenceForeground: #cccccc;
|
||||
--vscode-symbolIcon-snippetForeground: #cccccc;
|
||||
--vscode-symbolIcon-stringForeground: #cccccc;
|
||||
--vscode-symbolicon-stringForeground: #cccccc;
|
||||
--vscode-symbolIcon-structForeground: #cccccc;
|
||||
--vscode-symbolIcon-textForeground: #cccccc;
|
||||
--vscode-symbolIcon-typeParameterForeground: #cccccc;
|
||||
@ -565,7 +565,7 @@
|
||||
--vscode-debugIcon-pauseForeground: #75beff;
|
||||
--vscode-debugIcon-stopForeground: #f48771;
|
||||
--vscode-debugIcon-disconnectForeground: #f48771;
|
||||
--vscode-debugIcon-restartForeground: #89d185;
|
||||
--vscode-debugicon-realestartForeground: #89d185;
|
||||
--vscode-debugIcon-stepOverForeground: #75beff;
|
||||
--vscode-debugIcon-stepIntoForeground: #75beff;
|
||||
--vscode-debugIcon-stepOutForeground: #75beff;
|
||||
|
@ -4,13 +4,20 @@
|
||||
--main-color: #CB81DA;
|
||||
--main-dark-color: #2D323B;
|
||||
--main-light-color: var(--main-color);
|
||||
--sidebar-width: 280px;
|
||||
--sidebar-width: 230px;
|
||||
--right-nav-width: 60px;
|
||||
--time-scale-height: 50px;
|
||||
--sidebar-padding: 10px;
|
||||
--vcd-render-padding: 24px;
|
||||
--sidebar-item-margin: 5px;
|
||||
--vcd-render-padding: 30px;
|
||||
/* 需要满足如下公式 --time-scale-height + --sidebar-padding = --vcd-render-padding + canvas预留 高度 */
|
||||
--render-scale-x: 1;
|
||||
|
||||
/* css 动画属性 */
|
||||
--animation-7s: .7s cubic-bezier(0.23,1,0.32,1);
|
||||
--animation-5s: .5s cubic-bezier(0.23,1,0.32,1);
|
||||
--animation-3s: .35s cubic-bezier(0.23,1,0.32,1);
|
||||
--gray-box-shadow-0: 0 0 8px 3px rgba(182, 181, 182, 0.9);
|
||||
}
|
||||
|
||||
html, body {
|
||||
@ -94,3 +101,17 @@ body::-webkit-scrollbar {
|
||||
a {
|
||||
color: var(--main-color);
|
||||
}
|
||||
|
||||
.digital-ide-icon {
|
||||
background-image: url(./icon.svg);
|
||||
background-size: 100%;
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.digital-ide-icon.big {
|
||||
background-image: url(./icon.svg);
|
||||
background-size: 100%;
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
}
|
199
src/App.vue
199
src/App.vue
@ -14,9 +14,9 @@
|
||||
<RightNav :topModules="VcdInfo.topModules"></RightNav>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import { getVcdStream, readVcdFile, numberOrString, gcd, normaliseUsingGCD, parseTimescale } from '@/hook/utils';
|
||||
<script setup>
|
||||
import { onMounted, reactive, watch } from 'vue';
|
||||
import { getVcdStream, numberOrString, gcd, normaliseUsingGCD, parseTimescale } from '@/hook/utils';
|
||||
import { emitter, globalLookup, globalSetting, signalValues } from '@/hook/global';
|
||||
import { makeWaveView } from '@/hook/render';
|
||||
|
||||
@ -24,121 +24,120 @@ import Sidebar from '@/components/sidebar.vue';
|
||||
import RightNav from '@/components/right-nav.vue';
|
||||
import MainRender from '@/components/render';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
RightNav,
|
||||
Sidebar,
|
||||
MainRender
|
||||
// 监听 globalSetting 并录入 localStorage
|
||||
watch(
|
||||
() => globalSetting,
|
||||
() => {
|
||||
localStorage.setItem('setting', JSON.stringify(globalSetting));
|
||||
},
|
||||
setup() {
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
const VcdInfo = reactive({
|
||||
topModules: [],
|
||||
values: [],
|
||||
});
|
||||
const VcdInfo = reactive({
|
||||
topModules: [],
|
||||
values: [],
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
// 改变默认颜色
|
||||
document.body.style.setProperty('--el-color-primary', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-color-primary-light-9', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-color-primary-light-3', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-text-color-secondary', 'var(--foreground)');
|
||||
document.body.style.setProperty('--el-text-color-regular', 'var(--foreground)');
|
||||
document.body.style.setProperty('--el-border-color', 'var(--vscode-focusBorder)');
|
||||
document.body.style.setProperty('--el-fill-color-blank', 'var(--sidebar)');
|
||||
document.body.style.setProperty('--el-fill-color-light', 'var(--vscode-button-hoverBackground)');
|
||||
document.body.style.setProperty('--el-switch-on-color', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-border', 'var(--sidebar)');
|
||||
document.body.style.setProperty('--el-border-color-light', 'var(--sidebar)');
|
||||
document.body.style.setProperty('--el-border-color-lighter', 'var(--sidebar)');
|
||||
document.body.style.setProperty('--el-bg-color-overlay', 'transplant');
|
||||
document.body.style.setProperty('--el-color-info-light-9', 'var(--vscode-focusBorder)');
|
||||
document.body.style.setProperty('--el-color-info', 'var(--foreground)');
|
||||
document.body.style.setProperty('--el-color-info-light-8', 'var(--vscode-focusBorder)');
|
||||
document.body.style.setProperty('--el-bg-color-overlay', 'transplant');
|
||||
// document.body.style.setProperty('--el-color-white', 'var(--background)');
|
||||
onMounted(async () => {
|
||||
// 改变默认颜色
|
||||
document.body.style.setProperty('--el-color-primary', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-color-primary-light-9', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-color-primary-light-3', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-text-color-secondary', 'var(--foreground)');
|
||||
document.body.style.setProperty('--el-text-color-regular', 'var(--foreground)');
|
||||
document.body.style.setProperty('--el-border-color', 'var(--vscode-focusBorder)');
|
||||
document.body.style.setProperty('--el-fill-color-blank', 'var(--sidebar)');
|
||||
document.body.style.setProperty('--el-fill-color-light', 'var(--vscode-button-hoverBackground)');
|
||||
document.body.style.setProperty('--el-switch-on-color', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-border', 'var(--sidebar)');
|
||||
document.body.style.setProperty('--el-border-color-light', 'var(--sidebar)');
|
||||
document.body.style.setProperty('--el-border-color-lighter', 'var(--sidebar)');
|
||||
document.body.style.setProperty('--el-bg-color-overlay', 'var(--sidebar)');
|
||||
document.body.style.setProperty('--el-color-info-light-9', 'var(--vscode-focusBorder)');
|
||||
document.body.style.setProperty('--el-color-info', 'var(--foreground)');
|
||||
document.body.style.setProperty('--el-color-info-light-8', 'var(--vscode-focusBorder)');
|
||||
// document.body.style.setProperty('--el-color-white', 'var(--background)');
|
||||
|
||||
// 设置全局宏
|
||||
document.body.style.setProperty('--time-scale-height', '50px');
|
||||
document.body.style.setProperty('--sidebar-padding', '10px');
|
||||
document.body.style.setProperty('--vcd-render-padding', '24px');
|
||||
// 设置全局宏
|
||||
document.body.style.setProperty('--time-scale-height', '50px');
|
||||
document.body.style.setProperty('--vcd-render-padding', '30px');
|
||||
document.body.style.setProperty('--sidebar-width', '230px');
|
||||
|
||||
// signal height
|
||||
document.body.style.setProperty('--display-signal-info-height', globalSetting.displaySignalHeight + 'px');
|
||||
// signal height
|
||||
document.body.style.setProperty('--display-signal-info-height', globalSetting.displaySignalHeight + 'px');
|
||||
|
||||
const uint8array = await readVcdFile();
|
||||
const vcdstream = await getVcdStream();
|
||||
// 初始化 localStorage (如果没有的话)
|
||||
if (!localStorage.getItem('setting')) {
|
||||
localStorage.setItem('setting', JSON.stringify(globalSetting));
|
||||
}
|
||||
|
||||
let tgcd;
|
||||
// 使用 vcdstream 的 any 回调获取波形数据,并按照正确的格式进行解码和存储
|
||||
// 这段处理来自 https://github.com/wavedrom/vcd 的 vcd-pipe-deso.js 的 58 行
|
||||
// 请严格对准转换规则
|
||||
vcdstream.change.any((id, time, cmd, value, mask) => {
|
||||
const time53 = Number(time);
|
||||
tgcd = gcd(tgcd, time53);
|
||||
signalValues[id] = signalValues[id] || { kind: '', wave: [] };
|
||||
// 初始化载入 vcd 文件
|
||||
const uint8array = await window.readVcdFile();
|
||||
const vcdstream = await getVcdStream();
|
||||
|
||||
if (cmd >= 14 && cmd <= 28) {
|
||||
signalValues[id].kind = 'bit';
|
||||
signalValues[id].wave.push([time53, cmd - 14]);
|
||||
} else {
|
||||
signalValues[id].kind = 'vec';
|
||||
const point = [time53, numberOrString(value)];
|
||||
if (mask !== 0n) {
|
||||
point.push(numberOrString(mask));
|
||||
}
|
||||
signalValues[id].wave.push(point);
|
||||
}
|
||||
});
|
||||
let tgcd;
|
||||
// 使用 vcdstream 的 any 回调获取波形数据,并按照正确的格式进行解码和存储
|
||||
// 这段处理来自 https://github.com/wavedrom/vcd 的 vcd-pipe-deso.js 的 58 行
|
||||
// 请严格对准转换规则
|
||||
vcdstream.change.any((id, time, cmd, value, mask) => {
|
||||
const time53 = Number(time);
|
||||
tgcd = gcd(tgcd, time53);
|
||||
signalValues[id] = signalValues[id] || { kind: '', wave: [] };
|
||||
|
||||
vcdstream.on('$enddefinitions', () => {
|
||||
|
||||
});
|
||||
|
||||
const maxChunkLength = 1 << 17;
|
||||
for (let i = 0; i < uint8array.length; i += maxChunkLength) {
|
||||
const piece = uint8array.slice(i, i + maxChunkLength);
|
||||
vcdstream.write(piece);
|
||||
if (cmd >= 14 && cmd <= 28) {
|
||||
signalValues[id].kind = 'bit';
|
||||
signalValues[id].wave.push([time53, cmd - 14]);
|
||||
} else {
|
||||
signalValues[id].kind = 'vec';
|
||||
const point = [time53, numberOrString(value)];
|
||||
if (mask !== 0n) {
|
||||
point.push(numberOrString(mask));
|
||||
}
|
||||
signalValues[id].wave.push(point);
|
||||
}
|
||||
});
|
||||
|
||||
for (const topModule of vcdstream.info.wires.body) {
|
||||
VcdInfo.topModules.push(topModule);
|
||||
}
|
||||
globalLookup.status = vcdstream.info.status;
|
||||
globalLookup.version = vcdstream.info.version;
|
||||
globalLookup.timescale = parseTimescale(vcdstream.info.timescale);
|
||||
globalLookup.date = vcdstream.info.date;
|
||||
globalLookup.t0 = vcdstream.info.t0 || 0;
|
||||
vcdstream.on('$enddefinitions', () => {
|
||||
|
||||
globalLookup.tgcd = tgcd;
|
||||
globalLookup.time = Number(vcdstream.getTime());
|
||||
globalLookup.chango = signalValues;
|
||||
normaliseUsingGCD(globalLookup, signalValues);
|
||||
});
|
||||
|
||||
makeWaveView();
|
||||
const maxChunkLength = 1 << 17;
|
||||
for (let i = 0; i < uint8array.length; i += maxChunkLength) {
|
||||
const piece = uint8array.slice(i, i + maxChunkLength);
|
||||
vcdstream.write(piece);
|
||||
}
|
||||
|
||||
console.log('duration time', globalLookup.time);
|
||||
emitter.emit('meta-ready', null);
|
||||
for (const topModule of vcdstream.info.wires.body) {
|
||||
VcdInfo.topModules.push(topModule);
|
||||
}
|
||||
globalLookup.status = vcdstream.info.status;
|
||||
globalLookup.version = vcdstream.info.version;
|
||||
globalLookup.timescale = parseTimescale(vcdstream.info.timescale);
|
||||
globalLookup.date = vcdstream.info.date;
|
||||
globalLookup.t0 = vcdstream.info.t0 || 0;
|
||||
|
||||
// 这一步时,已经加载完成
|
||||
// 默认第一个模块被选中
|
||||
if (VcdInfo.topModules.length > 0) {
|
||||
const defaultMod = VcdInfo.topModules[0];
|
||||
const wires = defaultMod.body.filter(mod => mod.link);
|
||||
emitter.emit('tree-view', wires);
|
||||
// 将顶层模块存储进全局对象,以便后续的搜索服务
|
||||
for (const mod of VcdInfo.topModules) {
|
||||
globalLookup.topModules.push(mod);
|
||||
}
|
||||
}
|
||||
});
|
||||
globalLookup.tgcd = tgcd;
|
||||
globalLookup.time = Number(vcdstream.getTime());
|
||||
globalLookup.chango = signalValues;
|
||||
normaliseUsingGCD(globalLookup, signalValues);
|
||||
|
||||
return {
|
||||
VcdInfo
|
||||
makeWaveView();
|
||||
|
||||
// console.log('duration time', globalLookup.time);
|
||||
emitter.emit('meta-ready', null);
|
||||
|
||||
// 这一步时,已经加载完成
|
||||
// 默认第一个模块被选中
|
||||
if (VcdInfo.topModules.length > 0) {
|
||||
const defaultMod = VcdInfo.topModules[0];
|
||||
const wires = defaultMod.body.filter(mod => mod.link);
|
||||
emitter.emit('tree-view', wires);
|
||||
// 将顶层模块存储进全局对象,以便后续的搜索服务
|
||||
for (const mod of VcdInfo.topModules) {
|
||||
globalLookup.topModules.push(mod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
@ -1,18 +1,39 @@
|
||||
<template>
|
||||
<div class="about-wrapper">
|
||||
<div class="usermanual">
|
||||
<h2>{{ t('usermanual') }}</h2>
|
||||
<div class="usermanual-item">
|
||||
<div v-html="t('usermanual.left-right-scroll.title')"></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>{{ t('usermanual.up-down-scroll.caption') }}</div>
|
||||
</div>
|
||||
<div class="usermanual-item">
|
||||
<div v-html="t('usermanual.xscale.title')"></div>
|
||||
<div>{{ t('usermanual.xscale.caption') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
<br>
|
||||
|
||||
<div class="icon-caption" @click="goto('https://github.com/Digital-EDA')">
|
||||
<img src="../../assets/icon.png" height="200px" alt="">
|
||||
<div class="digital-ide-icon big"/>
|
||||
</div>
|
||||
<div class="version-caption">
|
||||
<span>{{ t('current-version') }}   <span class="version-wrapper">0.3.3</span></span>
|
||||
</div>
|
||||
<hr>
|
||||
<br>
|
||||
<div style="display: flex;justify-content: space-around;">
|
||||
<div class="copyright-caption" v-html="t('copyright')"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
@ -35,15 +56,14 @@ export default {
|
||||
|
||||
<style>
|
||||
.about-wrapper {
|
||||
margin-top: 20px;
|
||||
padding: 10px;
|
||||
width: 600px;
|
||||
margin-top: 10px;
|
||||
width: 450px;
|
||||
}
|
||||
|
||||
.version-caption {
|
||||
display: flex;
|
||||
width: 100% !important;
|
||||
font-size: 20px;
|
||||
font-size: 1.1rem;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
align-items: center;
|
||||
@ -53,7 +73,7 @@ export default {
|
||||
.copyright-caption {
|
||||
width: 50% !important;
|
||||
line-height: 30px;
|
||||
font-size: 20px;
|
||||
font-size: 0.9rem;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
align-items: center;
|
||||
@ -73,4 +93,23 @@ export default {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.usermanual {
|
||||
margin: 10px;
|
||||
margin-top: 0;
|
||||
padding: 10px;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.usermanual-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 5px;
|
||||
margin: 5px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.usermanual-item .iconfont {
|
||||
font-size: 1.1rem !important;
|
||||
color: var(--sidebar-text-item);
|
||||
}
|
||||
</style>
|
24
src/components/help-icon.vue
Normal file
24
src/components/help-icon.vue
Normal file
@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="props.content"
|
||||
:placement="props.placement"
|
||||
raw-content
|
||||
>
|
||||
<span class="iconfont icon-help"></span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps } from 'vue';
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
placement: {
|
||||
type: String,
|
||||
default: 'right'
|
||||
}
|
||||
});
|
||||
</script>
|
@ -12,7 +12,7 @@
|
||||
|
||||
<div class="vcd-function-option">
|
||||
<div class="vcd-control-panel-wrapper">
|
||||
<img class="vcd-control-panel-icon" src="../assets/icon.png" alt="">
|
||||
<div class="vcd-control-panel-icon digital-ide-icon" />
|
||||
</div>
|
||||
<hr>
|
||||
<div class="vcd-control-panel-wrapper"
|
||||
@ -52,7 +52,7 @@ export default {
|
||||
const controlPanel = reactive({
|
||||
sections: [
|
||||
{
|
||||
iconClass: 'iconfont icon-Collections'
|
||||
iconClass: 'iconfont icon-collections'
|
||||
},
|
||||
{
|
||||
iconClass: 'iconfont icon-setting'
|
||||
|
@ -1,132 +1,259 @@
|
||||
<template>
|
||||
<div class="setting-wrapper">
|
||||
<div class="setting-section">
|
||||
<h2>{{ t('search-setting') }}</h2>
|
||||
<div class="setting-option">
|
||||
<span class="option-title">{{ t('search-case-sensitivity') }}</span>
|
||||
<el-switch v-model="globalSetting.caseSensitivity" size="large"/>
|
||||
<div class="setting-container">
|
||||
<div class="setting-section">
|
||||
<h2>{{ t('general-setting') }}</h2>
|
||||
<div class="setting-option" style="width: 300px;">
|
||||
<span class="option-title">{{ t('language-setting') }}</span>
|
||||
<el-select name="language-setting" class="language-setting" v-model="locale">
|
||||
<el-option
|
||||
v-for="option in languageSetting.options"
|
||||
:value="option.value"
|
||||
:label="option.text"
|
||||
:key="option.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<br>
|
||||
<div class="setting-option">
|
||||
<span class="option-title">
|
||||
{{ t('prerender') }}
|
||||
<help-icon placement="left"
|
||||
:content="t('prerender-description')"
|
||||
></help-icon>
|
||||
</span>
|
||||
<el-switch v-model="globalSetting.prerender" size="default"/>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="setting-option">
|
||||
<span class="option-title">
|
||||
{{ t('render-animation') }}
|
||||
</span>
|
||||
<el-switch v-model="globalSetting.renderAnimation" size="default"/>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="setting-option" style="width: 380px;">
|
||||
<span class="option-title" style="width: 300px;">
|
||||
{{ t('horizontal-scaling-ratio') }}
|
||||
<help-icon placement="left"
|
||||
:content="t('horizontal-scaling-ratio-description')"
|
||||
></help-icon>
|
||||
</span>
|
||||
<el-slider v-model="globalSetting.HorizontalScalingRatio" show-stops :min="1" :max="5"/>
|
||||
</div>
|
||||
<br>
|
||||
<div class="setting-option" style="width: 380px;">
|
||||
<span class="option-title" style="width: 300px;">
|
||||
{{ t('horizontal-roll-ratio') }}
|
||||
<help-icon placement="left"
|
||||
:content="t('horizontal-roll-ratio-description')"
|
||||
></help-icon>
|
||||
</span>
|
||||
<el-slider v-model="globalSetting.HorizontalRollRatio" show-stops :min="1" :max="5"/>
|
||||
</div>
|
||||
<br>
|
||||
<div class="setting-option" style="width: 380px;">
|
||||
<span class="option-title" style="width: 300px;">
|
||||
{{ t('vertical-roll-ratio') }}
|
||||
<help-icon placement="left"
|
||||
:content="t('vertical-roll-ratio-description')"
|
||||
></help-icon>
|
||||
</span>
|
||||
<el-slider v-model="globalSetting.VerticalRollRario" show-stops :min="1" :max="5"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
|
||||
<div class="setting-option">
|
||||
<span class="option-title">{{ t('search-display-parent-only') }}</span>
|
||||
<el-switch v-model="globalSetting.displayParentOnly" size="large"/>
|
||||
<div class="setting-section">
|
||||
<h2>{{ t('appearance-setting') }}</h2>
|
||||
<div class="setting-option">
|
||||
<span class="option-title" style="width: 150px;">{{ t('display-wave-height') }}</span>
|
||||
<el-input-number v-model="globalSetting.displaySignalHeight" :min="1" :max="100" @change="safeModifySignalTrackHeight" size="default"/>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="setting-option">
|
||||
<span class="option-title" style="width: 150px;">{{ t('display-signal-info-scope') }}</span>
|
||||
<el-checkbox-group v-model="globalSetting.displaySignalInfoScope" size="default">
|
||||
<el-checkbox-button label="width" border>{{ t('display-signal-info-scope.width') }}</el-checkbox-button>
|
||||
<el-checkbox-button label="parent" border>{{ t('display-signal-info-scope.parent') }}</el-checkbox-button>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="setting-option">
|
||||
<span class="option-title">{{ t('wavecolor') }}</span>
|
||||
<el-select
|
||||
v-model="wavecolor.currentOptionIndex"
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder="Select"
|
||||
>
|
||||
<el-option v-for="option in wavecolor.options" :key="option.value"
|
||||
:label="option.label" :value="option.value" />
|
||||
</el-select>
|
||||
<div style="height: 20px; width: 20px;"></div>
|
||||
<el-color-picker
|
||||
v-model="wavecolor.colors[wavecolor.currentOptionIndex]"
|
||||
show-alpha
|
||||
:predefine="predefinedColors"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
<hr>
|
||||
|
||||
<div class="setting-option">
|
||||
<span class="option-title">{{ t('search-scope') }}</span>
|
||||
<el-select
|
||||
v-model="globalSetting.searchScope"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder="Select"
|
||||
>
|
||||
<el-option v-for="name in scopes" :key="name"
|
||||
:label="name" :value="name" />
|
||||
<el-option v-for="name in variables" :key="name"
|
||||
:label="name" :value="name" />
|
||||
</el-select>
|
||||
<div class="setting-section">
|
||||
<h2>{{ t('search-setting') }}</h2>
|
||||
<div class="setting-option">
|
||||
<span class="option-title">{{ t('search-case-sensitivity') }}</span>
|
||||
<el-switch v-model="globalSetting.caseSensitivity" size="default"/>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="setting-option">
|
||||
<span class="option-title">{{ t('search-display-parent-only') }}</span>
|
||||
<el-switch v-model="globalSetting.displayParentOnly" size="default"/>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="setting-option">
|
||||
<span class="option-title">{{ t('search-scope') }}</span>
|
||||
<el-select
|
||||
v-model="globalSetting.searchScope"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder="Select"
|
||||
>
|
||||
<el-option v-for="name in scopes" :key="name"
|
||||
:label="name" :value="name" />
|
||||
<el-option v-for="name in variables" :key="name"
|
||||
:label="name" :value="name" />
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="setting-section">
|
||||
<h2>{{ t('general-setting') }}</h2>
|
||||
<div class="setting-option" style="width: 300px;">
|
||||
<span class="option-title">{{ t('language-setting') }}</span>
|
||||
<el-select name="language-setting" class="language-setting" v-model="locale">
|
||||
<el-option
|
||||
v-for="option in languageSetting.options"
|
||||
:value="option.value"
|
||||
:label="option.text"
|
||||
:key="option.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<br>
|
||||
<div class="setting-option" style="width: 380px;">
|
||||
<span class="option-title" style="width: 300px;">{{ t('wheel-zoom-ratio') }}</span>
|
||||
<el-slider v-model="languageSetting.wheelZoomRatio" show-stops :min="1" :max="5"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="setting-section">
|
||||
<h2>{{ t('appearance-setting') }}</h2>
|
||||
<div class="setting-option">
|
||||
<span class="option-title">{{ t('display-wave-height') }}</span>
|
||||
<el-input-number v-model="globalSetting.displaySignalHeight" :min="1" :max="100" @change="safeModifySignalTrackHeight" size="large"/>
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
<div class="setting-option">
|
||||
<span class="option-title">{{ t('display-signal-info-scope') }}</span>
|
||||
<el-checkbox-group v-model="globalSetting.displaySignalInfoScope" size="default">
|
||||
<el-checkbox-button label="width" border>width </el-checkbox-button>
|
||||
<el-checkbox-button label="parent" border>parent </el-checkbox-button>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { reactive } from 'vue';
|
||||
<script setup>
|
||||
import { reactive, defineComponent, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { globalSetting } from '@/hook/global';
|
||||
import { debounceWrapper, scopes, variables } from '@/hook/utils';
|
||||
import { globalSetting, globalLookup } from '@/hook/global';
|
||||
import { debounceWrapper, scopes, variables, predefinedColors, webglColor2rgba, rgba2WebglColor } from '@/hook/utils';
|
||||
import { gl_Colors } from '@/hook/wave-view/render-utils';
|
||||
|
||||
export default {
|
||||
name: 'dide-setting',
|
||||
setup() {
|
||||
const { t, locale } = useI18n();
|
||||
import HelpIcon from '../help-icon.vue';
|
||||
|
||||
const languageSetting = reactive({
|
||||
options: [
|
||||
{
|
||||
value: 'en',
|
||||
text: 'English'
|
||||
},
|
||||
{
|
||||
value: 'zh',
|
||||
text: '中文'
|
||||
}
|
||||
]
|
||||
});
|
||||
defineComponent({ name: "dide-setting" });
|
||||
|
||||
function modifySignalTrackHeight() {
|
||||
document.body.style.setProperty('--display-signal-info-height', globalSetting.displaySignalHeight + 'px');
|
||||
}
|
||||
const { t, locale } = useI18n();
|
||||
locale.value = globalSetting.language;
|
||||
|
||||
const safeModifySignalTrackHeight = debounceWrapper(modifySignalTrackHeight, 200);
|
||||
|
||||
|
||||
return {
|
||||
t,
|
||||
languageSetting,
|
||||
globalSetting,
|
||||
safeModifySignalTrackHeight,
|
||||
locale,
|
||||
scopes,
|
||||
variables
|
||||
}
|
||||
watch(
|
||||
() => locale.value,
|
||||
() => {
|
||||
globalSetting.language = locale.value;
|
||||
localStorage.setItem('setting', JSON.stringify(globalSetting));
|
||||
}
|
||||
);
|
||||
|
||||
const wavecolor = reactive({
|
||||
options: [
|
||||
{
|
||||
value: 0,
|
||||
label: t('wavecolor.normal-bit')
|
||||
},
|
||||
{
|
||||
value: 1,
|
||||
label: t('wavecolor.normal-vec')
|
||||
},
|
||||
{
|
||||
value: 2,
|
||||
label: t('wavecolor.high-impedance')
|
||||
},
|
||||
{
|
||||
value: 3,
|
||||
label: t('wavecolor.unknown')
|
||||
}
|
||||
],
|
||||
glColorMap: [2, 5, 4, 1],
|
||||
currentOptionIndex: 0,
|
||||
colors: [
|
||||
webglColor2rgba(...gl_Colors.slice(2 * 4, 2 * 4 + 4)),
|
||||
webglColor2rgba(...gl_Colors.slice(5 * 4, 5 * 4 + 4)),
|
||||
webglColor2rgba(...gl_Colors.slice(4 * 4, 4 * 4 + 4)),
|
||||
webglColor2rgba(...gl_Colors.slice(1 * 4, 1 * 4 + 4)),
|
||||
],
|
||||
reset() {}
|
||||
});
|
||||
|
||||
watch(() => wavecolor.currentOptionIndex, () => {
|
||||
console.log(wavecolor.currentOptionIndex);
|
||||
});
|
||||
|
||||
watch(() => wavecolor.colors, () => {
|
||||
console.log('enter');
|
||||
const colorString = wavecolor.colors[wavecolor.currentOptionIndex];
|
||||
const rgba = rgba2WebglColor(colorString);
|
||||
if (rgba !== undefined) {
|
||||
const currentOption = wavecolor.options[wavecolor.currentOptionIndex];
|
||||
const waveRender = globalLookup.getWaveRender();
|
||||
const glColorIndex = wavecolor.glColorMap[currentOption.value];
|
||||
const colorUpdaters = [{ index: glColorIndex, rgba }];
|
||||
if (glColorIndex === 2) { // 默认情况下, value = 0 和 value = 1 保持一致
|
||||
colorUpdaters.push({ index: 3, rgba });
|
||||
}
|
||||
waveRender.updateGLColor(colorUpdaters, { updateMask: true });
|
||||
}
|
||||
}, { deep: true });
|
||||
|
||||
|
||||
const languageSetting = reactive({
|
||||
options: [
|
||||
{
|
||||
value: 'en',
|
||||
text: 'English'
|
||||
},
|
||||
{
|
||||
value: 'zh',
|
||||
text: '中文'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
function modifySignalTrackHeight() {
|
||||
document.body.style.setProperty('--display-signal-info-height', globalSetting.displaySignalHeight + 'px');
|
||||
const waveRender = globalLookup.getWaveRender();
|
||||
waveRender.render();
|
||||
}
|
||||
|
||||
const safeModifySignalTrackHeight = debounceWrapper(modifySignalTrackHeight, 200);
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.setting-wrapper {
|
||||
width: 600px;
|
||||
width: fit-content;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.setting-container {
|
||||
overflow-y: scroll;
|
||||
height: 99vh;
|
||||
}
|
||||
|
||||
.setting-section {
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
@ -136,22 +263,43 @@ export default {
|
||||
|
||||
.setting-option {
|
||||
margin: 5px;
|
||||
padding: 10px 12px;
|
||||
padding: 8px 12px;
|
||||
height: 40px;
|
||||
width: fit-content;
|
||||
border-radius: .5em;
|
||||
background-color: var(--background);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.option-title {
|
||||
min-width: 80px;
|
||||
margin-right: 12px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.el-slider__button {
|
||||
background-color: var(--background) !important;
|
||||
}
|
||||
|
||||
.el-switch__core .el-switch__action {
|
||||
background-color: var(--background) !important;
|
||||
}
|
||||
|
||||
.el-slider__stop {
|
||||
background-color: var(--sidebar-item-text) !important;
|
||||
}
|
||||
|
||||
.icon-help {
|
||||
cursor: pointer;
|
||||
transition: var(--animation-3s);
|
||||
-webkit-transition: var(--animation-3s);
|
||||
}
|
||||
|
||||
.icon-help:hover {
|
||||
color: var(--main-color);
|
||||
transition: var(--animation-3s);
|
||||
-webkit-transition: var(--animation-3s);
|
||||
}
|
||||
</style>
|
@ -1,111 +1,123 @@
|
||||
<template>
|
||||
<div class="vcd-sidebar-wrapper">
|
||||
<div class="display-signal-wrapper">
|
||||
<div style="height: var(--time-scale-height);"></div>
|
||||
<div class="display-signal-item"
|
||||
v-for="(signal, index) in globalLookup.currentWires" :key="index">
|
||||
<div class="signal-color-vendor">
|
||||
<span :class="makeSignalIconClass(signal)"></span>
|
||||
</div>
|
||||
<div class="signal-info">
|
||||
<div class="display-signal-wrapper" :style="sideBarWrapperStyle">
|
||||
<div class="display-signal-container" :style="sidedBarContainerStyle">
|
||||
<div :style="timeScaleStyle"></div>
|
||||
<div class="display-signal-item"
|
||||
:style="sideBarItemStyle"
|
||||
v-for="(signal, index) in globalLookup.currentWires" :key="index">
|
||||
<div class="signal-color-vendor">
|
||||
<span :class="makeSignalIconClass(signal)"></span>
|
||||
</div>
|
||||
<div class="signal-info">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="makeFullSignalNameDeps(signal)"
|
||||
placement="top"
|
||||
raw-content
|
||||
>
|
||||
<div class="signal-info-name">
|
||||
{{ signal.name }}
|
||||
</div></el-tooltip>
|
||||
<div class="signal-info">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="makeFullSignalNameDeps(signal)"
|
||||
placement="top"
|
||||
raw-content
|
||||
>
|
||||
<div class="signal-info-name">
|
||||
<span class="signal-parent-info" v-show="showParent">{{ signal.parent.name }}</span>
|
||||
<span>{{ signal.name }}</span>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
|
||||
<div class="signal-info-width">
|
||||
<div :class="signal.size > 1 ? 'signal-info-caption' : ''">
|
||||
{{ makeSignalCaption(signal) }}
|
||||
<div class="signal-info-width" v-show="showWidth">
|
||||
<div :class="signal.size > 1 ? 'signal-info-caption' : ''">
|
||||
{{ makeSignalCaption(signal) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="signal-info-current-value-wrapper">
|
||||
<span></span>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="globalLookup.currentSignalValues[signal.link] + ''"
|
||||
placement="top"
|
||||
raw-content
|
||||
><div class="signal-info-current-value">
|
||||
{{ globalLookup.currentSignalValues[signal.link] }}
|
||||
</div></el-tooltip>
|
||||
</div>
|
||||
<div class="signal-info-current-value-wrapper">
|
||||
<span></span>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="globalLookup.currentSignalValues[signal.link] + ''"
|
||||
placement="top"
|
||||
raw-content
|
||||
><div class="signal-info-current-value">
|
||||
{{ globalLookup.currentSignalValues[signal.link] }}
|
||||
</div></el-tooltip>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="add-signal-button" @click="addSignal">
|
||||
<span class="iconfont icon-Collections"></span>
|
||||
<span class="iconfont icon-collections"></span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/* eslint-disable */
|
||||
import { reactive } from 'vue';
|
||||
<script setup>
|
||||
import { reactive, computed, defineComponent } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { emitter, globalLookup, globalSetting } from '@/hook/global';
|
||||
import { emitter, globalLookup, globalSetting, globalStyle } from '@/hook/global';
|
||||
import { makeIconClass } from '@/hook/utils';
|
||||
|
||||
export default {
|
||||
name: 'sidebar',
|
||||
setup() {
|
||||
const { t } = useI18n();
|
||||
const { t } = useI18n();
|
||||
defineComponent({ name: 'side-bar' });
|
||||
|
||||
function addSignal() {
|
||||
emitter.emit('right-nav', 0);
|
||||
const showWidth = computed(() => globalSetting.displaySignalInfoScope.includes('width'));
|
||||
const showParent = computed(() => globalSetting.displaySignalInfoScope.includes('parent'));
|
||||
|
||||
const timeScaleStyle = computed(() => ({
|
||||
height: `${globalStyle.timeScaleHeight}px`
|
||||
}));
|
||||
|
||||
const sideBarWrapperStyle = computed(() => ({
|
||||
padding: `${globalStyle.sideBarPadding}px`
|
||||
}));
|
||||
|
||||
const sidedBarContainerStyle = computed(() => ({
|
||||
transform: `translateY(${- globalStyle.yOffset}px)`,
|
||||
transition: globalSetting.renderAnimation ? 'var(--animation-3s)' : 'unset'
|
||||
}));
|
||||
|
||||
const sideBarItemStyle = computed(() => ({
|
||||
margin: `${globalStyle.sideBarItemMargin}px`
|
||||
}));
|
||||
|
||||
function addSignal() {
|
||||
emitter.emit('right-nav', 0);
|
||||
}
|
||||
|
||||
function makeSignalIconClass(signal) {
|
||||
return 'iconfont ' + makeIconClass(signal);
|
||||
}
|
||||
|
||||
function makeSignalCaption(signal) {
|
||||
return signal.size === 1 ? '' : `${signal.size - 1}:0`;
|
||||
}
|
||||
|
||||
function makeFullSignalNameDeps(signal) {
|
||||
const deps = [];
|
||||
while (signal) {
|
||||
if (signal.name && signal.type) {
|
||||
deps.push(signal);
|
||||
}
|
||||
signal = signal.parent;
|
||||
}
|
||||
let htmlString = '';
|
||||
for (let i = deps.length - 1; i >= 0; -- i) {
|
||||
const mod = deps[i];
|
||||
// const displayName = mod.name.length > 6 ? mod.name.substring(0, 6) + '...' : mod.name;
|
||||
const iconClass = makeIconClass(mod);
|
||||
const iconText = `<span class="iconfont ${iconClass}"></span> ${mod.name}`;
|
||||
|
||||
function makeSignalIconClass(signal) {
|
||||
return 'iconfont ' + makeIconClass(signal);
|
||||
}
|
||||
htmlString += iconText;
|
||||
|
||||
function makeSignalCaption(signal) {
|
||||
return signal.size === 1 ? '' : `${signal.size - 1}:0`;
|
||||
}
|
||||
|
||||
function makeFullSignalNameDeps(signal) {
|
||||
const deps = [];
|
||||
while (signal) {
|
||||
if (signal.name && signal.type) {
|
||||
deps.push(signal);
|
||||
}
|
||||
signal = signal.parent;
|
||||
}
|
||||
let htmlString = '';
|
||||
for (let i = deps.length - 1; i >= 0; -- i) {
|
||||
const mod = deps[i];
|
||||
// const displayName = mod.name.length > 6 ? mod.name.substring(0, 6) + '...' : mod.name;
|
||||
const iconClass = makeIconClass(mod);
|
||||
const iconText = `<span class="iconfont ${iconClass}"></span> ${mod.name}`;
|
||||
|
||||
htmlString += iconText;
|
||||
|
||||
if (i > 0) {
|
||||
htmlString += '<div class="dep-arrow"></div>';
|
||||
}
|
||||
}
|
||||
htmlString = '<div class="signal-info-tooltip-wrapper">' + htmlString + '</div>';
|
||||
return htmlString;
|
||||
}
|
||||
|
||||
return {
|
||||
t,
|
||||
globalLookup,
|
||||
makeSignalIconClass,
|
||||
makeSignalCaption,
|
||||
makeFullSignalNameDeps,
|
||||
addSignal
|
||||
if (i > 0) {
|
||||
htmlString += '<div class="dep-arrow"></div>';
|
||||
}
|
||||
}
|
||||
htmlString = '<div class="signal-info-tooltip-wrapper">' + htmlString + '</div>';
|
||||
return htmlString;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@ -132,20 +144,20 @@ export default {
|
||||
}
|
||||
|
||||
.display-signal-wrapper {
|
||||
padding: var(--sidebar-padding);
|
||||
background-color: var(--sidebar);
|
||||
border: solid 1px var(--sidebar-border);
|
||||
min-width: var(--sidebar-width);
|
||||
height: calc(100vh - 90px);
|
||||
box-shadow: 0 0 15px 1px rgb(16, 16, 16);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.display-signal-item {
|
||||
border-radius: .5em;
|
||||
background-color: var(--background);
|
||||
margin: 5px;
|
||||
height: var(--display-signal-info-height);
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.display-signal-item::selection {
|
||||
@ -182,6 +194,8 @@ export default {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.signal-info-tooltip-wrapper {
|
||||
@ -223,4 +237,15 @@ export default {
|
||||
cursor: none;
|
||||
}
|
||||
|
||||
.signal-parent-info {
|
||||
font-size: .8rem;
|
||||
border-radius: .5em;
|
||||
padding: 2px 5px;
|
||||
color: var(--sidebar);
|
||||
background-color: var(--main-color);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
</style>
|
@ -56,8 +56,8 @@ export default {
|
||||
}
|
||||
|
||||
const expandManage = reactive({
|
||||
expanded: true,
|
||||
expandTagClass: mods.length === 0 ? '' : 'expand-tag',
|
||||
expanded: false,
|
||||
expandTagClass: mods.length === 0 ? '' : 'collapse-tag',
|
||||
click() {
|
||||
this.expanded = !this.expanded;
|
||||
if (this.expandTagClass) {
|
||||
|
@ -13,19 +13,23 @@
|
||||
@blur="searchManage.displayResult = false"
|
||||
/>
|
||||
</div>
|
||||
<div class="search-result-wrapper" v-if="searchManage.displayResult | searchManage.mouseOnResult">
|
||||
<div
|
||||
v-if="searchManage.displayResult | searchManage.mouseOnResult"
|
||||
:style="searchResultWrapper"
|
||||
class="search-result-wrapper"
|
||||
id="search-result-wrapper"
|
||||
>
|
||||
<div class="search-result"
|
||||
@mouseenter="searchManage.mouseOnResult = true"
|
||||
@mouseleave="searchManage.mouseOnResult = false"
|
||||
>
|
||||
<div v-if="searchManage.searchResult.length > 0">
|
||||
<div v-for="(searchResult, index) in searchManage.searchResult"
|
||||
:key="index"
|
||||
:class="globalLookup.currentWires.has(searchResult.module) ? 'vcd-treeview-selected' : ''"
|
||||
@click="toggleRender(searchResult.module)">
|
||||
<div v-html="searchResult.htmlString" class="search-result-item"></div>
|
||||
</div>
|
||||
|
||||
<div v-for="(searchResult, index) in searchManage.searchResult"
|
||||
:key="index"
|
||||
:class="globalLookup.currentWires.has(searchResult.module) ? 'vcd-treeview-selected' : ''"
|
||||
@click="toggleRender(searchResult.module)">
|
||||
<div v-html="searchResult.htmlString" class="search-result-item"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
{{ t('search-nothing') }}
|
||||
@ -36,71 +40,72 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { reactive } from 'vue';
|
||||
<script setup>
|
||||
import { reactive, computed, defineComponent, nextTick } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { globalSetting, globalLookup, emitter } from '@/hook/global';
|
||||
import { debounceWrapper, makeSearchResultItem } from '@/hook/utils';
|
||||
import { toggleRender } from '@/hook/render';
|
||||
const { t } = useI18n();
|
||||
|
||||
export default {
|
||||
name: 'tree-view-search',
|
||||
setup() {
|
||||
const { t } = useI18n();
|
||||
defineComponent({ name: 'search-box' });
|
||||
|
||||
const searchManage = reactive({
|
||||
content: '',
|
||||
displayResult: false,
|
||||
mouseOnResult: false,
|
||||
searchResult: []
|
||||
});
|
||||
const searchResultWrapper = computed(() => ({
|
||||
right: '55px',
|
||||
transition: 'var(--animation-3s)'
|
||||
}));
|
||||
|
||||
|
||||
const searchManage = reactive({
|
||||
content: '',
|
||||
displayResult: false,
|
||||
mouseOnResult: false,
|
||||
searchResult: [],
|
||||
searchResultEl: undefined,
|
||||
searchResultLeft: -5,
|
||||
});
|
||||
|
||||
function search() {
|
||||
const searchString = searchManage.content.trim();
|
||||
if (searchString.length === 0) {
|
||||
searchManage.displayResult = false;
|
||||
return;
|
||||
}
|
||||
function search() {
|
||||
const searchString = searchManage.content.trim();
|
||||
if (searchString.length === 0) {
|
||||
searchManage.displayResult = false;
|
||||
return;
|
||||
}
|
||||
|
||||
searchManage.displayResult = true;
|
||||
searchManage.searchResult = [];
|
||||
searchManage.displayResult = true;
|
||||
searchManage.searchResult = [];
|
||||
|
||||
const stacks = [ { name: '', body: globalLookup.topModules } ];
|
||||
const searchRule = new Set(globalSetting.searchScope);
|
||||
const caseSensitivity = globalSetting.caseSensitivity;
|
||||
const displayParentOnly = globalSetting.displayParentOnly;
|
||||
const stacks = [ { name: '', body: globalLookup.topModules } ];
|
||||
const searchRule = new Set(globalSetting.searchScope);
|
||||
const caseSensitivity = globalSetting.caseSensitivity;
|
||||
const displayParentOnly = globalSetting.displayParentOnly;
|
||||
|
||||
while (stacks.length > 0) {
|
||||
const p = stacks.pop();
|
||||
if (p.body && p.body.length) {
|
||||
p.body.forEach(mod => stacks.push(mod));
|
||||
}
|
||||
|
||||
const searchResultItem = makeSearchResultItem(searchString, p, searchRule, caseSensitivity, displayParentOnly);
|
||||
if (searchResultItem) {
|
||||
emitter.emit('signal-search', searchResultItem);
|
||||
}
|
||||
}
|
||||
while (stacks.length > 0) {
|
||||
const p = stacks.pop();
|
||||
if (p.body && p.body.length) {
|
||||
p.body.forEach(mod => stacks.push(mod));
|
||||
}
|
||||
|
||||
emitter.on('signal-search', searchResultItem => {
|
||||
searchManage.searchResult.push(searchResultItem);
|
||||
});
|
||||
|
||||
const safeSearch = debounceWrapper(search, 500);
|
||||
|
||||
return {
|
||||
searchManage,
|
||||
safeSearch,
|
||||
globalLookup,
|
||||
debounceWrapper,
|
||||
t,
|
||||
toggleRender
|
||||
const searchResultItem = makeSearchResultItem(searchString, p, searchRule, caseSensitivity, displayParentOnly);
|
||||
if (searchResultItem) {
|
||||
emitter.emit('signal-search', searchResultItem);
|
||||
}
|
||||
}
|
||||
|
||||
nextTick(() => {
|
||||
searchManage.searchResultEl = document.getElementById('search-result-wrapper');
|
||||
if (searchManage.searchResultEl) {
|
||||
searchManage.searchResultLeft = 480 - searchManage.searchResultEl.offsetWidth;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
emitter.on('signal-search', searchResultItem => {
|
||||
searchManage.searchResult.push(searchResultItem);
|
||||
});
|
||||
|
||||
const safeSearch = debounceWrapper(search, 500);
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
@ -80,15 +80,15 @@ export default {
|
||||
color: #C76B3C;
|
||||
}
|
||||
|
||||
.icon-String {
|
||||
.icon-string {
|
||||
color: #8CC265;
|
||||
}
|
||||
|
||||
.icon-R {
|
||||
.icon-real {
|
||||
color: #5fb4d8;
|
||||
}
|
||||
|
||||
.icon-task- {
|
||||
.icon-task {
|
||||
color: orange;
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ export default {
|
||||
margin: 3px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 25px;
|
||||
height: 23px;
|
||||
padding-left: 3px;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
@ -124,6 +124,6 @@ export default {
|
||||
border-radius: .5em;
|
||||
background-color: var(--color-deepPurple);
|
||||
padding: 3px;
|
||||
font-size: 15px;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
@ -1,5 +1,6 @@
|
||||
import mitt from 'mitt';
|
||||
import { reactive } from 'vue';
|
||||
import WebGL2WaveRender from './wave-view/render-wave';
|
||||
|
||||
const emitter = mitt();
|
||||
|
||||
@ -35,8 +36,11 @@ const globalLookup = reactive({
|
||||
tgcd: null,
|
||||
// 其实就是 signalValues
|
||||
chango: {},
|
||||
|
||||
// 初始化时会被定义
|
||||
render: () => {},
|
||||
waveRender: undefined,
|
||||
pstate: undefined,
|
||||
|
||||
xScale: 1,
|
||||
|
||||
@ -60,25 +64,75 @@ const globalLookup = reactive({
|
||||
childModule.parent = module;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {WebGL2WaveRender}
|
||||
*/
|
||||
getWaveRender() {
|
||||
return this.waveRender;
|
||||
}
|
||||
});
|
||||
|
||||
const globalStyle = reactive({
|
||||
timeScaleHeight: 30,
|
||||
sideBarPadding: 10,
|
||||
sideBarItemMargin: 5,
|
||||
vcdRenderPadding: 24,
|
||||
yOffset: 0,
|
||||
});
|
||||
|
||||
const globalSetting = reactive({
|
||||
language: 'zh',
|
||||
caseSensitivity: false,
|
||||
displayParentOnly: false,
|
||||
displaySignalHeight: 50,
|
||||
searchMode: 'so', // so, mo, sm
|
||||
searchScope: ['wire', 'reg', 'integer'],
|
||||
displaySignalInfoScope: ['width', 'parent'],
|
||||
wheelZoomRatio: 1,
|
||||
minGridWidth: 300
|
||||
displaySignalInfoScope: ['width'],
|
||||
HorizontalScalingRatio: 1,
|
||||
HorizontalRollRatio: 1,
|
||||
VerticalRollRario: 1,
|
||||
minGridWidth: 300,
|
||||
prerender: true,
|
||||
renderAnimation: false,
|
||||
});
|
||||
|
||||
function loadSetting() {
|
||||
const settingString = localStorage.getItem('setting')
|
||||
try {
|
||||
const setting = JSON.parse(settingString);
|
||||
return setting;
|
||||
} catch (error) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const storedSetting = loadSetting();
|
||||
if (storedSetting) {
|
||||
for (const key of Reflect.ownKeys(storedSetting)) {
|
||||
const value = storedSetting[key];
|
||||
if (value !== undefined) {
|
||||
globalSetting[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// for (const key of Reflect.ownKeys(globalSetting)) {
|
||||
// const value = localStorageGetItem(key);
|
||||
// if (value !== undefined && value !== null) {
|
||||
// globalSetting[key] = value;
|
||||
// }
|
||||
// }
|
||||
|
||||
const signalValues = {};
|
||||
|
||||
export {
|
||||
emitter,
|
||||
globalLookup,
|
||||
globalSetting,
|
||||
globalStyle,
|
||||
signalValues
|
||||
};
|
@ -1,6 +1,7 @@
|
||||
import { globalLookup, globalSetting, signalValues } from "./global";
|
||||
import { domContainer, pluginRenderTimeGrid, pluginRenderValues, mountTree,
|
||||
genOnWheel, genKeyHandler, keyBindo } from './wave-view';
|
||||
genOnWheel, genKeyHandler, keyEvent } from './wave-view';
|
||||
|
||||
import { findCurrentSignalValue } from './utils';
|
||||
|
||||
let mainRenderEl = null;
|
||||
@ -38,6 +39,7 @@ function makeWaveView(parentElement) {
|
||||
if (!parentElement) {
|
||||
parentElement = getMainRenderEl();
|
||||
}
|
||||
|
||||
const container = domContainer({
|
||||
elemento: mountTree.defaultElemento,
|
||||
layers: mountTree.defaultLayers,
|
||||
@ -55,7 +57,7 @@ function makeWaveView(parentElement) {
|
||||
console.log('updater');
|
||||
};
|
||||
|
||||
container.elo.container.addEventListener('wheel', genOnWheel(parentElement, container.pstate, globalLookup, keyBindo));
|
||||
container.elo.container.addEventListener('wheel', genOnWheel(parentElement, container.pstate, globalLookup, keyEvent));
|
||||
}
|
||||
|
||||
|
||||
|
47
src/hook/types/index.d.ts
vendored
47
src/hook/types/index.d.ts
vendored
@ -1,47 +0,0 @@
|
||||
export interface RenderElements {
|
||||
grid: HTMLDivElement
|
||||
view: HTMLDivElement
|
||||
values: HTMLDivElement
|
||||
}
|
||||
|
||||
export interface ChangoItem {
|
||||
kind: string
|
||||
wave: Array<number | string>
|
||||
lineVao: WebGLVertexArrayObject
|
||||
maskVao: WebGLVertexArrayObject
|
||||
}
|
||||
|
||||
export interface WireInfoItem {
|
||||
kind: string
|
||||
link: string
|
||||
name: string
|
||||
size: number
|
||||
parent: WireInfoItem
|
||||
type: string
|
||||
}
|
||||
|
||||
export interface Pstate {
|
||||
width: number
|
||||
height: number
|
||||
xScale: number
|
||||
xOffset: number
|
||||
yOffset: number
|
||||
yStep: number
|
||||
yDuty: number
|
||||
}
|
||||
|
||||
export interface WebGLLocation {
|
||||
colors: WebGLUniformLocation
|
||||
shifts: WebGLUniformLocation
|
||||
scale: WebGLUniformLocation
|
||||
offset: WebGLUniformLocation
|
||||
pos: number
|
||||
widthShifts: WebGLUniformLocation
|
||||
gl: WebGL2RenderingContext
|
||||
}
|
||||
|
||||
export interface PerspectivePoint {
|
||||
x: number
|
||||
y: number
|
||||
color: number
|
||||
}
|
@ -1 +0,0 @@
|
||||
module.Render = {};
|
@ -1,5 +1,3 @@
|
||||
/* eslint-disable no-undef */
|
||||
|
||||
import { Stream } from "stream";
|
||||
import { globalLookup } from "./global";
|
||||
|
||||
@ -12,22 +10,6 @@ async function getVcdStream() {
|
||||
return ostream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<Uint8Array>}
|
||||
*/
|
||||
async function readVcdFile() {
|
||||
const response = await fetch('test.vcd');
|
||||
const blob = await response.blob();
|
||||
const reader = new FileReader();
|
||||
return new Promise((resolve, reject) => {
|
||||
reader.onload = event => {
|
||||
const fileContent = event.target.result;
|
||||
const unintarray = new Uint8Array(fileContent);
|
||||
resolve(unintarray);
|
||||
};
|
||||
reader.readAsArrayBuffer(blob);
|
||||
});
|
||||
}
|
||||
|
||||
function debounceWrapper(fn, delay) {
|
||||
let timer
|
||||
@ -47,13 +29,13 @@ function makeIconClass(mod) {
|
||||
case 'module': return 'icon-memory-chip';
|
||||
case 'begin': return 'icon-brackets';
|
||||
case 'fork': return 'icon-fork';
|
||||
case 'function': return 'icon-Function';
|
||||
case 'task': return 'icon-task-';
|
||||
case 'function': return 'icon-function';
|
||||
case 'task': return 'icon-task';
|
||||
|
||||
case 'event': return 'icon-prevent';
|
||||
case 'integer': return 'icon-integer';
|
||||
case 'parameter': return 'icon-parameter';
|
||||
case 'real': return 'icon-R';
|
||||
case 'real': return 'icon-real';
|
||||
case 'realtime': return 'icon-wave-square';
|
||||
case 'reg': return 'icon-register';
|
||||
case 'supply0': return 'icon-wave-square';
|
||||
@ -68,7 +50,7 @@ function makeIconClass(mod) {
|
||||
case 'wand': return 'icon-wave-square';
|
||||
case 'wire': return 'icon-wave-square';
|
||||
case 'wor': return 'icon-wave-square';
|
||||
case 'string': return 'icon-String';
|
||||
case 'string': return 'icon-string';
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -322,12 +304,57 @@ function isVariable(wire) {
|
||||
return variables.has(wire.type);
|
||||
}
|
||||
|
||||
function webglColor2rgba(r, g, b, a) {
|
||||
const standRed = Math.floor(r * 255);
|
||||
const standGreen = Math.floor(g * 255);
|
||||
const standBlue = Math.floor(b * 255);
|
||||
return `rgba(${standRed},${standGreen},${standBlue},${a})`;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} rgba
|
||||
* @returns {{
|
||||
* red: number,
|
||||
* green: number,
|
||||
* blue: number,
|
||||
* alpha: number
|
||||
* } | undefined}
|
||||
*/
|
||||
function rgba2WebglColor(rgba) {
|
||||
const match = rgba.match(/^rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+(\.\d+)?)\)$/);
|
||||
if (match) {
|
||||
return {
|
||||
red: parseInt(match[1]) / 255,
|
||||
green: parseInt(match[2]) / 255,
|
||||
blue: parseInt(match[3]) / 255,
|
||||
alpha: parseFloat(match[4])
|
||||
};
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const predefinedColors = [
|
||||
'#ff4500',
|
||||
'#ff8c00',
|
||||
'#ffd700',
|
||||
'#90ee90',
|
||||
'#00ced1',
|
||||
'#1e90ff',
|
||||
'#c71585',
|
||||
'rgba(255, 69, 0, 0.68)',
|
||||
'rgb(255, 120, 0)',
|
||||
'hsv(51, 100, 98)',
|
||||
'hsva(120, 40, 94, 0.5)',
|
||||
'hsl(181, 100%, 37%)',
|
||||
'hsla(209, 100%, 56%, 0.73)',
|
||||
'#c7158577'
|
||||
];
|
||||
|
||||
|
||||
export {
|
||||
getVcdStream,
|
||||
readVcdFile,
|
||||
debounceWrapper,
|
||||
makeSearchResultItem,
|
||||
handleTimeScale,
|
||||
@ -341,5 +368,8 @@ export {
|
||||
gcd,
|
||||
findCurrentSignalValue,
|
||||
normaliseUsingGCD,
|
||||
updateWireCurrentValue
|
||||
updateWireCurrentValue,
|
||||
predefinedColors,
|
||||
webglColor2rgba,
|
||||
rgba2WebglColor
|
||||
};
|
@ -1,107 +1,108 @@
|
||||
'use strict';
|
||||
|
||||
const getX = require('./get-x.js');
|
||||
const surferer = require('./surferer.js');
|
||||
import getX from './get-x';
|
||||
import surferer from './surferer';
|
||||
|
||||
const skipT = (wave, iStart, tLimit) => {
|
||||
let iRes = iStart;
|
||||
let [tRes, vRes] = wave[iStart];
|
||||
for (let i = iStart; i < wave.length; i++) {
|
||||
const [t, v] = wave[i];
|
||||
if (t >= tLimit) {
|
||||
break;
|
||||
let iRes = iStart;
|
||||
let [tRes, vRes] = wave[iStart];
|
||||
for (let i = iStart; i < wave.length; i++) {
|
||||
const [t, v] = wave[i];
|
||||
if (t >= tLimit) {
|
||||
break;
|
||||
}
|
||||
iRes = i;
|
||||
tRes = t;
|
||||
vRes = v;
|
||||
}
|
||||
iRes = i;
|
||||
tRes = t;
|
||||
vRes = v;
|
||||
}
|
||||
return [iRes, vRes, tRes];
|
||||
return [iRes, vRes, tRes];
|
||||
};
|
||||
|
||||
const bracer = (lane, desc, pstate) => {
|
||||
const body = lane.body;
|
||||
const { yStep } = pstate;
|
||||
let { clock, valid, ready, up } = body;
|
||||
up = up || 1;
|
||||
const body = lane.body;
|
||||
const { yStep } = pstate;
|
||||
let { clock, valid, ready, up } = body;
|
||||
up = up || 1;
|
||||
|
||||
const res = [];
|
||||
let count = 0;
|
||||
const res = [];
|
||||
let count = 0;
|
||||
|
||||
if (clock && clock.ref) {
|
||||
const clockWave = desc.chango[clock.ref].wave;
|
||||
const clockEr = surferer(clockWave, pstate);
|
||||
let tPrevClock = 0;
|
||||
if (clock && clock.ref) {
|
||||
const clockWave = desc.chango[clock.ref].wave;
|
||||
const clockEr = surferer(clockWave, pstate);
|
||||
let tPrevClock = 0;
|
||||
|
||||
if (valid && valid.ref) {
|
||||
const validWave = desc.chango[valid.ref].wave;
|
||||
let iValid = 0;
|
||||
let vValid;
|
||||
if (valid && valid.ref) {
|
||||
const validWave = desc.chango[valid.ref].wave;
|
||||
let iValid = 0;
|
||||
let vValid;
|
||||
|
||||
if (ready && ready.ref) {
|
||||
const readyWave = desc.chango[ready.ref].wave;
|
||||
let iReady = 0;
|
||||
let vReady;
|
||||
if (ready && ready.ref) {
|
||||
const readyWave = desc.chango[ready.ref].wave;
|
||||
let iReady = 0;
|
||||
let vReady;
|
||||
|
||||
for (const iClock of clockEr) {
|
||||
const [tClock, vClock] = clockWave[iClock];
|
||||
if (vClock) {
|
||||
[iValid, vValid] = skipT(validWave, iValid, tClock);
|
||||
[iReady, vReady] = skipT(readyWave, iReady, tClock);
|
||||
const xClock = getX(pstate, tClock);
|
||||
const xPrevClock = getX(pstate, tPrevClock);
|
||||
const width = xClock - xPrevClock;
|
||||
const height = up * yStep;
|
||||
if (xClock > 0 && xPrevClock > 0 && width > 0) {
|
||||
if (vValid) {
|
||||
if (width >= 1) {
|
||||
if (vReady) {
|
||||
res.push(['rect', {fill: 'url(\'#valid&ready\')', width: Math.round(width), height, x: Math.round(xPrevClock), y: -height}]);
|
||||
} else {
|
||||
res.push(['rect', {fill: 'url(\'#valid&~ready\')', width: Math.round(width), height, x: Math.round(xPrevClock), y: -height}]);
|
||||
}
|
||||
count++;
|
||||
} else {
|
||||
count += 10;
|
||||
for (const iClock of clockEr) {
|
||||
const [tClock, vClock] = clockWave[iClock];
|
||||
if (vClock) {
|
||||
[iValid, vValid] = skipT(validWave, iValid, tClock);
|
||||
[iReady, vReady] = skipT(readyWave, iReady, tClock);
|
||||
const xClock = getX(pstate, tClock);
|
||||
const xPrevClock = getX(pstate, tPrevClock);
|
||||
const width = xClock - xPrevClock;
|
||||
const height = up * yStep;
|
||||
if (xClock > 0 && xPrevClock > 0 && width > 0) {
|
||||
if (vValid) {
|
||||
if (width >= 1) {
|
||||
if (vReady) {
|
||||
res.push(['rect', { fill: 'url(\'#valid&ready\')', width: Math.round(width), height, x: Math.round(xPrevClock), y: -height }]);
|
||||
} else {
|
||||
res.push(['rect', { fill: 'url(\'#valid&~ready\')', width: Math.round(width), height, x: Math.round(xPrevClock), y: -height }]);
|
||||
}
|
||||
count++;
|
||||
} else {
|
||||
count += 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
tPrevClock = tClock;
|
||||
if (count > 500) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tPrevClock = tClock;
|
||||
if (count > 500) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const iClock of clockEr) {
|
||||
const [tClock, vClock] = clockWave[iClock];
|
||||
if (vClock) {
|
||||
[iValid, vValid] = skipT(validWave, iValid, tClock);
|
||||
const xClock = getX(pstate, tClock);
|
||||
const xPrevClock = getX(pstate, tPrevClock);
|
||||
const width = xClock - xPrevClock;
|
||||
const height = up * yStep;
|
||||
if (xClock > 0 && xPrevClock > 0 && width > 0) {
|
||||
if (vValid) {
|
||||
if (width >= 1) {
|
||||
res.push(['rect', {fill: 'url(\'#valid\')', width: Math.round(width), height, x: Math.round(xPrevClock), y: -height}]);
|
||||
count++;
|
||||
} else {
|
||||
count += 10;
|
||||
} else {
|
||||
for (const iClock of clockEr) {
|
||||
const [tClock, vClock] = clockWave[iClock];
|
||||
if (vClock) {
|
||||
[iValid, vValid] = skipT(validWave, iValid, tClock);
|
||||
const xClock = getX(pstate, tClock);
|
||||
const xPrevClock = getX(pstate, tPrevClock);
|
||||
const width = xClock - xPrevClock;
|
||||
const height = up * yStep;
|
||||
if (xClock > 0 && xPrevClock > 0 && width > 0) {
|
||||
if (vValid) {
|
||||
if (width >= 1) {
|
||||
res.push(['rect', { fill: 'url(\'#valid\')', width: Math.round(width), height, x: Math.round(xPrevClock), y: -height }]);
|
||||
count++;
|
||||
} else {
|
||||
count += 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
tPrevClock = tClock;
|
||||
if (count > 500) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
tPrevClock = tClock;
|
||||
if (count > 500) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
return res;
|
||||
};
|
||||
|
||||
module.exports = bracer;
|
||||
|
||||
|
||||
export default bracer;
|
||||
|
||||
/* eslint complexity: [1, 55] */
|
@ -1,7 +1,9 @@
|
||||
const WebGL2WaveRender = require('./gen-render-waves-gl.js');
|
||||
const renderCursor = require('./render-cursor.js');
|
||||
const genResizeHandler = require('./gen-resize-handler.js');
|
||||
const mTree = require('./mount-tree.js');
|
||||
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;
|
||||
@ -108,20 +110,29 @@ const domContainer = (obj) => {
|
||||
|
||||
const pstate = {
|
||||
fontHeight,
|
||||
width: 1024, // [px] window width
|
||||
height: 1024, // [px] window height
|
||||
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]
|
||||
topBarHeight: fontHeight * 1.5, // [px]
|
||||
botBarHeight: fontHeight * 1.5, // [px]
|
||||
xOffset: sidebarWidth,
|
||||
yOffset: -40, // [px]
|
||||
yStep: 54, // = 24 // [px] wave lane height
|
||||
yOffset: -40, // [px]
|
||||
yStep: 54, // = 24 // [px] wave lane height
|
||||
yDuty: 0.6,
|
||||
|
||||
// for animation
|
||||
oldXOffset: sidebarWidth,
|
||||
oldYOffset: -40,
|
||||
oldYStep: 54,
|
||||
oldYDuty: 0.6,
|
||||
|
||||
sidebarWidth,
|
||||
container
|
||||
};
|
||||
|
||||
globalLookup.pstate = pstate;
|
||||
|
||||
return {
|
||||
elo,
|
||||
pstate,
|
||||
@ -138,6 +149,7 @@ const domContainer = (obj) => {
|
||||
tgcd: deso.tgcd,
|
||||
timescale: deso.timescale,
|
||||
xScale: deso.xScale || 8,
|
||||
oldXScale: deso.xScale || 8,
|
||||
numLanes: deso.currentWires.size,
|
||||
t0: deso.t0,
|
||||
time: deso.time
|
||||
@ -157,16 +169,20 @@ const domContainer = (obj) => {
|
||||
setTime(pstate, deso.timeOpt.value);
|
||||
}
|
||||
|
||||
let waveRender = new WebGL2WaveRender(elo, deso, pstate, obj.renderPlugins);
|
||||
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);
|
||||
@ -183,6 +199,4 @@ const domContainer = (obj) => {
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = domContainer;
|
||||
|
||||
/* eslint-env browser */
|
||||
export default domContainer;
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const formatTime = (t, expo) => {
|
||||
const prefixes = ['T', 'G', 'M', 'k', '', 'm', 'µ', 'n', 'p', 'f', 'a', 'z', 'y'];
|
||||
const ts1 = 14 - expo;
|
||||
@ -8,4 +6,4 @@ const formatTime = (t, expo) => {
|
||||
return (t * mult).toLocaleString() + ' ' + prefix + 's';
|
||||
};
|
||||
|
||||
module.exports = formatTime;
|
||||
export default formatTime;
|
||||
|
@ -1,143 +1,145 @@
|
||||
'use strict';
|
||||
const replacer = '...';
|
||||
|
||||
// '\u205D'
|
||||
|
||||
const format = (fmt, len) => {
|
||||
len = BigInt(len);
|
||||
{
|
||||
const m = fmt.match(/^%(?<sign>[s])?(?<radix>[bodh])(?<elen>\d+)?$/);
|
||||
if (m) {
|
||||
const radix = ({b: 2, o: 8, d: 10, h: 16, H: 16})[m.groups.radix];
|
||||
if (m.groups.sign) {
|
||||
return (val, pos) => {
|
||||
if ((val >> (len - 1n)) & 1n) {
|
||||
val = val - (2n ** len);
|
||||
}
|
||||
let txtOrig = val.toString(radix);
|
||||
if (txtOrig.length <= pos) {
|
||||
return txtOrig;
|
||||
}
|
||||
const sign = (val < 0) ? '-' : '+';
|
||||
if (pos === 1) {
|
||||
return sign;
|
||||
}
|
||||
if (pos === 2) {
|
||||
return sign + '\u205D';
|
||||
}
|
||||
return sign + '\u205D' + txtOrig.slice(2 - pos);
|
||||
};
|
||||
}
|
||||
if (Number(m.groups.elen) > 0) {
|
||||
const elen = BigInt(m.groups.elen);
|
||||
return (val, pos) => {
|
||||
let txtRes = [];
|
||||
for (let i = 0n; i < len; i += elen) {
|
||||
const chunk = (val >> i) & (2n ** elen - 1n);
|
||||
txtRes.unshift(chunk.toString(radix));
|
||||
}
|
||||
txtRes = '{' + txtRes.join(', ') + '}';
|
||||
if (txtRes.length <= pos) {
|
||||
return txtRes;
|
||||
}
|
||||
if (pos === 1) {
|
||||
return '\u205D';
|
||||
}
|
||||
return '\u205D' + txtRes.slice(1 - pos);
|
||||
};
|
||||
}
|
||||
return (val, pos) => {
|
||||
let txtOrig = val.toString(radix);
|
||||
if (txtOrig.length <= pos) {
|
||||
return txtOrig;
|
||||
len = BigInt(len);
|
||||
{
|
||||
const m = fmt.match(/^%(?<sign>[s])?(?<radix>[bodh])(?<elen>\d+)?$/);
|
||||
if (m) {
|
||||
const radix = ({ b: 2, o: 8, d: 10, h: 16, H: 16 })[m.groups.radix];
|
||||
if (m.groups.sign) {
|
||||
return (val, pos) => {
|
||||
if ((val >> (len - 1n)) & 1n) {
|
||||
val = val - (2n ** len);
|
||||
}
|
||||
let txtOrig = val.toString(radix);
|
||||
if (txtOrig.length <= pos) {
|
||||
return txtOrig;
|
||||
}
|
||||
const sign = (val < 0) ? '-' : '+';
|
||||
if (pos === 1) {
|
||||
return sign;
|
||||
}
|
||||
if (pos === 2) {
|
||||
return sign + replacer;
|
||||
}
|
||||
return sign + replacer + txtOrig.slice(2 - pos);
|
||||
};
|
||||
}
|
||||
if (Number(m.groups.elen) > 0) {
|
||||
const elen = BigInt(m.groups.elen);
|
||||
return (val, pos) => {
|
||||
let txtRes = [];
|
||||
for (let i = 0n; i < len; i += elen) {
|
||||
const chunk = (val >> i) & (2n ** elen - 1n);
|
||||
txtRes.unshift(chunk.toString(radix));
|
||||
}
|
||||
txtRes = '{' + txtRes.join(', ') + '}';
|
||||
if (txtRes.length <= pos) {
|
||||
return txtRes;
|
||||
}
|
||||
if (pos === 1) {
|
||||
return replacer;
|
||||
}
|
||||
return replacer + txtRes.slice(1 - pos);
|
||||
};
|
||||
}
|
||||
return (val, pos) => {
|
||||
let txtOrig = val.toString(radix);
|
||||
if (txtOrig.length <= pos) {
|
||||
return txtOrig;
|
||||
}
|
||||
if (pos === 1) {
|
||||
return replacer;
|
||||
}
|
||||
return replacer + txtOrig.slice(1 - pos);
|
||||
};
|
||||
}
|
||||
if (pos === 1) {
|
||||
return '\u205D';
|
||||
} {
|
||||
const m = fmt.match(/^%a$/);
|
||||
if (m) {
|
||||
return (val, pos) => {
|
||||
let txtRes = '';
|
||||
for (let i = 0n; i < len; i += 8n) {
|
||||
txtRes = String.fromCharCode(Number((val >> i) & 0xffn)) + txtRes;
|
||||
}
|
||||
txtRes = txtRes.trim();
|
||||
if (txtRes.length <= pos) {
|
||||
return txtRes;
|
||||
}
|
||||
txtRes = txtRes.slice(0, pos - 1) + replacer;
|
||||
return txtRes;
|
||||
};
|
||||
}
|
||||
} {
|
||||
const m = fmt.match(/^%(?<form>[fe])(?<elen>32|64)$/);
|
||||
if (m) {
|
||||
const buf = new ArrayBuffer(8);
|
||||
const bufBInt = new BigInt64Array(buf);
|
||||
const elen = BigInt(m.groups.elen);
|
||||
const bufFloat = new ((elen === 32n) ? Float32Array : Float64Array)(buf);
|
||||
const mask = (elen === 32n) ? 0xffffffffn : 0xffffffffffffffffn;
|
||||
if (m.groups.form === 'f') {
|
||||
if (len > elen) {
|
||||
return (val, pos) => {
|
||||
let txtRes = [];
|
||||
for (let i = 0n; i < len; i += elen) {
|
||||
bufBInt[0] = (val >> i) & mask;
|
||||
const fval = bufFloat[0];
|
||||
txtRes.unshift(fval.toString());
|
||||
}
|
||||
txtRes = '{' + txtRes.join(', ') + '}';
|
||||
if (txtRes.length <= pos) {
|
||||
return txtRes;
|
||||
}
|
||||
if (pos === 1) {
|
||||
return replacer;
|
||||
}
|
||||
return replacer + txtRes.slice(1 - pos);
|
||||
};
|
||||
}
|
||||
return (val, pos) => {
|
||||
bufBInt[0] = val & mask;
|
||||
const fval = bufFloat[0];
|
||||
let txtOrig;
|
||||
txtOrig = fval.toString();
|
||||
if (txtOrig.length <= pos) {
|
||||
return txtOrig;
|
||||
}
|
||||
for (let i = pos; i >= 0; i--) {
|
||||
txtOrig = fval.toPrecision(i + 1);
|
||||
if (txtOrig.length <= pos) {
|
||||
return txtOrig;
|
||||
}
|
||||
txtOrig = fval.toExponential(i);
|
||||
if (txtOrig.length <= pos) {
|
||||
return txtOrig;
|
||||
}
|
||||
}
|
||||
return (val < 0) ? '-' : '+';
|
||||
};
|
||||
} else {// e
|
||||
return (val, pos) => {
|
||||
bufBInt[0] = val & mask;
|
||||
const fval = bufFloat[0];
|
||||
let txtOrig;
|
||||
txtOrig = fval.toExponential();
|
||||
if (txtOrig.length <= pos) {
|
||||
return txtOrig;
|
||||
}
|
||||
for (let i = 4; i <= pos; i++) {
|
||||
txtOrig = fval.toExponential(pos - i);
|
||||
if (txtOrig.length <= pos) {
|
||||
return txtOrig;
|
||||
}
|
||||
}
|
||||
return (val < 0) ? '-' : '+';
|
||||
};
|
||||
}
|
||||
}
|
||||
return '\u205D' + txtOrig.slice(1 - pos);
|
||||
};
|
||||
}
|
||||
} {
|
||||
const m = fmt.match(/^%a$/);
|
||||
if (m) {
|
||||
return (val, pos) => {
|
||||
let txtRes = '';
|
||||
for (let i = 0n; i < len; i += 8n) {
|
||||
txtRes = String.fromCharCode(Number((val >> i) & 0xffn)) + txtRes;
|
||||
}
|
||||
txtRes = txtRes.trim();
|
||||
if (txtRes.length <= pos) {
|
||||
return txtRes;
|
||||
}
|
||||
txtRes = txtRes.slice(0, pos - 1) + '\u205D';
|
||||
return txtRes;
|
||||
};
|
||||
}
|
||||
} {
|
||||
const m = fmt.match(/^%(?<form>[fe])(?<elen>32|64)$/);
|
||||
if (m) {
|
||||
const buf = new ArrayBuffer(8);
|
||||
const bufBInt = new BigInt64Array(buf);
|
||||
const elen = BigInt(m.groups.elen);
|
||||
const bufFloat = new ((elen === 32n) ? Float32Array : Float64Array)(buf);
|
||||
const mask = (elen === 32n) ? 0xffffffffn : 0xffffffffffffffffn;
|
||||
if (m.groups.form === 'f') {
|
||||
if (len > elen) {
|
||||
return (val, pos) => {
|
||||
let txtRes = [];
|
||||
for (let i = 0n; i < len; i += elen) {
|
||||
bufBInt[0] = (val >> i) & mask;
|
||||
const fval = bufFloat[0];
|
||||
txtRes.unshift(fval.toString());
|
||||
}
|
||||
txtRes = '{' + txtRes.join(', ') + '}';
|
||||
if (txtRes.length <= pos) {
|
||||
return txtRes;
|
||||
}
|
||||
if (pos === 1) {
|
||||
return '\u205D';
|
||||
}
|
||||
return '\u205D' + txtRes.slice(1 - pos);
|
||||
};
|
||||
}
|
||||
return (val, pos) => {
|
||||
bufBInt[0] = val & mask;
|
||||
const fval = bufFloat[0];
|
||||
let txtOrig;
|
||||
txtOrig = fval.toString();
|
||||
if (txtOrig.length <= pos) {
|
||||
return txtOrig;
|
||||
}
|
||||
for (let i = pos; i >= 0; i--) {
|
||||
txtOrig = fval.toPrecision(i + 1);
|
||||
if (txtOrig.length <= pos) {
|
||||
return txtOrig;
|
||||
}
|
||||
txtOrig = fval.toExponential(i);
|
||||
if (txtOrig.length <= pos) {
|
||||
return txtOrig;
|
||||
}
|
||||
}
|
||||
return (val < 0) ? '-' : '+';
|
||||
};
|
||||
} else {// e
|
||||
return (val, pos) => {
|
||||
bufBInt[0] = val & mask;
|
||||
const fval = bufFloat[0];
|
||||
let txtOrig;
|
||||
txtOrig = fval.toExponential();
|
||||
if (txtOrig.length <= pos) {
|
||||
return txtOrig;
|
||||
}
|
||||
for (let i = 4; i <= pos; i++) {
|
||||
txtOrig = fval.toExponential(pos - i);
|
||||
if (txtOrig.length <= pos) {
|
||||
return txtOrig;
|
||||
}
|
||||
}
|
||||
return (val < 0) ? '-' : '+';
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
return () => '?';
|
||||
return () => '?';
|
||||
};
|
||||
|
||||
module.exports = format;
|
||||
export default format;
|
||||
|
@ -1,12 +1,10 @@
|
||||
'use strict';
|
||||
const { keyName } = require('w3c-keyname');
|
||||
|
||||
const {keyName} = require('w3c-keyname');
|
||||
|
||||
const executeKeyHandler = (key, keyBindo, pstate, cm) => {
|
||||
return (keyBindo[key] || keyBindo.nop).fn(pstate, cm);
|
||||
const executeKeyHandler = (key, keyEvent, pstate, cm) => {
|
||||
return (keyEvent[key] || keyEvent.nop).fn(pstate, cm);
|
||||
};
|
||||
|
||||
const genKeyHandler = (div, pstate, deso, cm, keyBindo, plugins) => {
|
||||
const genKeyHandler = (div, pstate, deso, cm, keyEvent, plugins) => {
|
||||
return event => {
|
||||
|
||||
const modifier = (
|
||||
@ -17,7 +15,7 @@ const genKeyHandler = (div, pstate, deso, cm, keyBindo, plugins) => {
|
||||
// const key = modifier + event.key;
|
||||
const key = modifier + keyName(event);
|
||||
|
||||
if (executeKeyHandler(key, keyBindo, pstate, cm)) {
|
||||
if (executeKeyHandler(key, keyEvent, pstate, cm)) {
|
||||
event.stopPropagation();
|
||||
if (plugins != undefined) {
|
||||
plugins.map(fn => fn(key, event));
|
||||
@ -27,5 +25,7 @@ const genKeyHandler = (div, pstate, deso, cm, keyBindo, plugins) => {
|
||||
};
|
||||
};
|
||||
|
||||
exports.executeKeyHandler = executeKeyHandler;
|
||||
exports.genKeyHandler = genKeyHandler;
|
||||
export default {
|
||||
executeKeyHandler,
|
||||
genKeyHandler
|
||||
};
|
@ -1,13 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
const genOnWheel = (element, pstate, deso, keyBindo, plugins) =>
|
||||
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 (keyBindo[key].fn(pstate)) {
|
||||
if (keyEvent[key].fn(pstate)) {
|
||||
if (plugins != undefined) {
|
||||
plugins.map(fn => fn(key, event));
|
||||
}
|
||||
@ -16,7 +14,7 @@ const genOnWheel = (element, pstate, deso, keyBindo, plugins) =>
|
||||
event.preventDefault();
|
||||
} else if (event.shiftKey) {
|
||||
const key = (deltaY < 0) ? 'Shift+icon:scrollUp' : ((deltaY > 0) ? 'Shift+icon:scrollDown' : 'nop');
|
||||
if (keyBindo[key].fn(pstate)) {
|
||||
if (keyEvent[key].fn(pstate)) {
|
||||
if (plugins != undefined) {
|
||||
plugins.map(fn => fn(key, event));
|
||||
}
|
||||
@ -24,8 +22,17 @@ const genOnWheel = (element, pstate, deso, keyBindo, plugins) =>
|
||||
}
|
||||
event.preventDefault();
|
||||
} else if (deltaX !== 0 && deltaY === 0) {
|
||||
const key = (deltaX < 0) ? 'icon:scrollLeft': 'icon:scrollRight';
|
||||
if (keyBindo[key].fn(pstate)) {
|
||||
const key = (deltaX < 0) ? 'scrollLeft': 'scrollRight';
|
||||
if (keyEvent[key].fn(pstate)) {
|
||||
if (plugins != undefined) {
|
||||
plugins.map(fn => fn(key, event));
|
||||
}
|
||||
deso.render();
|
||||
}
|
||||
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));
|
||||
}
|
||||
@ -35,4 +42,4 @@ const genOnWheel = (element, pstate, deso, keyBindo, plugins) =>
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = genOnWheel;
|
||||
export default genOnWheel;
|
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const xOffsetUpdate = require('./x-offset-update.js');
|
||||
import xOffsetUpdate from './x-offset-update';
|
||||
|
||||
const genResizeHandler = pstate =>
|
||||
(width, height) => {
|
||||
@ -8,8 +6,6 @@ const genResizeHandler = pstate =>
|
||||
pstate.width = width;
|
||||
pstate.height = height;
|
||||
|
||||
console.log('time', time);
|
||||
|
||||
// Y
|
||||
const yOffsetMax = (numLanes + 2) * 2 * yStep;
|
||||
if (yOffsetMax < 0) {
|
||||
@ -21,7 +17,7 @@ const genResizeHandler = pstate =>
|
||||
|
||||
const xScaleMin = pstate.xScaleMin = 0.001;
|
||||
pstate.xScale = (xScale < xScaleMin) ? xScaleMin : xScale;
|
||||
xOffsetUpdate(pstate, xOffset);
|
||||
xOffsetUpdate(pstate, () => xOffset);
|
||||
};
|
||||
|
||||
module.exports = genResizeHandler;
|
||||
export default genResizeHandler;
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const getElement = divName => {
|
||||
if (typeof divName === 'string') {
|
||||
const c = document.getElementById(divName);
|
||||
@ -11,6 +9,6 @@ const getElement = divName => {
|
||||
return divName;
|
||||
};
|
||||
|
||||
module.exports = getElement;
|
||||
export default getElement;
|
||||
|
||||
/* eslint-env browser */
|
||||
|
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const format = require('./format.js');
|
||||
import format from './format';
|
||||
|
||||
const getLabel = (lane) => {
|
||||
if (typeof lane !== 'object') {
|
||||
@ -31,4 +29,4 @@ const getLabel = (lane) => {
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = getLabel;
|
||||
export default getLabel;
|
||||
|
@ -1,26 +1,24 @@
|
||||
'use strict';
|
||||
import lister from './lister';
|
||||
|
||||
const lister = require('./lister.js');
|
||||
|
||||
const getListing = async (readers) => {
|
||||
let listing = [];
|
||||
const r = readers.find(reader => reader.ext === 'lst');
|
||||
if (r) {
|
||||
const utf8Decoder = new TextDecoder('utf-8');
|
||||
const list = lister();
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
let { done, value } = await r.reader.read();
|
||||
if (typeof value !== 'string') {
|
||||
value = utf8Decoder.decode(value, {stream: true});
|
||||
}
|
||||
list.onChunk(value);
|
||||
if (done) {
|
||||
listing = list.getTrace();
|
||||
break;
|
||||
}
|
||||
async function getListing(readers) {
|
||||
let listing = [];
|
||||
const r = readers.find(reader => reader.ext === 'lst');
|
||||
if (r) {
|
||||
const utf8Decoder = new TextDecoder('utf-8');
|
||||
const list = lister();
|
||||
for (let i = 0; i < 10000; i++) {
|
||||
let { done, value } = await r.reader.read();
|
||||
if (typeof value !== 'string') {
|
||||
value = utf8Decoder.decode(value, { stream: true });
|
||||
}
|
||||
list.onChunk(value);
|
||||
if (done) {
|
||||
listing = list.getTrace();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return listing;
|
||||
};
|
||||
return listing;
|
||||
}
|
||||
|
||||
module.exports = getListing;
|
||||
export default getListing;
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const getT = (x, pstate) => {
|
||||
const {xOffset, xScale, tgcd } = pstate;
|
||||
return Math.round((x / xScale) - (xOffset / xScale)) * tgcd;
|
||||
@ -10,4 +8,4 @@ const getT = (x, pstate) => {
|
||||
// (t / tgcd) * xScale / 2 + (xOffset * width / 2) = x;
|
||||
};
|
||||
|
||||
module.exports = getT;
|
||||
export default getT;
|
||||
|
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const getX = (pstate, time) =>
|
||||
time * pstate.xScale + pstate.xOffset;
|
||||
|
||||
module.exports = getX;
|
||||
export default getX;
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
// Fletcher Style checksum
|
||||
|
||||
const hash = str => {
|
||||
@ -12,4 +10,4 @@ const hash = str => {
|
||||
return (sum2 ^ sum1 ^ (sum2 >> 5) ^ (sum1 >> 5)) % 36;
|
||||
};
|
||||
|
||||
module.exports = hash;
|
||||
export default hash;
|
@ -1,27 +1,28 @@
|
||||
'use strict';
|
||||
import getElement from './get-element';
|
||||
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 mountTree from './mount-tree';
|
||||
import genKeyHandler from './gen-key-handler';
|
||||
import genOnWheel from './gen-on-wheel';
|
||||
import xOffsetUpdate from './x-offset-update';
|
||||
import getX from './get-x';
|
||||
import getT from './get-t';
|
||||
|
||||
const getElement = require('./get-element.js');
|
||||
const getListing = require('./get-listing.js');
|
||||
const domContainer = require('./dom-container.js');
|
||||
const pluginRenderValues = require('./plugin-render-values.js');
|
||||
const pluginRenderTimeGrid = require('./plugin-render-time-grid.js');
|
||||
const keyBindo = require('./key-bindo.js');
|
||||
const mountTree = require('./mount-tree.js');
|
||||
const genKeyHandler = require('./gen-key-handler.js');
|
||||
const genOnWheel = require('./gen-on-wheel.js');
|
||||
const xOffsetUpdate = require('./x-offset-update.js');
|
||||
const getX = require('./get-x.js');
|
||||
const getT = require('./get-t.js');
|
||||
|
||||
exports.getListing = getListing;
|
||||
exports.getElement = getElement;
|
||||
exports.domContainer = domContainer;
|
||||
exports.pluginRenderValues = pluginRenderValues;
|
||||
exports.pluginRenderTimeGrid = pluginRenderTimeGrid;
|
||||
exports.keyBindo = keyBindo;
|
||||
exports.mountTree = mountTree;
|
||||
exports.genKeyHandler = genKeyHandler;
|
||||
exports.genOnWheel = genOnWheel;
|
||||
exports.xOffsetUpdate = xOffsetUpdate;
|
||||
exports.getX = getX;
|
||||
exports.getT = getT;
|
||||
export {
|
||||
getListing,
|
||||
getElement,
|
||||
domContainer,
|
||||
pluginRenderValues,
|
||||
pluginRenderTimeGrid,
|
||||
keyEvent,
|
||||
mountTree,
|
||||
genKeyHandler,
|
||||
genOnWheel,
|
||||
xOffsetUpdate,
|
||||
getX,
|
||||
getT
|
||||
};
|
||||
|
@ -1,86 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const xOffsetUpdate = require('./x-offset-update.js');
|
||||
const xScaleUpdate = require('./x-scale-update.js');
|
||||
|
||||
const yScroll = delta => (pstate, cm) => {
|
||||
const info = cm.getScrollInfo();
|
||||
cm.scrollTo(null, info.top + info.clientHeight * delta);
|
||||
return false;
|
||||
};
|
||||
|
||||
const pluso = {
|
||||
desc: 'Zoom in time',
|
||||
fn: pstate => xScaleUpdate(pstate, 10 / 9 * pstate.xScale)
|
||||
};
|
||||
|
||||
const minuso = {
|
||||
desc: 'Zoom out time',
|
||||
fn: pstate => xScaleUpdate(pstate, 9 / 10 * pstate.xScale)
|
||||
};
|
||||
|
||||
const fullo = {
|
||||
desc: 'All of time',
|
||||
fn: pstate => xScaleUpdate(pstate, pstate.xScaleMin)
|
||||
};
|
||||
|
||||
const scroll = {
|
||||
left: {
|
||||
desc: 'Scroll into the past',
|
||||
fn: pstate => xOffsetUpdate(pstate, pstate.xOffset + pstate.time)
|
||||
},
|
||||
right: {
|
||||
desc: 'Scroll into the future',
|
||||
fn: pstate => xOffsetUpdate(pstate, pstate.xOffset - pstate.time)
|
||||
},
|
||||
up: {
|
||||
desc: 'scroll up',
|
||||
fn: yScroll(-.1)
|
||||
},
|
||||
down: {
|
||||
desc: 'scroll down',
|
||||
fn: yScroll(.1)
|
||||
}
|
||||
};
|
||||
|
||||
const editable = {
|
||||
desc: 'Toggle edit mode',
|
||||
fn: (pstate, cm) => {
|
||||
console.log('editable', pstate, cm);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
// 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,
|
||||
'Alt+/': editable,
|
||||
|
||||
// wheel
|
||||
'icon:scrollLeft': scroll.left,
|
||||
'icon:scrollRight': scroll.right,
|
||||
'Shift+icon:scrollUp': scroll.left,
|
||||
'Shift+icon:scrollDown': scroll.right,
|
||||
'Ctrl+icon:scrollUp': pluso,
|
||||
'Ctrl+icon:scrollDown': minuso,
|
||||
|
||||
// CAN'T DO: Alt + e, d, f, l
|
||||
|
||||
// ArrowUp: scroll.up, 'Shift+ArrowUp': scroll.up,
|
||||
// ArrowDown: scroll.down, 'Shift+ArrowDown': scroll.down,
|
||||
|
||||
// PageUp: {desc: 'scroll page up', fn: yScroll(-1)},
|
||||
// PageDown: {desc: 'scroll page down', fn: yScroll(1)},
|
||||
|
||||
nop: { fn: () => false }
|
||||
};
|
102
src/hook/wave-view/keyEvent.js
Normal file
102
src/hook/wave-view/keyEvent.js
Normal file
@ -0,0 +1,102 @@
|
||||
import { globalSetting } from '../global';
|
||||
|
||||
import xOffsetUpdate from './x-offset-update';
|
||||
import yOffsetUpdate from './y-offset-update';
|
||||
|
||||
import xScaleUpdate from './x-scale-update';
|
||||
|
||||
|
||||
const xScaleLevels = {
|
||||
1: 10 / 9,
|
||||
2: 10 / 7,
|
||||
3: 10 / 6,
|
||||
4: 10 / 5,
|
||||
5: 10 / 4
|
||||
};
|
||||
|
||||
const xOffsetLevel = {
|
||||
1: 5,
|
||||
2: 4,
|
||||
3: 3,
|
||||
4: 1,
|
||||
5: 0.5
|
||||
};
|
||||
|
||||
const yOffsetLevel = {
|
||||
1: 20,
|
||||
2: 40,
|
||||
3: 80,
|
||||
4: 160,
|
||||
5: 320
|
||||
};
|
||||
|
||||
const pluso = {
|
||||
desc: 'Zoom in time',
|
||||
fn: pstate => xScaleUpdate(pstate, () => pstate.xScale * xScaleLevels[globalSetting.HorizontalScalingRatio])
|
||||
};
|
||||
|
||||
const minuso = {
|
||||
desc: 'Zoom out time',
|
||||
fn: pstate => xScaleUpdate(pstate, () => pstate.xScale / xScaleLevels[globalSetting.HorizontalScalingRatio])
|
||||
};
|
||||
|
||||
const fullo = {
|
||||
desc: 'All of time',
|
||||
fn: pstate => xScaleUpdate(pstate, () => pstate.xScaleMin)
|
||||
};
|
||||
|
||||
const scroll = {
|
||||
left: {
|
||||
desc: 'Scroll into the past',
|
||||
fn: pstate => xOffsetUpdate(pstate, () => pstate.xOffset + pstate.time / xOffsetLevel[globalSetting.HorizontalRollRatio])
|
||||
},
|
||||
right: {
|
||||
desc: 'Scroll into the future',
|
||||
fn: pstate => xOffsetUpdate(pstate, () => pstate.xOffset - pstate.time / xOffsetLevel[globalSetting.HorizontalRollRatio])
|
||||
},
|
||||
up: {
|
||||
desc: 'scroll up',
|
||||
fn: pstate => yOffsetUpdate(pstate, () => pstate.yOffset - yOffsetLevel[globalSetting.VerticalRollRario])
|
||||
},
|
||||
down: {
|
||||
desc: 'scroll down',
|
||||
fn: pstate => yOffsetUpdate(pstate, () => pstate.yOffset + yOffsetLevel[globalSetting.VerticalRollRario])
|
||||
}
|
||||
};
|
||||
|
||||
const editable = {
|
||||
desc: 'Toggle edit mode',
|
||||
fn: (pstate, cm) => {
|
||||
console.log('editable', pstate, cm);
|
||||
}
|
||||
};
|
||||
|
||||
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,
|
||||
|
||||
'Shift+icon:scrollUp': scroll.left,
|
||||
'Shift+icon:scrollDown': scroll.right,
|
||||
'Ctrl+icon:scrollUp': pluso,
|
||||
'Ctrl+icon:scrollDown': minuso,
|
||||
|
||||
|
||||
nop: { fn: () => false }
|
||||
};
|
@ -1,23 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = () => {
|
||||
const trace = {};
|
||||
let tail = '';
|
||||
return {
|
||||
onChunk: (chunk) => {
|
||||
const rows = (tail + chunk).split('\n');
|
||||
// console.log('chunk:', chunk.length, 'tail:', tail.length, 'rows:', rows.length);
|
||||
tail = rows.pop();
|
||||
rows.map(row => {
|
||||
const m = row.match(/\s*([0-9a-f]+):\s*([0-9a-f]+)\s+(.+)/);
|
||||
if (m) {
|
||||
const pc = parseInt(m[1], 16);
|
||||
const op = m[2];
|
||||
const asm = m[3].replace(/\t/, ' ');
|
||||
trace[pc] = {op, asm};
|
||||
}
|
||||
});
|
||||
},
|
||||
getTrace: () => trace
|
||||
};
|
||||
export default () => {
|
||||
const trace = {};
|
||||
let tail = '';
|
||||
return {
|
||||
onChunk: (chunk) => {
|
||||
const rows = (tail + chunk).split('\n');
|
||||
// console.log('chunk:', chunk.length, 'tail:', tail.length, 'rows:', rows.length);
|
||||
tail = rows.pop();
|
||||
rows.map(row => {
|
||||
const m = row.match(/\s*([0-9a-f]+):\s*([0-9a-f]+)\s+(.+)/);
|
||||
if (m) {
|
||||
const pc = parseInt(m[1], 16);
|
||||
const op = m[2];
|
||||
const asm = m[3].replace(/\t/, ' ');
|
||||
trace[pc] = { op, asm };
|
||||
}
|
||||
});
|
||||
},
|
||||
getTrace: () => trace
|
||||
};
|
||||
};
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const defaultElemento = {
|
||||
container: ['div', { class: 'vcd-container', id: 'vcd-container' }],
|
||||
grid: ['div', { class: 'vcd-vline', id: 'vcd-vline' }],
|
||||
@ -43,9 +41,9 @@ const createContainer = (els, layers) => {
|
||||
return els.container;
|
||||
};
|
||||
|
||||
exports.defaultElemento = defaultElemento;
|
||||
exports.defaultLayers = defaultLayers;
|
||||
exports.createElemento = createElemento;
|
||||
exports.createContainer = createContainer;
|
||||
|
||||
/* eslint-env browser */
|
||||
export default {
|
||||
defaultElemento,
|
||||
defaultLayers,
|
||||
createElemento,
|
||||
createContainer
|
||||
};
|
@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
import onml from 'onml';
|
||||
|
||||
const onml = require('onml');
|
||||
const format = require('./format');
|
||||
import format from './format';
|
||||
|
||||
const getElement = divName => {
|
||||
if (typeof divName === 'string') {
|
||||
|
@ -1,69 +1,67 @@
|
||||
'use strict';
|
||||
import genSVG from 'onml/gen-svg.js';
|
||||
import stringify from 'onml/stringify.js';
|
||||
|
||||
const genSVG = require('onml/gen-svg.js');
|
||||
const stringify = require('onml/stringify.js');
|
||||
|
||||
const formatTime = require('./format-time.js');
|
||||
const getT = require('./get-t.js');
|
||||
import formatTime from './format-time.js';
|
||||
import getT from './get-t.js';
|
||||
|
||||
const round10 = n =>
|
||||
([
|
||||
/*0 1 2 3 4 5 6 7 8 9 */
|
||||
0, 1, 2, 4, 4, 5, 5, 5, 10, 10,
|
||||
/*10 11 12 13 14 15 16 17 18 19 */
|
||||
10, 10, 10, 15, 15, 15, 15, 20, 20, 20
|
||||
])[Math.round(n)]
|
||||
|| Math.round(n);
|
||||
([
|
||||
/*0 1 2 3 4 5 6 7 8 9 */
|
||||
0, 1, 2, 4, 4, 5, 5, 5, 10, 10,
|
||||
/*10 11 12 13 14 15 16 17 18 19 */
|
||||
10, 10, 10, 15, 15, 15, 15, 20, 20, 20
|
||||
])[Math.round(n)]
|
||||
|| Math.round(n);
|
||||
|
||||
const getTimeGrid = pstate => {
|
||||
const { sidebarWidth, width, height, timescale, xScale, tgcd, xOffset, topBarHeight, botBarHeight } = pstate;
|
||||
const fontHeight = 16;
|
||||
// const timeLineStart = (xOffset * width / 2) |0;
|
||||
const { sidebarWidth, width, height, timescale, xScale, tgcd, xOffset, topBarHeight, botBarHeight } = pstate;
|
||||
const fontHeight = 16;
|
||||
// const timeLineStart = (xOffset * width / 2) |0;
|
||||
|
||||
const timeGrid = ['g', {}];
|
||||
const timeGrid = ['g', {}];
|
||||
|
||||
const xStartExact = getT(sidebarWidth, pstate);
|
||||
const xFinishExact = getT(width, pstate);
|
||||
const density = 1;
|
||||
const xLines = Math.round(density * width / sidebarWidth);
|
||||
const xStartExact = getT(sidebarWidth, pstate);
|
||||
const xFinishExact = getT(width, pstate);
|
||||
const density = 1;
|
||||
const xLines = Math.round(density * width / sidebarWidth);
|
||||
|
||||
const xStep = ((xFinishExact - xStartExact) / xLines);
|
||||
const xExp = Math.pow(10, Math.log10(xStep) |0);
|
||||
const xDelta = round10(xStep / xExp) * xExp;
|
||||
const xStep = ((xFinishExact - xStartExact) / xLines);
|
||||
const xExp = Math.pow(10, Math.log10(xStep) | 0);
|
||||
const xDelta = round10(xStep / xExp) * xExp;
|
||||
|
||||
const xStart = Math.ceil(xStartExact / xDelta) * xDelta;
|
||||
const xFinish = Math.floor(xFinishExact / xDelta) * xDelta;
|
||||
const xStart = Math.ceil(xStartExact / xDelta) * xDelta;
|
||||
const xFinish = Math.floor(xFinishExact / xDelta) * xDelta;
|
||||
|
||||
for (let t = xStart; t <= xFinish; t += xDelta) {
|
||||
const x = Math.round(t / tgcd * xScale + xOffset);
|
||||
timeGrid.push(['g', {},
|
||||
['line', {
|
||||
class: 'wd-grid-time',
|
||||
x1: x,
|
||||
x2: x,
|
||||
y2: height
|
||||
}],
|
||||
['text', {
|
||||
class: 'wd-grid-time',
|
||||
x: x,
|
||||
y: (topBarHeight + fontHeight) / 2
|
||||
}, formatTime(t, timescale)],
|
||||
['text', {
|
||||
class: 'wd-grid-time',
|
||||
x: x,
|
||||
y: height - (botBarHeight - fontHeight) / 2
|
||||
}, formatTime(t, timescale)]
|
||||
]);
|
||||
}
|
||||
for (let t = xStart; t <= xFinish; t += xDelta) {
|
||||
const x = Math.round(t / tgcd * xScale + xOffset);
|
||||
timeGrid.push(['g', {},
|
||||
['line', {
|
||||
class: 'wd-grid-time',
|
||||
x1: x,
|
||||
x2: x,
|
||||
y2: height
|
||||
}],
|
||||
['text', {
|
||||
class: 'wd-grid-time',
|
||||
x: x,
|
||||
y: (topBarHeight + fontHeight) / 2
|
||||
}, formatTime(t, timescale)],
|
||||
['text', {
|
||||
class: 'wd-grid-time',
|
||||
x: x,
|
||||
y: height - (botBarHeight - fontHeight) / 2
|
||||
}, formatTime(t, timescale)]
|
||||
]);
|
||||
}
|
||||
|
||||
return timeGrid;
|
||||
return timeGrid;
|
||||
};
|
||||
|
||||
const pluginRenderTimeGrid = (desc, pstate, els) => {
|
||||
const {width, height} = pstate;
|
||||
const ml = genSVG(width, height);
|
||||
ml.push(getTimeGrid(pstate));
|
||||
els.grid.innerHTML = stringify(ml);
|
||||
const { width, height } = pstate;
|
||||
const ml = genSVG(width, height);
|
||||
ml.push(getTimeGrid(pstate));
|
||||
els.grid.innerHTML = stringify(ml);
|
||||
};
|
||||
|
||||
module.exports = pluginRenderTimeGrid;
|
||||
export default pluginRenderTimeGrid;
|
@ -1,8 +1,6 @@
|
||||
'use strict';
|
||||
import renderValues from './render-values';
|
||||
|
||||
const renderValues = require('./render-values.js');
|
||||
|
||||
function pluginRenderValues(desc, pstate, els) {
|
||||
export default function pluginRenderValues(desc, pstate, els) {
|
||||
const gen = renderValues(desc, pstate);
|
||||
for (let i = 0; i < 1e6; i++) {
|
||||
const iter = gen.next();
|
||||
@ -12,5 +10,3 @@ function pluginRenderValues(desc, pstate, els) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = pluginRenderValues;
|
||||
|
@ -1,10 +1,8 @@
|
||||
'use strict';
|
||||
import genSVG from 'onml/gen-svg.js';
|
||||
import stringify from 'onml/stringify.js';
|
||||
|
||||
const genSVG = require('onml/gen-svg.js');
|
||||
const stringify = require('onml/stringify.js');
|
||||
const formatTime = require('./format-time.js');
|
||||
|
||||
const { globalLookup } = require('../global');
|
||||
import formatTime from './format-time';
|
||||
import { globalLookup } from '../global';
|
||||
|
||||
const renderCursor = (cfg, pstate) => {
|
||||
const { xmargin, fontWidth, fontHeight } = cfg;
|
||||
@ -58,4 +56,4 @@ const renderCursor = (cfg, pstate) => {
|
||||
return stringify(genSVG(2 * xmargin, height).concat(body));
|
||||
};
|
||||
|
||||
module.exports = renderCursor;
|
||||
export default renderCursor;
|
@ -40,7 +40,7 @@ void main() {
|
||||
vec2 shift = shifts[pos.y];
|
||||
vec2 widthShift = widthShifts[pos.w];
|
||||
gl_Position = vec4(
|
||||
float(pos.x) * scale.x + offset.x + float(widthShift.x),
|
||||
float(pos.x) * scale.x + offset.x + float(widthShift.x) + shift.y,
|
||||
float(shift.x) * scale.y + offset.y + float(widthShift.y),
|
||||
1, 1
|
||||
);
|
||||
|
@ -28,11 +28,11 @@ const screenWidthPixel = window.screen.width * getRatio() / 100;
|
||||
const gl_Colors = new Float32Array([
|
||||
0, 0, 0, 0, // 0: 空
|
||||
|
||||
0, 0, 1, 1, // 1: 高阻态 Z
|
||||
0, 0, 1, 1, // 1: 未知态 X
|
||||
0.2, 0.847, 0.1, 1, // 2: value = 0 用于 width = 1 的信号
|
||||
0.2, 0.847, 0.1, 1, // 3: value = 1 用于 width = 1 的信号
|
||||
0.9, 0.2, 0.2, 1, // 4: 未知态 X
|
||||
.5, 1, 1, 1, // 5: vec 用于 width > 1 的信号
|
||||
0.9, 0.2, 0.2, 1, // 4: 高阻态 Z
|
||||
0.486, 0.302, 1., 1, // 5: vec 用于 width > 1 的信号
|
||||
|
||||
1, 1, 0, 1, // 6: yellow
|
||||
1, 0, 1, 1, // 7: strange purple
|
||||
@ -41,23 +41,38 @@ const gl_Colors = new Float32Array([
|
||||
0, 1, 1, .5, // 9: (h H) weak 1
|
||||
1, 0, 0, .5, // 10: (w W) weak unknown
|
||||
|
||||
0, 0, 1, 0.1, // 11: 高阻态 Z 遮罩
|
||||
0, 0, 1, 0.1, // 11: 未知态 X 遮罩
|
||||
0.2, 0.847, 0.1, 0.1, // 12: value = 0 遮罩
|
||||
0.2, 0.847, 0.1, 0.1, // 13: value = 1 遮罩
|
||||
0.9, 0.2, 0.2, 0.1, // 14: 未知态 X 遮罩
|
||||
.5, 1, 1, 0.1 // 15: vec 遮罩
|
||||
0.9, 0.2, 0.2, 0.1, // 14: 高阻态 Z 遮罩
|
||||
0.486, 0.302, 1., 0.1 // 15: vec 遮罩
|
||||
]);
|
||||
|
||||
|
||||
// 控制方向
|
||||
// 特殊偏移量
|
||||
// 第一列 Y 第二列 保留
|
||||
const gl_Shifts = new Float32Array([ // 14
|
||||
0, 0, // 0
|
||||
1, -1, // 1
|
||||
1, 0, // 2
|
||||
1, 1, // 3
|
||||
-1, -1, // 4
|
||||
0, 0, // 0
|
||||
1, 0, // 1
|
||||
1, 0, // 2
|
||||
1, 0, // 3
|
||||
-1, 0, // 4
|
||||
-1, 0, // 5
|
||||
-1, 1 // 6
|
||||
-1, 0 // 6
|
||||
]);
|
||||
|
||||
// 为了满足 vec 类型的波形的开头和结尾的那个小小的内嵌的、不受scale影响的值
|
||||
// 第一列 Y 第二列 X 在所有计算完成后的额外偏移量
|
||||
const barShift = 0.005;
|
||||
|
||||
const gl_Shifts_for_bar = new Float32Array([
|
||||
0, 0, // 0
|
||||
1, barShift, // 1
|
||||
1, -barShift, // 2
|
||||
1, 0, // 3
|
||||
-1, barShift, // 4
|
||||
-1, -barShift, // 5
|
||||
-1, 0 // 6
|
||||
]);
|
||||
|
||||
const gl_Shifts_map = new Map();
|
||||
@ -78,7 +93,6 @@ const gl_WidthShifts = new Float32Array([
|
||||
widthShift, widthShift // 7
|
||||
]);
|
||||
|
||||
|
||||
export {
|
||||
getRatio,
|
||||
gl_Colors,
|
||||
@ -88,5 +102,7 @@ export {
|
||||
gl_WidthShifts,
|
||||
gl_Shifts_map,
|
||||
screenWidthPixel,
|
||||
screenHeightPixel
|
||||
screenHeightPixel,
|
||||
gl_Shifts_for_bar,
|
||||
barShift
|
||||
};
|
@ -1,15 +1,13 @@
|
||||
'use strict';
|
||||
import tt from 'onml/tt.js';
|
||||
import genSVG from 'onml/gen-svg.js';
|
||||
import stringify from 'onml/stringify.js';
|
||||
|
||||
const tt = require('onml/tt.js');
|
||||
const genSVG = require('onml/gen-svg.js');
|
||||
const stringify = require('onml/stringify.js');
|
||||
// const getPco = require('./get-pco.js');
|
||||
const water = require('./water.js');
|
||||
const bracer = require('./bracer.js');
|
||||
const vline = require('./vline.js');
|
||||
const getX = require('./get-x.js');
|
||||
const vlineStylo = require('./vline-stylo.js');
|
||||
const getLabel = require('./get-label.js');
|
||||
import water from './water.js';
|
||||
import bracer from './bracer';
|
||||
import vline from './vline';
|
||||
import getX from './get-x';
|
||||
import vlineStylo from './vline-stylo';
|
||||
import getLabel from './get-label';
|
||||
|
||||
const defs = ['defs',
|
||||
['linearGradient', { id: 'valid' },
|
||||
@ -53,7 +51,7 @@ function* renderValues(desc, pstate) {
|
||||
const ml = genSVG(width, height - topBarHeight - botBarHeight);
|
||||
|
||||
let ifirst = 0;
|
||||
for (let i = 0; i < ilen; i += 1) {
|
||||
for (let i = 0; i < ilen; ++ i) {
|
||||
const lane = view[i];
|
||||
if (lane && (lane.name || lane.kind)) {
|
||||
if (i > iskip) {
|
||||
@ -78,7 +76,7 @@ function* renderValues(desc, pstate) {
|
||||
} else if (lane && lane.ref) {
|
||||
const chango = desc.chango[lane.ref];
|
||||
if (chango && chango.kind === 'vec') {
|
||||
const mLane = ['g', tt(0, Math.round((i - (iskip - ifirst) + .8) * yStep))];
|
||||
const mLane = ['g', tt(0, Math.round((i - (iskip - ifirst) + 0.1) * yStep))];
|
||||
const { wave } = chango;
|
||||
const jlen = wave.length;
|
||||
|
||||
@ -131,5 +129,5 @@ function* renderValues(desc, pstate) {
|
||||
return stringify(ml);
|
||||
}
|
||||
|
||||
module.exports = renderValues;
|
||||
export default renderValues;
|
||||
/* eslint complexity: [1, 55] */
|
||||
|
@ -1,10 +1,16 @@
|
||||
'use strict';
|
||||
import { ElLoading } from 'element-plus';
|
||||
|
||||
import { globalSetting, globalStyle } from '../global';
|
||||
import i18n from '../../i18n';
|
||||
const { t } = i18n.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 { gl_Colors, gl_Shifts, gl_Shifts_map, gl_WidthShifts } = require('./render-utils.js');
|
||||
const { vertexShader, fragmentShader } = require('./render-shader.js');
|
||||
|
||||
// const { ChangoItem } = require('./types.d.ts');
|
||||
|
||||
|
||||
class WebGL2WaveRender {
|
||||
/**
|
||||
*
|
||||
@ -43,6 +49,12 @@ class WebGL2WaveRender {
|
||||
* @param { Array } plugins
|
||||
*/
|
||||
constructor(elements, globalLookup, pstate, plugins) {
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: t('loading'),
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
});
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
elements.view.replaceChildren(canvas);
|
||||
|
||||
@ -62,9 +74,10 @@ class WebGL2WaveRender {
|
||||
const { lineVerticesMap, maskVerticesMap } = this.makeVertex();
|
||||
this.lineVerticesMap = lineVerticesMap;
|
||||
this.maskVerticesMap = maskVerticesMap;
|
||||
|
||||
this.initData();
|
||||
this.animationHandler = undefined;
|
||||
|
||||
loading.close();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,21 +125,44 @@ class WebGL2WaveRender {
|
||||
const time = globalLookup.time;
|
||||
const lineVerticesMap = new Map();
|
||||
const maskVerticesMap = new Map();
|
||||
for (const id of Reflect.ownKeys(globalLookup.chango)) {
|
||||
const signalItem = globalLookup.chango[id];
|
||||
const { kind, wave } = signalItem;
|
||||
if (kind === 'bit') {
|
||||
const { lineVertices, maskVertices } = this.makeBitVertex(wave, time);
|
||||
if (globalSetting.prerender) {
|
||||
for (const id of Reflect.ownKeys(globalLookup.chango)) {
|
||||
const { lineVertices, maskVertices } = this.makeVertexByID(id);
|
||||
lineVerticesMap.set(id, lineVertices);
|
||||
maskVerticesMap.set(id, maskVertices);
|
||||
} else if (kind === 'vec') {
|
||||
// const vertices = this.makeVecVertex(wave, time);
|
||||
// lineVerticesMap.set(id, vertices);
|
||||
}
|
||||
}
|
||||
|
||||
return { lineVerticesMap, maskVerticesMap };
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @returns {{
|
||||
* lineVertices: Uint32Array
|
||||
* maskVertices: Uint32Array
|
||||
* }}
|
||||
*/
|
||||
makeVertexByID(id) {
|
||||
const globalLookup = this.globalLookup;
|
||||
const time = globalLookup.time;
|
||||
const signalItem = globalLookup.chango[id];
|
||||
|
||||
const { kind, wave } = signalItem;
|
||||
if (kind === 'bit') {
|
||||
const { lineVertices, maskVertices } = this.makeBitVertex(wave, time);
|
||||
return { lineVertices, maskVertices };
|
||||
} else if (kind === 'vec') {
|
||||
const { lineVertices, maskVertices } = this.makeVecVertex(wave, time);
|
||||
return { lineVertices, maskVertices };
|
||||
}
|
||||
return {
|
||||
lineVertices: undefined,
|
||||
maskVertices: undefined
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @description 将wave 的值转化为渲染需要用到的值
|
||||
@ -198,12 +234,25 @@ class WebGL2WaveRender {
|
||||
const r2 = [x1, gl_Shifts_map.get(y1), color, wsIndex];
|
||||
const r3 = [x2, gl_Shifts_map.get(y1), color, wsIndex];
|
||||
const r4 = [x2, gl_Shifts_map.get(y2), color, wsIndex];
|
||||
return this.makeQuadVertices(r1, r2, r3, r4);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number[]} p1
|
||||
* @param {number[]} p2
|
||||
* @param {number[]} p3
|
||||
* @param {number[]} p4
|
||||
* @returns {number[]}
|
||||
*/
|
||||
makeQuadVertices(p1, p2, p3, p4) {
|
||||
return [
|
||||
...r1, ...r2, ...r3,
|
||||
...r1, ...r3, ...r4,
|
||||
...p1, ...p2, ...p3,
|
||||
...p1, ...p3, ...p4
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Array<string | number>} wave
|
||||
@ -329,112 +378,187 @@ class WebGL2WaveRender {
|
||||
}
|
||||
|
||||
|
||||
if (debug) {
|
||||
console.log(perspectivePoints);
|
||||
console.log(pointNum);
|
||||
console.log(lineVertices);
|
||||
}
|
||||
|
||||
const Uint32lineVertices = new Uint32Array(lineVertices);
|
||||
const Uint32maskVertices = new Uint32Array(maskVertices);
|
||||
// if (debug) {
|
||||
// console.log(perspectivePoints);
|
||||
// console.log(pointNum);
|
||||
// console.log(lineVertices);
|
||||
// }
|
||||
|
||||
return {
|
||||
lineVertices : Uint32lineVertices,
|
||||
maskVertices : Uint32maskVertices
|
||||
lineVertices : new Uint32Array(lineVertices),
|
||||
maskVertices : new Uint32Array(maskVertices)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Array<string | number>} wave
|
||||
* @param { number } time
|
||||
* @returns {Uint32Array}
|
||||
* @returns {{
|
||||
* lineVertices: Uint32Array
|
||||
* maskVertices: Uint32Array
|
||||
* }}
|
||||
*/
|
||||
makeVecVertex(wave, time) {
|
||||
const vertices = [];
|
||||
makeVecVertex(wave, time, debug = false) {
|
||||
const lineVertices = [];
|
||||
const maskVertices = [];
|
||||
const length = wave.length;
|
||||
for (let i = 0; i < length; ++ i) {
|
||||
const [t1, val, msk] = wave[i];
|
||||
const t2 = (i === (length - 1)) ? time : wave[i + 1][0];
|
||||
// t1(val) --- t2(val)
|
||||
|
||||
if (msk) {
|
||||
vertices.push(
|
||||
t1, 0, 0,
|
||||
t2, 0, 0,
|
||||
t2, 0, 4,
|
||||
t2, 4, 4,
|
||||
t1, 6, 4,
|
||||
t1, 0, 4,
|
||||
t1, 3, 4,
|
||||
t2, 1, 4,
|
||||
t2, 0, 4
|
||||
);
|
||||
} else {
|
||||
vertices.push(
|
||||
t1, 0, 0,
|
||||
t2, 0, 0,
|
||||
t2, 0, 5,
|
||||
t2, 4, 5,
|
||||
t1, 6, 5,
|
||||
t1, 0, 5,
|
||||
t1, 3, 5,
|
||||
t2, 1, 5,
|
||||
t2, 0, 5
|
||||
for (let i = 0; i < length; ++ i) {
|
||||
const [t1, val, mask] = wave[i];
|
||||
const t2 = (i === (length - 1)) ? time : wave[i + 1][0];
|
||||
|
||||
// t1(val) --- t2(val)
|
||||
// 详见 设计图 ./design/webgl.drawio makeVecVertex原理 sheet
|
||||
// 此处的 y 不是 y 的索引,详见 gl_Shifts_for_bar 的设计
|
||||
const p0 = {x: t1, y: 0};
|
||||
const p1 = {x: t2, y: 0};
|
||||
const a0 = {x: t1, y: 4};
|
||||
const a1 = {x: t2, y: 5};
|
||||
const a2 = {x: t1, y: 1};
|
||||
const a3 = {x: t2, y: 2};
|
||||
|
||||
const color = mask ? 4 : 5;
|
||||
|
||||
const points = [ a1, p1, a3, a2, p0, a0 ];
|
||||
const wsIndice = [ 1, 2, 3, 5, 6, 7 ];
|
||||
for (let i = 0; i < 6; ++ i) {
|
||||
const prePoint = points[i];
|
||||
const nextPoint = points[(i + 1) % 6];
|
||||
const preWsIndex = wsIndice[i];
|
||||
const nextWsIndex = wsIndice[(i + 1) % 6];
|
||||
const quadVertices = this.makeQuadVertices(
|
||||
[prePoint.x, prePoint.y, color, preWsIndex],
|
||||
[prePoint.x, prePoint.y, color, (preWsIndex + 4) % 8],
|
||||
[nextPoint.x, nextPoint.y, color, (nextWsIndex + 4) % 8],
|
||||
[nextPoint.x, nextPoint.y, color, nextWsIndex],
|
||||
);
|
||||
lineVertices.push(...quadVertices);
|
||||
}
|
||||
|
||||
const maskTriangles = [
|
||||
[3, 4, 5],
|
||||
[5, 0, 3],
|
||||
[0, 3, 2],
|
||||
[0, 1, 2]
|
||||
];
|
||||
|
||||
for (const triangleIndice of maskTriangles) {
|
||||
const [i1, i2, i3] = triangleIndice;
|
||||
const point1 = points[i1];
|
||||
const point2 = points[i2];
|
||||
const point3 = points[i3];
|
||||
maskVertices.push(
|
||||
point1.x, point1.y, color + 10, wsIndice[i1],
|
||||
point2.x, point2.y, color + 10, wsIndice[i2],
|
||||
point3.x, point3.y, color + 10, wsIndice[i3]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return new Uint32Array(vertices);
|
||||
if (debug) {
|
||||
console.log(lineVertices);
|
||||
}
|
||||
|
||||
return {
|
||||
lineVertices: new Uint32Array(lineVertices),
|
||||
maskVertices: new Uint32Array(maskVertices)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} id
|
||||
* @returns
|
||||
*/
|
||||
initVertice(id) {
|
||||
const webglLocation = this.webglLocation;
|
||||
const gl = webglLocation.gl;
|
||||
const signalItem = this.globalLookup.chango[id];
|
||||
|
||||
if (this.lineVerticesMap.get(id) === undefined) {
|
||||
const { lineVertices, maskVertices } = this.makeVertexByID(id);
|
||||
this.lineVerticesMap.set(id, lineVertices);
|
||||
this.maskVerticesMap.set(id, maskVertices);
|
||||
}
|
||||
const lineVertices = this.lineVerticesMap.get(id);
|
||||
const maskVertices = this.maskVerticesMap.get(id);
|
||||
|
||||
// 创建并设置 绘制wave轮廓 主体轮廓的 缓冲区、vao、顶点设置
|
||||
const lineVertexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, lineVertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, lineVertices, gl.STATIC_DRAW);
|
||||
signalItem.lineVao = gl.createVertexArray();
|
||||
gl.bindVertexArray(signalItem.lineVao);
|
||||
gl.vertexAttribIPointer(webglLocation.pos, 4, gl.UNSIGNED_INT, 0, 0);
|
||||
gl.enableVertexAttribArray(webglLocation.pos);
|
||||
|
||||
// 创建并设置 绘制wave半透明遮罩层 主体轮廓的 缓冲区、vao、顶点设置
|
||||
const maskVertexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, maskVertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, maskVertices, gl.STATIC_DRAW);
|
||||
signalItem.maskVao = gl.createVertexArray();
|
||||
gl.bindVertexArray(signalItem.maskVao);
|
||||
gl.vertexAttribIPointer(webglLocation.pos, 4, gl.UNSIGNED_INT, 0, 0);
|
||||
gl.enableVertexAttribArray(webglLocation.pos);
|
||||
}
|
||||
|
||||
initData() {
|
||||
const webglLocation = this.webglLocation;
|
||||
const gl = webglLocation.gl;
|
||||
const globalLookup = this.globalLookup;
|
||||
const lineVerticesMap = this.lineVerticesMap;
|
||||
const maskVerticesMap = this.maskVerticesMap;
|
||||
|
||||
for (const id of Reflect.ownKeys(globalLookup.chango)) {
|
||||
const signalItem = globalLookup.chango[id];
|
||||
|
||||
const lineVertices = lineVerticesMap.get(id);
|
||||
if (lineVertices === undefined) {
|
||||
// console.warn(`无法找到 link 为 ${id} 的顶点数据`);
|
||||
continue;
|
||||
if (globalSetting.prerender) {
|
||||
for (const id of Reflect.ownKeys(this.globalLookup.chango)) {
|
||||
this.initVertice(id);
|
||||
}
|
||||
|
||||
// 创建并设置 绘制wave轮廓 主体轮廓的 缓冲区、vao、顶点设置
|
||||
const lineVertexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, lineVertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, lineVertices, gl.STATIC_DRAW);
|
||||
signalItem.lineVao = gl.createVertexArray();
|
||||
gl.bindVertexArray(signalItem.lineVao);
|
||||
gl.vertexAttribIPointer(webglLocation.pos, 4, gl.UNSIGNED_INT, 0, 0);
|
||||
gl.enableVertexAttribArray(webglLocation.pos);
|
||||
|
||||
|
||||
const maskVertices = maskVerticesMap.get(id);
|
||||
if (maskVertices === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 创建并设置 绘制wave半透明遮罩层 主体轮廓的 缓冲区、vao、顶点设置
|
||||
const maskVertexBuffer = gl.createBuffer();
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, maskVertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, maskVertices, gl.STATIC_DRAW);
|
||||
signalItem.maskVao = gl.createVertexArray();
|
||||
gl.bindVertexArray(signalItem.maskVao);
|
||||
gl.vertexAttribIPointer(webglLocation.pos, 4, gl.UNSIGNED_INT, 0, 0);
|
||||
gl.enableVertexAttribArray(webglLocation.pos);
|
||||
}
|
||||
|
||||
const webglLocation = this.webglLocation;
|
||||
const gl = webglLocation.gl;
|
||||
gl.uniform4fv(webglLocation.colors, gl_Colors);
|
||||
gl.uniform2fv(webglLocation.widthShifts, gl_WidthShifts);
|
||||
gl.uniform2fv(webglLocation.shifts, gl_Shifts);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Array<{
|
||||
* index: number
|
||||
* rgba: {
|
||||
* red: number,
|
||||
* green: number,
|
||||
* blue: number,
|
||||
* alpha: number
|
||||
* }
|
||||
* }>} updaters
|
||||
* @param {{
|
||||
* updateMask: boolean
|
||||
* }} config
|
||||
*/
|
||||
updateGLColor(updaters, config) {
|
||||
const webglLocation = this.webglLocation;
|
||||
const gl = webglLocation.gl;
|
||||
|
||||
for (const updater of updaters) {
|
||||
const startIndex = updater.index * 4;
|
||||
const rgba = updater.rgba;
|
||||
gl_Colors[startIndex] = rgba.red;
|
||||
gl_Colors[startIndex + 1] = rgba.green;
|
||||
gl_Colors[startIndex + 2] = rgba.blue;
|
||||
gl_Colors[startIndex + 3] = rgba.alpha;
|
||||
|
||||
if (config.updateMask) {
|
||||
const maskIndex = (updater.index + 10) * 4;
|
||||
gl_Colors[maskIndex] = rgba.red;
|
||||
gl_Colors[maskIndex + 1] = rgba.green;
|
||||
gl_Colors[maskIndex + 2] = rgba.blue;
|
||||
}
|
||||
}
|
||||
|
||||
gl.uniform4fv(webglLocation.colors, gl_Colors);
|
||||
this.render();
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.animationHandler !== undefined) {
|
||||
cancelAnimationFrame(this.animationHandler);
|
||||
@ -448,76 +572,131 @@ class WebGL2WaveRender {
|
||||
const maskVerticesMap = this.maskVerticesMap;
|
||||
const elements = this.elements;
|
||||
|
||||
const timeScaleHeight = parseInt(document.body.style.getPropertyValue('--time-scale-height').match(/\d+/)[0]);
|
||||
const sidebarPadding = parseInt(document.body.style.getPropertyValue('--sidebar-padding').match(/\d+/)[0]);
|
||||
const vcdRenderPadding = parseInt(document.body.style.getPropertyValue('--vcd-render-padding').match(/\d+/)[0]);
|
||||
const canvasPaddingTop = timeScaleHeight + sidebarPadding - vcdRenderPadding;
|
||||
// 更新 yDuty & yStep
|
||||
// yStep: scale 之后的单个 wave 的容器高度需要和 displaySignalHeight + sideBarItemMargin 一样
|
||||
// yDuty: scale 之后的单个 wave 的 padding 必须等于 sideBarItemMargin,也就是 (1 - yDuty) * yStep = 2 * margin
|
||||
const sidebarItemMargin = globalStyle.sideBarItemMargin;
|
||||
|
||||
this.animationHandler = window.requestAnimationFrame(() => {
|
||||
const { width, height, xScale, xOffset, yOffset, yStep, yDuty } = this.pstate;
|
||||
const canvasHeight = height - canvasPaddingTop;
|
||||
const canvasWidth = width;
|
||||
const pstate = this.pstate;
|
||||
const plugins = this.plugins;
|
||||
|
||||
// 默认 1594
|
||||
canvas.width = canvasWidth;
|
||||
pstate.yStep = globalSetting.displaySignalHeight + globalStyle.sideBarItemMargin;
|
||||
pstate.yDuty = (1 - 2 * globalStyle.sideBarItemMargin / this.pstate.yStep) * 0.9;
|
||||
|
||||
// 默认 1260
|
||||
canvas.height = canvasHeight;
|
||||
document.body.style.setProperty('--vcd-render-padding', pstate.topBarHeight + 'px');
|
||||
const canvasHeight = pstate.height - pstate.topBarHeight - pstate.botBarHeight;
|
||||
const canvasWidth = pstate.width;
|
||||
|
||||
// 默认 1594
|
||||
canvas.width = canvasWidth;
|
||||
// 默认 1260
|
||||
canvas.height = canvasHeight;
|
||||
|
||||
let startTime = undefined;
|
||||
// 默认执行一个 300 ms 的动画
|
||||
const animationDuration = 300;
|
||||
let animationHandler = this.animationHandler = requestAnimationFrame(drawWaves);
|
||||
|
||||
function linearAnimation(delta, oldVal, newVal) {
|
||||
return (1 - delta) * oldVal + delta * newVal;
|
||||
}
|
||||
|
||||
function cubicBezierAnimation(delta, oldVal, newVal) {
|
||||
delta = 3 * (1 - delta) * (1 - delta) * delta + 3 * (1 - delta) * delta * delta + delta * delta * delta;
|
||||
return (1 - delta) * oldVal + delta * newVal;
|
||||
}
|
||||
|
||||
function renderOneFrame(animationDelta) {
|
||||
// 考虑设置线性动画的变量 xScale, xOffset, yOffset, yStep, yDuty
|
||||
const xScale = cubicBezierAnimation(animationDelta, pstate.oldXScale, pstate.xScale);
|
||||
const xOffset = cubicBezierAnimation(animationDelta, pstate.oldXOffset, pstate.xOffset);
|
||||
const yOffset = cubicBezierAnimation(animationDelta, pstate.oldYOffset, pstate.yOffset);
|
||||
const yStep = cubicBezierAnimation(animationDelta, pstate.oldYStep, pstate.yStep);
|
||||
const yDuty = cubicBezierAnimation(animationDelta, pstate.oldYDuty, pstate.yDuty);
|
||||
|
||||
// 设置 glsl 变量
|
||||
gl.uniform2f(webglLocation.scale,
|
||||
2 * xScale / canvasWidth,
|
||||
yStep * yDuty / canvasHeight
|
||||
);
|
||||
console.log(yStep, yDuty, canvasHeight);
|
||||
const scaleX = 2 * xScale / canvasWidth;
|
||||
const scaleY = yStep * yDuty / canvasHeight;
|
||||
gl.uniform2f(webglLocation.scale, scaleX, scaleY);
|
||||
|
||||
// 设置 webgl 和 canvas 大小位置一致
|
||||
gl.viewport(0, 0, canvasWidth, canvasHeight);
|
||||
// 清楚颜色缓冲区,也就是删除上一次的渲染结果
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
|
||||
// 根据 globalLookup 当前激活的需要渲染的信号进行渲染
|
||||
let index = 0;
|
||||
for (const signal of globalLookup.currentWires) {
|
||||
const wave = globalLookup.chango[signal.link].wave;
|
||||
const id = signal.link;
|
||||
const wave = globalLookup.chango[id].wave;
|
||||
|
||||
// this.makeBitVertex(wave, globalLookup.time, true);
|
||||
const signalItem = globalLookup.chango[signal.link];
|
||||
// this.makeVecVertex(wave, globalLookup.time, true);
|
||||
|
||||
const signalItem = globalLookup.chango[id];
|
||||
if (!signalItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: 将此处的 offset 计算中的参数和 globalSetting 的数字形成关联
|
||||
gl.uniform2f(webglLocation.offset,
|
||||
(2 * xOffset / width) - 1,
|
||||
(2 * yOffset - 2 * yStep * (index + .7)) / canvasHeight + 1
|
||||
);
|
||||
|
||||
|
||||
console.log('offset y', (2 * yOffset - 2 * yStep * (index + .7)) / canvasHeight + 1);
|
||||
const offsetX = 2 * xOffset / canvasWidth - 1;
|
||||
const offsetY = 2 * (yOffset - yStep * index) / canvasHeight + 1;
|
||||
gl.uniform2f(webglLocation.offset, offsetX, offsetY);
|
||||
|
||||
// 根据 lineVao 进行绘制
|
||||
const lineVertices = lineVerticesMap.get(signal.link);
|
||||
const maskVertices = maskVerticesMap.get(signal.link);
|
||||
if (lineVerticesMap.get(id) === undefined) {
|
||||
this.initVertice(id);
|
||||
}
|
||||
const lineVertices = lineVerticesMap.get(id);
|
||||
const maskVertices = maskVerticesMap.get(id);
|
||||
|
||||
if (signal.size === 1) {
|
||||
// 如果是 width 为 1 的
|
||||
gl.uniform2fv(webglLocation.shifts, gl_Shifts);
|
||||
gl.bindVertexArray(signalItem.lineVao);
|
||||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, lineVertices.length / 4);
|
||||
``
|
||||
|
||||
gl.bindVertexArray(signalItem.maskVao);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, maskVertices.length / 4);
|
||||
} else {
|
||||
// 如果是 width 大于 1 的
|
||||
gl.drawArrays(gl.LINE_STRIP, 0, lineVertices.length / 4);
|
||||
gl.uniform2fv(webglLocation.shifts, gl_Shifts_for_bar);
|
||||
gl.bindVertexArray(signalItem.lineVao);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, lineVertices.length / 4);
|
||||
|
||||
gl.bindVertexArray(signalItem.maskVao);
|
||||
gl.drawArrays(gl.TRIANGLES, 0, maskVertices.length / 4);
|
||||
}
|
||||
|
||||
index ++;
|
||||
}
|
||||
|
||||
this.plugins.map(fn => fn(globalLookup, this.pstate, elements));
|
||||
this.animationHandler = undefined;
|
||||
});
|
||||
plugins.map(fn => fn(globalLookup, pstate, elements));
|
||||
}
|
||||
|
||||
function drawWaves(now) {
|
||||
if (startTime === undefined) {
|
||||
startTime = now;
|
||||
} else {
|
||||
const pastTime = now - startTime;
|
||||
const animationDelta = globalSetting.renderAnimation ? Math.min(pastTime / animationDuration, 1) : 1;
|
||||
renderOneFrame(animationDelta);
|
||||
// 达到 1 时说明线性动画时间到了,退出即可
|
||||
if (animationDelta >= 1) {
|
||||
cancelAnimationFrame(animationHandler);
|
||||
// 更新状态变量
|
||||
pstate.oldXOffset = pstate.xOffset;
|
||||
pstate.oldYOffset = pstate.yOffset;
|
||||
pstate.oldXScale = pstate.xScale;
|
||||
pstate.oldYStep = pstate.yStep;
|
||||
pstate.oldYDuty = pstate.yDuty;
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 进入下一帧
|
||||
requestAnimationFrame(drawWaves);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = WebGL2WaveRender;
|
||||
export default WebGL2WaveRender;
|
@ -1,22 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
function* sampler (wave) {
|
||||
let t1, v0, v1;
|
||||
[t1, v1] = wave[0]; // initial state
|
||||
let t = 0;
|
||||
for (let i = 1; i < wave.length; i++) {
|
||||
v0 = v1;
|
||||
[t1, v1] = wave[i]; // next change
|
||||
while (true) {
|
||||
if (t >= t1) {
|
||||
break;
|
||||
}
|
||||
t = yield v0;
|
||||
export default function* sampler(wave) {
|
||||
let t1, v0, v1;
|
||||
[t1, v1] = wave[0]; // initial state
|
||||
let t = 0;
|
||||
for (let i = 1; i < wave.length; i++) {
|
||||
v0 = v1;
|
||||
[t1, v1] = wave[i]; // next change
|
||||
while (true) {
|
||||
if (t >= t1) {
|
||||
break;
|
||||
}
|
||||
t = yield v0;
|
||||
}
|
||||
}
|
||||
while (true) { // to the end of time
|
||||
yield v1;
|
||||
}
|
||||
}
|
||||
while(true) { // to the end of time
|
||||
yield v1;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = sampler;
|
||||
|
@ -1,24 +1,22 @@
|
||||
'use strict';
|
||||
import getT from './get-t';
|
||||
|
||||
const getT = require('./get-t.js');
|
||||
function* surferer(wave, pstate) {
|
||||
const { sidebarWidth, width } = pstate;
|
||||
const xStartExact = getT(sidebarWidth, pstate);
|
||||
const xFinishExact = getT(width, pstate);
|
||||
|
||||
function* surferer (wave, pstate) {
|
||||
const { sidebarWidth, width } = pstate;
|
||||
const xStartExact = getT(sidebarWidth, pstate);
|
||||
const xFinishExact = getT(width, pstate);
|
||||
|
||||
let i = 0;
|
||||
for (i = 0; i < wave.length; i++) { // seek to the start of viewport
|
||||
if ((wave[i] === undefined) || (wave[i][0] >= xStartExact)) {
|
||||
break;
|
||||
let i = 0;
|
||||
for (i = 0; i < wave.length; i++) { // seek to the start of viewport
|
||||
if ((wave[i] === undefined) || (wave[i][0] >= xStartExact)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (; i < wave.length; i++) { // render viewport
|
||||
if ((wave[i] === undefined) || (wave[i][0] > xFinishExact)) {
|
||||
break;
|
||||
for (; i < wave.length; i++) { // render viewport
|
||||
if ((wave[i] === undefined) || (wave[i][0] > xFinishExact)) {
|
||||
break;
|
||||
}
|
||||
yield i;
|
||||
}
|
||||
yield i;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = surferer;
|
||||
export default surferer;
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const vlineStylo = {
|
||||
w: {h:0, l:100}, // w
|
||||
r: {h:10, l:45}, // r
|
||||
@ -11,4 +9,4 @@ const vlineStylo = {
|
||||
v: {h:280, l:55} // v
|
||||
};
|
||||
|
||||
module.exports = vlineStylo;
|
||||
export default vlineStylo;
|
||||
|
@ -1,8 +1,7 @@
|
||||
'use strict';
|
||||
import onml from 'onml';
|
||||
|
||||
const getX = require('./get-x.js');
|
||||
const onml = require('onml');
|
||||
const vlineStylo = require('./vline-stylo.js');
|
||||
import getX from './get-x.js';
|
||||
import vlineStylo from './vline-stylo.js';
|
||||
|
||||
/* Zones
|
||||
1 2 3
|
||||
@ -11,47 +10,47 @@ const vlineStylo = require('./vline-stylo.js');
|
||||
*/
|
||||
|
||||
const vline = (lane, pstate, i) => {
|
||||
const {width, height, timescale, yStep, yOffset, topBarHeight, botBarHeight} = pstate;
|
||||
const y = (i + .7) * yStep - yOffset;
|
||||
const yMax = height - topBarHeight - botBarHeight;
|
||||
const { width, height, timescale, yStep, yOffset, topBarHeight, botBarHeight } = pstate;
|
||||
const y = i * yStep - yOffset;
|
||||
const yMax = height - topBarHeight - botBarHeight;
|
||||
|
||||
return lane.vlines.map(vline => {
|
||||
const t = vline.value * Math.pow(10, vline.mult - timescale);
|
||||
const x = Math.round(getX(pstate, t));
|
||||
const style = (vlineStylo[vline.style] || vlineStylo.w);
|
||||
const color = `hsl(${style.h},100%,${style.l}%)`;
|
||||
const symbol = ['path', {style: 'stroke-width: 1px; stroke: ' + color}];
|
||||
return lane.vlines.map(vline => {
|
||||
const t = vline.value * Math.pow(10, vline.mult - timescale);
|
||||
const x = Math.round(getX(pstate, t));
|
||||
const style = (vlineStylo[vline.style] || vlineStylo.w);
|
||||
const color = `hsl(${style.h},100%,${style.l}%)`;
|
||||
const symbol = ['path', { style: 'stroke-width: 1px; stroke: ' + color }];
|
||||
|
||||
if ((x < 0) || (x > width)) {
|
||||
if ((y < 0) || (y > yMax)) { // Zones: 1, 7, 3, 9
|
||||
return ['g'];
|
||||
}
|
||||
if (x < 0) { // Zone: 4
|
||||
symbol[1].d = `M ${0} ${y} l 8 -4 v 8 z`;
|
||||
return symbol;
|
||||
}
|
||||
// Zone: 6
|
||||
symbol[1].d = `M ${width - 16} ${y} l -8 -4 v 8 z`;
|
||||
return symbol;
|
||||
}
|
||||
if ((x < 0) || (x > width)) {
|
||||
if ((y < 0) || (y > yMax)) { // Zones: 1, 7, 3, 9
|
||||
return ['g'];
|
||||
}
|
||||
if (x < 0) { // Zone: 4
|
||||
symbol[1].d = `M ${0} ${y} l 8 -4 v 8 z`;
|
||||
return symbol;
|
||||
}
|
||||
// Zone: 6
|
||||
symbol[1].d = `M ${width - 16} ${y} l -8 -4 v 8 z`;
|
||||
return symbol;
|
||||
}
|
||||
|
||||
const line = ['g', onml.tt(x, 0),
|
||||
['rect', {x: -1, width: 3, height, fill: '#fff', filter: 'url(#neonGlow-' + vline.style + ')'}],
|
||||
['rect', {width: 1, height, fill: color}]
|
||||
];
|
||||
const line = ['g', onml.tt(x, 0),
|
||||
['rect', { x: -1, width: 3, height, fill: '#fff', filter: 'url(#neonGlow-' + vline.style + ')' }],
|
||||
['rect', { width: 1, height, fill: color }]
|
||||
];
|
||||
|
||||
if (y < 0) { // Zone: 2
|
||||
symbol[1].d = `M ${x} ${topBarHeight} l 4 8 h -8 z`;
|
||||
return ['g', line, symbol];
|
||||
}
|
||||
if (y > yMax) { // Zone: 8
|
||||
symbol[1].d = `M ${x} ${yMax} l -4 -8 h 8 z`;
|
||||
return ['g', line, symbol];
|
||||
}
|
||||
// Zone: 5
|
||||
symbol[1].d = `M ${x} ${y} m-4 0 l 4 -4 l 4 4 l -4 4 z`;
|
||||
return ['g', line, symbol];
|
||||
});
|
||||
if (y < 0) { // Zone: 2
|
||||
symbol[1].d = `M ${x} ${topBarHeight} l 4 8 h -8 z`;
|
||||
return ['g', line, symbol];
|
||||
}
|
||||
if (y > yMax) { // Zone: 8
|
||||
symbol[1].d = `M ${x} ${yMax} l -4 -8 h 8 z`;
|
||||
return ['g', line, symbol];
|
||||
}
|
||||
// Zone: 5
|
||||
symbol[1].d = `M ${x} ${y} m-4 0 l 4 -4 l 4 4 l -4 4 z`;
|
||||
return ['g', line, symbol];
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = vline;
|
||||
export default vline;
|
@ -1,140 +1,140 @@
|
||||
'use strict';
|
||||
|
||||
// PC based pipeline view
|
||||
|
||||
const tt = require('onml/tt.js');
|
||||
const getX = require('./get-x.js');
|
||||
const surferer = require('./surferer.js');
|
||||
const sampler = require('./sampler.js');
|
||||
const hash = require('./hash.js');
|
||||
import tt from 'onml/tt.js';
|
||||
|
||||
import getX from './get-x';
|
||||
import surferer from './surferer';
|
||||
import sampler from './sampler';
|
||||
import hash from './hash';
|
||||
|
||||
const pushBrick = (listing, pco, v, name, label, t) => {
|
||||
let pc = v;
|
||||
let tail = false;
|
||||
let le = listing[pc];
|
||||
if (le === undefined) {
|
||||
pc = v - 2;
|
||||
le = listing[pc];
|
||||
tail = true;
|
||||
}
|
||||
if (le) {
|
||||
if (pco[pc] === undefined) {
|
||||
pco[pc] = {op: le.op, asm: le.asm, bricks: []};
|
||||
let pc = v;
|
||||
let tail = false;
|
||||
let le = listing[pc];
|
||||
if (le === undefined) {
|
||||
pc = v - 2;
|
||||
le = listing[pc];
|
||||
tail = true;
|
||||
}
|
||||
if (le) {
|
||||
if (pco[pc] === undefined) {
|
||||
pco[pc] = { op: le.op, asm: le.asm, bricks: [] };
|
||||
}
|
||||
pco[pc].bricks.push({ name, label, t, tail });
|
||||
}
|
||||
pco[pc].bricks.push({name, label, t, tail});
|
||||
}
|
||||
};
|
||||
|
||||
const progress = (lane, desc, pstate) => {
|
||||
const pco = {};
|
||||
const pco = {};
|
||||
|
||||
const { listing } = desc;
|
||||
const { clock, othero } = lane;
|
||||
const { listing } = desc;
|
||||
const { clock, othero } = lane;
|
||||
|
||||
|
||||
if (desc.chango[clock.ref] === undefined) {
|
||||
// console.log(desc.chango, clock, clock.ref);
|
||||
return pco;
|
||||
}
|
||||
const clockWave = desc.chango[clock.ref].wave;
|
||||
const clockEr = surferer(clockWave, pstate);
|
||||
if (desc.chango[clock.ref] === undefined) {
|
||||
// console.log(desc.chango, clock, clock.ref);
|
||||
return pco;
|
||||
}
|
||||
const clockWave = desc.chango[clock.ref].wave;
|
||||
const clockEr = surferer(clockWave, pstate);
|
||||
|
||||
// create samplers
|
||||
for (const id of Object.keys(othero)) {
|
||||
['pc', 'go'].map(role => {
|
||||
const obj = othero[id][role];
|
||||
obj.sampler = sampler(desc.chango[obj.ref].wave);
|
||||
obj.sampler.next(0); // dry run
|
||||
});
|
||||
}
|
||||
// create samplers
|
||||
for (const id of Object.keys(othero)) {
|
||||
['pc', 'go'].map(role => {
|
||||
const obj = othero[id][role];
|
||||
obj.sampler = sampler(desc.chango[obj.ref].wave);
|
||||
obj.sampler.next(0); // dry run
|
||||
});
|
||||
}
|
||||
|
||||
let count = 8000; // max number of pipeline bricks
|
||||
let count = 8000; // max number of pipeline bricks
|
||||
|
||||
outerLoop: for (const iClock of clockEr) {
|
||||
const [tClock, vClock] = clockWave[iClock];
|
||||
if (vClock) {
|
||||
for (const key of Object.keys(othero)) {
|
||||
const id = othero[key];
|
||||
const go = id.go.sampler.next(tClock).value;
|
||||
const pc = id.pc.sampler.next(tClock).value;
|
||||
const KEY = key.toUpperCase();
|
||||
if (go) {
|
||||
pushBrick(listing, pco, pc, KEY, KEY, tClock);
|
||||
if (count-- === 0) {
|
||||
break outerLoop;
|
||||
}
|
||||
outerLoop: for (const iClock of clockEr) {
|
||||
const [tClock, vClock] = clockWave[iClock];
|
||||
if (vClock) {
|
||||
for (const key of Object.keys(othero)) {
|
||||
const id = othero[key];
|
||||
const go = id.go.sampler.next(tClock).value;
|
||||
const pc = id.pc.sampler.next(tClock).value;
|
||||
const KEY = key.toUpperCase();
|
||||
if (go) {
|
||||
pushBrick(listing, pco, pc, KEY, KEY, tClock);
|
||||
if (count-- === 0) {
|
||||
break outerLoop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const [idx, key] of Object.keys(pco).entries()) {
|
||||
if (pco[key] !== undefined) {
|
||||
pco[key].idx = idx;
|
||||
for (const [idx, key] of Object.keys(pco).entries()) {
|
||||
if (pco[key] !== undefined) {
|
||||
pco[key].idx = idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return pco;
|
||||
return pco;
|
||||
};
|
||||
|
||||
const water = (lane, desc, pstate) => {
|
||||
const { width, yStep } = pstate;
|
||||
const brickWidth = getX(pstate, 2) - getX(pstate, 0);
|
||||
const { width, yStep } = pstate;
|
||||
const brickWidth = getX(pstate, 2) - getX(pstate, 0);
|
||||
|
||||
const pco = progress(lane, desc, pstate);
|
||||
const pco = progress(lane, desc, pstate);
|
||||
|
||||
const pcs = Object.keys(pco).map(e => Number(e)).sort();
|
||||
const pcs = Object.keys(pco).map(e => Number(e)).sort();
|
||||
|
||||
const mLanes = [];
|
||||
const mLanes = [];
|
||||
|
||||
// const pco = getPco(desc, pstate, lane); // signals, dats, cycles, listing, state.cursor);
|
||||
for (let j = 0; j < lane.len - 2; j++) {
|
||||
const pc = pcs[j];
|
||||
const pcd = pco[pc];
|
||||
if (pc === undefined || pcd === undefined) {
|
||||
break;
|
||||
// const pco = getPco(desc, pstate, lane); // signals, dats, cycles, listing, state.cursor);
|
||||
for (let j = 0; j < lane.len - 2; j++) {
|
||||
const pc = pcs[j];
|
||||
const pcd = pco[pc];
|
||||
if (pc === undefined || pcd === undefined) {
|
||||
break;
|
||||
}
|
||||
|
||||
const asm = pcd.asm.replace(/<.+>/, '\u25C6');
|
||||
const mLane = ['g', tt(0, Math.round(j * yStep))];
|
||||
|
||||
// striped background
|
||||
if (j & 1) {
|
||||
mLane.push(['rect', { width: width, height: yStep - 1, class: 'pc-odd' }]);
|
||||
// ['rect', {width: width, height: yStep - 2, class: (j & 1) ? 'pc-odd' : 'pc-even'}],
|
||||
}
|
||||
|
||||
// dotted separator
|
||||
if ((j > 0) && (pc - pcs[j - 1] > 4)) {
|
||||
mLane.push(['line', { class: 'gap', x1: 0, y1: 0, x2: width, y2: 0 }]);
|
||||
}
|
||||
|
||||
// row header
|
||||
mLane.push(['text', { class: 'pc', 'xml:space': 'preserve', y: Math.round(yStep) },
|
||||
['tspan', { class: 'pc-addr' }, parseInt(pc, 10).toString(16).padStart(12, ' ')],
|
||||
['tspan', { class: 'pc-opcode' }, pcd.op.padStart(9, ' ')],
|
||||
' ',
|
||||
['tspan', { class: 'pc-asm' }, asm]
|
||||
]);
|
||||
|
||||
// bricks in row
|
||||
pcd.bricks.map(e => {
|
||||
mLane.push(['g', tt(Math.round(getX(pstate, e.t))),
|
||||
['rect', {
|
||||
class: (e.label === '') ? e.name : 'ct' + hash(e.name).toString(36),
|
||||
width: brickWidth,
|
||||
height: (e.tail ? (yStep >> 1) : yStep) - 3,
|
||||
y: e.tail ? ((yStep >> 1) + 1) : 1,
|
||||
'data-stage': e.label
|
||||
}],
|
||||
...((brickWidth > 20) ? [['text', { class: e.name, width: brickWidth, x: brickWidth / 2, y: 16 }, e.label]] : [])
|
||||
]);
|
||||
});
|
||||
|
||||
mLanes.push(mLane);
|
||||
}
|
||||
|
||||
const asm = pcd.asm.replace(/<.+>/, '\u25C6');
|
||||
const mLane = ['g', tt(0, Math.round(j * yStep))];
|
||||
|
||||
// striped background
|
||||
if (j & 1) {
|
||||
mLane.push(['rect', {width: width, height: yStep - 1, class: 'pc-odd'}]);
|
||||
// ['rect', {width: width, height: yStep - 2, class: (j & 1) ? 'pc-odd' : 'pc-even'}],
|
||||
}
|
||||
|
||||
// dotted separator
|
||||
if ((j > 0) && (pc - pcs[j - 1] > 4)) {
|
||||
mLane.push(['line', {class: 'gap', x1: 0, y1: 0, x2: width, y2: 0}]);
|
||||
}
|
||||
|
||||
// row header
|
||||
mLane.push(['text', {class: 'pc', 'xml:space': 'preserve', y: Math.round(yStep * .7)},
|
||||
['tspan', {class: 'pc-addr'}, parseInt(pc, 10).toString(16).padStart(12, ' ')],
|
||||
['tspan', {class: 'pc-opcode'}, pcd.op.padStart(9, ' ')],
|
||||
' ',
|
||||
['tspan', {class: 'pc-asm'}, asm]
|
||||
]);
|
||||
|
||||
// bricks in row
|
||||
pcd.bricks.map(e => {
|
||||
mLane.push(['g', tt(Math.round(getX(pstate, e.t))),
|
||||
['rect', {
|
||||
class: (e.label === '') ? e.name : 'ct' + hash(e.name).toString(36),
|
||||
width: brickWidth,
|
||||
height: (e.tail ? (yStep >> 1) : yStep) - 3,
|
||||
y: e.tail ? ((yStep >> 1) + 1) : 1,
|
||||
'data-stage': e.label
|
||||
}],
|
||||
...((brickWidth > 20) ? [['text', {class: e.name, width: brickWidth, x: brickWidth / 2, y: 16}, e.label]] : [])
|
||||
]);
|
||||
});
|
||||
|
||||
mLanes.push(mLane);
|
||||
}
|
||||
return mLanes;
|
||||
return mLanes;
|
||||
};
|
||||
|
||||
|
||||
module.exports = water;
|
||||
export default water;
|
@ -1,14 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
const xOffsetUpdate = (pstate, nextOffsetX) => {
|
||||
const xOffsetUpdate = (pstate, nextOffsetXFn) => {
|
||||
let nextOffsetX = nextOffsetXFn();
|
||||
const { width, xOffset, xScale, time, sidebarWidth } = pstate;
|
||||
|
||||
// console.log('input offset', nextOffsetX);
|
||||
// console.log('xScale', xScale);
|
||||
const maxOffsetX = width - xScale * time + 2000; // maximum offset
|
||||
const maxOffsetX = width + xScale * time * 1.0; // maximum offset
|
||||
nextOffsetX = Math.min(nextOffsetX, maxOffsetX);
|
||||
|
||||
const minOffsetX = 0; // minimum offset
|
||||
const minOffsetX = - width - xScale * time * 1.2; // minimum offset
|
||||
nextOffsetX = Math.max(nextOffsetX, minOffsetX);
|
||||
|
||||
// console.log('max offset', maxOffsetX);
|
||||
@ -16,11 +13,12 @@ const xOffsetUpdate = (pstate, nextOffsetX) => {
|
||||
// console.log('next offset', nextOffsetX);
|
||||
|
||||
if (nextOffsetX === xOffset) {
|
||||
return false; // exit without scroll
|
||||
return false; // exit without scroll
|
||||
}
|
||||
|
||||
pstate.oldXOffset = pstate.xOffset;
|
||||
pstate.xOffset = nextOffsetX;
|
||||
return true;
|
||||
};
|
||||
|
||||
module.exports = xOffsetUpdate;
|
||||
export default xOffsetUpdate;
|
@ -1,8 +1,14 @@
|
||||
'use strict';
|
||||
import xOffsetUpdate from './x-offset-update';
|
||||
|
||||
const xOffsetUpdate = require('./x-offset-update.js');
|
||||
|
||||
const xScaleUpdate = (pstate, xScaleNext) => {
|
||||
/**
|
||||
*
|
||||
* @param {{
|
||||
* xScale: number
|
||||
* }} pstate
|
||||
* @returns
|
||||
*/
|
||||
function xScaleUpdate(pstate, xScaleNextFn) {
|
||||
let xScaleNext = xScaleNextFn();
|
||||
const { xOffset, xCursor, xScale, xScaleMin, xScaleMax } = pstate;
|
||||
|
||||
xScaleNext = (xScaleNext > xScaleMax) ? xScaleMax : xScaleNext;
|
||||
@ -14,10 +20,12 @@ const xScaleUpdate = (pstate, xScaleNext) => {
|
||||
if (xScaleNext === xScale) {
|
||||
return false; // exit without scale change
|
||||
}
|
||||
|
||||
pstate.oldXScale = pstate.xScale;
|
||||
pstate.xScale = xScaleNext;
|
||||
|
||||
xOffsetUpdate(pstate, xCursor - (xCursor - xOffset) * xScaleNext / xScale);
|
||||
xOffsetUpdate(pstate, () => xCursor - (xCursor - xOffset) * xScaleNext / xScale);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = xScaleUpdate;
|
||||
export default xScaleUpdate;
|
30
src/hook/wave-view/y-offset-update.js
Normal file
30
src/hook/wave-view/y-offset-update.js
Normal file
@ -0,0 +1,30 @@
|
||||
import { globalStyle, globalLookup } from '../global';
|
||||
|
||||
const yOffsetUpdate = (pstate, nextOffsetYFn) => {
|
||||
let nextOffsetY = nextOffsetYFn();
|
||||
const { width, xOffset, xScale, time, sidebarWidth } = pstate;
|
||||
|
||||
const currentRenderHeight = globalLookup.currentWires.size * pstate.yStep;
|
||||
const canvasHeight = pstate.height - pstate.topBarHeight - pstate.botBarHeight;
|
||||
console.log(currentRenderHeight, canvasHeight);
|
||||
const maxOffsetX = Math.max(-40, currentRenderHeight - canvasHeight); // maximum offset
|
||||
nextOffsetY = Math.min(nextOffsetY, maxOffsetX);
|
||||
|
||||
const minOffsetX = -40; // minimum offset
|
||||
nextOffsetY = Math.max(nextOffsetY, minOffsetX);
|
||||
|
||||
if (nextOffsetY === xOffset) {
|
||||
return false; // exit without scroll
|
||||
}
|
||||
|
||||
console.log('next offset y', nextOffsetY);
|
||||
|
||||
pstate.oldYOffset = pstate.yOffset;
|
||||
pstate.yOffset = nextOffsetY;
|
||||
|
||||
// 这玩意儿初始设置 -40 的偏移,当作 padding-top
|
||||
globalStyle.yOffset = nextOffsetY + 40;
|
||||
return true;
|
||||
};
|
||||
|
||||
export default yOffsetUpdate;
|
@ -3,7 +3,13 @@
|
||||
"signal": "Signals",
|
||||
"search-signal": "Search Signal",
|
||||
"language-setting": "Language",
|
||||
"wheel-zoom-ratio": "Wheel Zoom Level",
|
||||
"horizontal-scaling-ratio": "Horizontal Scaling Level",
|
||||
"horizontal-scaling-ratio-description": "There are a total of 5 gear, the higher the gear, <br/>the higher the magnification when ctrl + mouse wheel zoomin",
|
||||
|
||||
"horizontal-roll-ratio": "Horizontal Roll Level",
|
||||
"horizontal-roll-ratio-description": "There are 5 gear positions in total. The higher the gear position, <br/>the larger the step length of the left and right sliding waveform timeline",
|
||||
"vertical-roll-ratio": "Vertical Roll Level",
|
||||
"vertical-roll-ratio-description": "There are 5 gear positions in total. The higher the gear position, <br/>the larger the step length of the up and down sliding waveform timeline",
|
||||
|
||||
"search-setting": "Search",
|
||||
"search-case-sensitivity": "Case Sensitivity",
|
||||
@ -21,6 +27,31 @@
|
||||
"appearance-setting": "Appearance",
|
||||
"display-wave-height": "Height of Wave Track",
|
||||
"display-signal-info-scope": "Info displayed in sidebar",
|
||||
"display-signal-info-scope.width": "width",
|
||||
"display-signal-info-scope.parent": "parent",
|
||||
|
||||
"wavecolor": "color of wave",
|
||||
"wavecolor.normal-bit": "wave of one width",
|
||||
"wavecolor.normal-vec": "wave of more than one width",
|
||||
"wavecolor.high-impedance": "wave of high impedance",
|
||||
"wavecolor.unknown": "wave of unknown",
|
||||
|
||||
"operation-setting": "Operation",
|
||||
"render-setting": "Render",
|
||||
"prerender": "prerender",
|
||||
"prerender-description": "Prerendering will make rendering faster, but will take up extra memory <br/> If your computer has more than 10 GB of memory, we recommend you turn it on.",
|
||||
|
||||
"render-animation": "enable rendering animation",
|
||||
|
||||
"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.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",
|
||||
|
||||
"loading": "loading",
|
||||
|
||||
"current-version": "current version",
|
||||
"copyright": "The copyright of this software belongs to <a href=\"https://github.com/Digital-EDA\" target=\"_blank\">Digital-IDE</a> project team. Welcome to <a href=\"https://github.com/Digital-EDA/Digital-IDE\">Star</a>."
|
||||
|
@ -5,7 +5,7 @@ import zh from './zh.json';
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'en',
|
||||
locale: 'zh',
|
||||
warnHtmlMessage: false,
|
||||
messages: { en, zh }
|
||||
});
|
||||
|
@ -3,7 +3,13 @@
|
||||
"signal": "信号",
|
||||
"search-signal": "搜索信号",
|
||||
"language-setting": "语言",
|
||||
"wheel-zoom-ratio": "滚轮缩放倍率",
|
||||
"horizontal-scaling-ratio": "横向缩放速度",
|
||||
"horizontal-scaling-ratio-description": "一共有5个挡位,挡位越高,<br/>ctrl + 鼠标滚轮缩放时的倍率越高",
|
||||
|
||||
"horizontal-roll-ratio": "横向滚动速度",
|
||||
"horizontal-roll-ratio-description": "一共有5个挡位,挡位越高,<br/>左右滑动波形时间轴的步长越大",
|
||||
"vertical-roll-ratio": "纵向滚动速度",
|
||||
"vertical-roll-ratio-description": "一共有5个挡位,挡位越高,<br/>上下滑动波形时间轴的步长越大",
|
||||
|
||||
"search-setting": "搜索",
|
||||
"search-case-sensitivity": "区分大小写",
|
||||
@ -20,6 +26,31 @@
|
||||
"appearance-setting": "外观",
|
||||
"display-wave-height": "波形轨道的高度",
|
||||
"display-signal-info-scope": "侧边栏展示信息",
|
||||
"display-signal-info-scope.width": "位宽",
|
||||
"display-signal-info-scope.parent": "所属模块名",
|
||||
|
||||
"wavecolor": "波形颜色",
|
||||
"wavecolor.normal-bit": "单位宽波形",
|
||||
"wavecolor.normal-vec": "多位宽波形",
|
||||
"wavecolor.high-impedance": "高阻态波形",
|
||||
"wavecolor.unknown": "未知态波形",
|
||||
|
||||
"operation-setting": "操作",
|
||||
"render-setting": "渲染",
|
||||
"prerender": "预渲染",
|
||||
"prerender-description": "预渲染将使得渲染速度更快,但是会占用额外内存<br/>如果您的电脑内存大于10个G,我们建议您开启。",
|
||||
|
||||
"render-animation": "开启渲染动画",
|
||||
|
||||
"usermanual": "使用说明",
|
||||
"usermanual.left-right-scroll.title": "<span class=\"iconfont icon-mouse\"/><span class=\"iconfont icon-up-down\"/>",
|
||||
"usermanual.left-right-scroll.caption": "上下移动",
|
||||
"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.caption": "左右移动",
|
||||
"usermanual.xscale.title": "<span class=\"iconfont icon-ctrl\"/> + <span class=\"iconfont icon-mouse\"/><span class=\"iconfont icon-up-down\"/>",
|
||||
"usermanual.xscale.caption": "横向缩放",
|
||||
|
||||
"loading": "加载中",
|
||||
|
||||
"current-version": "当前版本",
|
||||
"copyright": "本软件版权归 <a href=\"https://github.com/Digital-EDA\" target=\"_blank\">Digital-IDE</a> 项目组所有,欢迎 <a href=\"https://github.com/Digital-EDA/Digital-IDE\">Star</a>。"
|
||||
|
@ -10,5 +10,9 @@ module.exports = defineConfig({
|
||||
})
|
||||
return definitions;
|
||||
})
|
||||
},
|
||||
publicPath: './',
|
||||
configureWebpack: {
|
||||
devtool: false,
|
||||
}
|
||||
})
|
||||
|
@ -3,12 +3,13 @@ const Components = require('unplugin-vue-components/webpack')
|
||||
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
AutoImport({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
}),
|
||||
Components({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
}),
|
||||
],
|
||||
plugins: [
|
||||
AutoImport({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
}),
|
||||
Components({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
}),
|
||||
],
|
||||
devtool: 'none',
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user