html5画布可以执行以下操作吗?如果是,那怎么......
span
ID标识),无论浏览器缩放大小或换行符我正在尝试使用HTML / CSS / JS创建以下内容:
(请原谅绿色波浪形的下划线)
突出显示的文字显然可以使用background-color:
棘手的部分是用箭头连接突出显示的文本,我认为它可以用HTLM画布完成,但我对任何想法持开放态度。
同样漂亮的小奖励是悬停时可能会突出显示/箭头,也可能是关闭按钮。
PS有点背景,文本是一些简化的JCL(大型机的一种脚本语言),突出显示的项目是文件。我试图通过作业(脚本)更容易跟踪数据流。这是非常简单的版本,但许多作业可能是100多行,有很多细节,这使得很难追踪彼此相关的步骤。如果有其他想法或工具来帮助跟踪JCL中的数据流,请告诉我。
//COBLPGM EXEC PGM=COBLPGM
//INPUT DD DSN=&&SORT,DISP=(OLD,DELETE)
//NACHA DD DSN=NODE.OPER.COBLPGM.OUT(+1)
//SORT2 EXEC PGM=SORT
//SORTIN DD DSN=NODE.OPER.COBLPGM.OUT(+1)
//SORTOUT DD DSN=&&SORT2,DISP=(,PASS)
//SYSIN DD DSN=NODE.OPER.PROCLIB(MEM)
//UNRELATE EXEC PGM=UNPGM
//INPUT DD DSN=NODE.OPER.UNRELATED.FILE
//REPORT DD DSN=&&REPORT
//TSTEMPT1 EXEC PGM=SPOPNCLO
//IN DD DSN=&&SORT2,DISP=(OLD,DELETE)
// IF TSTEMPT1.RC=0 THEN
//SORT3 EXEC PGM=SORT
//SORTIN DD DSN=NODE.OPER.COBLPGM.OUT(+1)
//SORTOUT DD DSN=&&SORT3,DISP=(,PASS),LRECL=141
//SYSIN DD DSN=NODE.OPER.CNTRLCDS(PARM)
// ENDIF
答案 0 :(得分:2)
这只是一个"概念"回答显示您可以跟踪HTML以同步画布元素。
以下代码将文本本身放在HTML中的<pre>
标记中。背景中有一个画布,大小固定。画布在滚动时更新,因此相对于页面绘制框(它也应在调整大小时更新,未显示)。
由于我们可以跟踪文本,您可以看到我们也可以放置相对于它的任何其他图形,例如箭头和线条。我没有在这里展示,因为我觉得它太宽泛,但你应该得到它的要点,因为它显示了如何计算文本行和字符位置。
依据是:
<pre>
代码measureText()
上下文通过设置上下文来衡量每行的宽度,以使用与<pre>
标记相同的字体和大小文本可以选择,背景中的画布标记区域。
请注意,文本行中的特殊字符可能会抛出measureText(例如&amp;&amp; in示例文本中)。在测量之前,必须对这些字符进行编码或替换。使用等宽字体替换不是问题,例如在这种情况下。
var pre = document.querySelector("pre"), // get pre ele,ent
rect = pre.getBoundingClientRect(), // get its absolute position
lines = pre.innerHTML.split("\n"), // split text lines
count = lines.length, // count lines
lineH = rect.height / count, // line height
canvas = document.querySelector("canvas"), // setup canvas
ctx = canvas.getContext("2d");
canvas.width = window.innerWidth; // todo: update on resize
canvas.height = window.innerHeight;
ctx.font = "14px monospace"; // use same font in canvas as for pre
ctx.strokeStyle = "#d00";
ctx.translate(0.5, 0.5); // makes lines sharper for demo
window.onscroll = drawBoxes; // we need to track scrolling
drawBoxes();
function drawBoxes() { // render line boxes (y)
ctx.clearRect(0, 0, canvas.width, canvas.height);
for(var i = 0; i < count; i++) {
var w = ctx.measureText(lines[i]).width;
if (w) ctx.strokeRect(rect.left, rect.top + i * lineH - window.scrollY, w, lineH - 1);
showChars(lines[i], rect.top + i * lineH - window.scrollY, lineH);
}
}
function showChars(line, y, h) { // render char lines (x)
ctx.beginPath();
for(var i = 0, ch, x, s = ""; ch = line[i]; i++) {
s += ch;
x = ctx.measureText(s).width;
ctx.moveTo(x, y); ctx.lineTo(x, y + h - 1);
}
ctx.globalAlpha = 0.2;
ctx.stroke();
ctx.globalAlpha = 1;
}
&#13;
canvas {position:fixed;left:0;top:0;z-index:-1}
pre {font:14px monospace}
&#13;
<canvas></canvas>
<pre>//COBLPGM EXEC PGM=COBLPGM
//INPUT DD DSN=SORT,DISP=(OLD,DELETE)
//NACHA DD DSN=NODE.OPER.COBLPGM.OUT(+1)
//SORT2 EXEC PGM=SORT
//SORTIN DD DSN=NODE.OPER.COBLPGM.OUT(+1)
//SORTOUT DD DSN=SORT2,DISP=(,PASS)
//SYSIN DD DSN=NODE.OPER.PROCLIB(MEM)
//UNRELATE EXEC PGM=UNPGM
//INPUT DD DSN=NODE.OPER.UNRELATED.FILE
//REPORT DD DSN=REPORT
//TSTEMPT1 EXEC PGM=SPOPNCLO
//IN DD DSN=SORT2,DISP=(OLD,DELETE)
// IF TSTEMPT1.RC=0 THEN
//SORT3 EXEC PGM=SORT
//SORTIN DD DSN=NODE.OPER.COBLPGM.OUT(+1)
//SORTOUT DD DSN=SORT3,DISP=(,PASS),LRECL=141
//SYSIN DD DSN=NODE.OPER.CNTRLCDS(PARM)
// ENDIF</pre>
&#13;