3

首先,我感谢网站和在我的 html5 和 javascript 查询中提供了很多帮助的成员。让我进入我的问题。在我使用画布和 javascript 创建的柱形图中。我必须包括一个工具提示。我开发了一个工具提示,我在下面给出了代码和图像。问题是工具提示没有重绘,它一次又一次地绘制。

在此处输入图像描述

<!doctype html>
<html>
    <head>
        <script type="text/javascript">
        window.onload=function() {
            var canvas=document.getElementById('mycanvas');
            var ctx=canvas.getContext('2d');
            var graphInfo=[{data:[120,130,140,160,180,100],color:'purple',label:["a","b","c","d","e","f"]},{data:[100,120,130,140,150,190],color:'green',label:["g","h","i","j","k","l"]}];
            var width=45;
             function renderGrid(gridPixelSize, color)
    {
        ctx.save();
        ctx.lineWidth = 0.5;
        ctx.strokeStyle = color;
        for(var i = 20; i <= canvas.height-20; i = i + gridPixelSize)
        {
            ctx.beginPath();
            ctx.moveTo(20, i);
            ctx.lineTo(canvas.width-20, i);
            ctx.closePath();
            ctx.stroke();
        }
        for(var j = 20; j <= canvas.width-20; j = j + gridPixelSize)
        {
            ctx.beginPath();
            ctx.moveTo(j, 20);
            ctx.lineTo(j, canvas.height-20);
            ctx.closePath();
            ctx.stroke();
        }
        ctx.restore();
    }
   renderGrid(10, "grey");

            ctx.beginPath();
            ctx.strokeStyle = 'black';
            ctx.moveTo(20, canvas.height-20);
            ctx.lineTo(canvas.width-20, canvas.height-20);
            ctx.closePath();
            ctx.stroke();

            ctx.beginPath();
    ctx.strokeStyle = 'black';
            ctx.moveTo(20, 20);
            ctx.lineTo(20, canvas.height-20);
            ctx.closePath();
            ctx.stroke();
            ctx.font = "bold 16px Arial";

    function getFunctionForTimeout(j){
                var i=0,currx=30,info=graphInfo[j],x5=j*5;
                var fTimeout=function(){
                    var h=Math.max(info.data[i]-x5,0);
                    var m=info.label[i];
                    ctx.fillStyle='black'
                    ctx.fillRect(currx+(10*x5)+2,canvas.height-h-20,width+2,h-1);
                    ctx.fillStyle=info.color;                   
                    ctx.fillRect(currx+(10*x5),canvas.height-h-21,width,h);                 
                    ctx.fillText(m, currx+(10*x5)+20, canvas.height-5);
                    currx+=120;  
                    i++;
                    if(i<info.data.length)setTimeout(fTimeout,0);
                     canvas.addEventListener('mousemove',function onMouseover(e) {
                        var mx = e.clientX - 8;
                        var my = e.clientY - 8;
                        ctx.save();
                        var str='X : ' + mx + ', ' + 'Y :' + my;
                        ctx.fillStyle = '#00ff00';
                        ctx.fillRect(mx + 10, my + 10, 70, 20);
                        ctx.fillStyle = '#000';
                        ctx.font = 'bold 20px verdana';
                        ctx.fillText(str, mx + 10, my + 25, 60);
                        ctx.restore();
                    }, 0);
                };
                return fTimeout;
    }

            for(var j=graphInfo.length-1;j>=0;j--) {
                setTimeout(getFunctionForTimeout(j),2000);
            }
        };
        </script>
    </head>
    <body>
        <canvas id="mycanvas" height="400" width="800" style="border:1px solid #000000;">
    </body>
</html>
4

3 回答 3

1

HTML5 Canvas 与 SVG 或 HTML 不同:您不能只是添加和删除元素,或更改它们的属性,并期望为您重新绘制内容。当你在画布上画东西时,它是永久的。要“移动”某些内容,您必须擦除画布 ( clearRect()),然后使用工具提示在新位置再次绘制内容。

或者,我建议不要将画布用作工具提示。你为什么要?相反,将工具提示创建为单独的 HTML(或 SVG)元素并移动它。让浏览器为您重绘合成。

于 2012-07-27T15:30:05.400 回答
0

restore绘制提示框后是否想要画布?我认为这行不通。首先我们看一下定义save/restore

语境 。save() 将当前状态压入堆栈。

语境 。restore() 弹出栈顶状态,将上下文恢复到该状态。

那么,什么是“当前状态”?

规格

绘图状态包括:

  • 当前的变换矩阵。
  • 当前剪辑区域。
  • 以下属性的当前值:
    • 笔触风格,
    • 填充样式,
    • 全球阿尔法,
    • 行宽,
    • 线帽,
    • 线连接,
    • 斜接限制,
    • lineDashOffset,
    • shadowOffsetX,
    • shadowOffsetY,
    • 阴影模糊,
    • 阴影颜色,
    • globalCompositeOperation,
    • 字体,
    • 文本对齐,
    • 文本基线,
    • 图像平滑启用。
  • 当前的破折号列表。

不包含:

当前默认路径和当前位图不是绘图状态的一部分。当前默认路径是持久的,只能使用 beginPath() 方法重置。当前位图是画布的属性,而不是上下文。

我猜你想要一些操作,比如undo. 我建议你检查toDataURLdrawImage方法,前者返回一个 Base64 编码的图像,并用于drawImage将该图像绘制回画布。或者,你可以google一下

于 2012-07-27T12:39:05.613 回答
0

只需尝试这段代码,因为上次使用 getMousePos() 方法获取鼠标 x 和 y 位置并将其传送到您的工具提示..(现在它是一个警报):)

<!doctype html>
<html>
    <head>
        <script type="text/javascript">
        window.onload=function() {
            var canvas=document.getElementById('mycanvas');

            canvas.addEventListener('mousemove', function(evt) {
                  var mousePos = getMousePos(canvas, evt);
                  var message = "Mouse position: " + mousePos.x + "," + mousePos.y;
                  //alert(message);
                }, false);

            var ctx=canvas.getContext('2d');
            var graphInfo=[{data:[120,130,140,160,180,100],color:'purple',label:["a","b","c","d","e","f"]},{data:[100,120,130,140,150,190],color:'green',label:["g","h","i","j","k","l"]}];
            var width=45;
             function renderGrid(gridPixelSize, color)
    {
        ctx.save();
        ctx.lineWidth = 0.5;
        ctx.strokeStyle = color;
        for(var i = 20; i <= canvas.height-20; i = i + gridPixelSize)
        {
            ctx.beginPath();
            ctx.moveTo(20, i);
            ctx.lineTo(canvas.width-20, i);
            ctx.closePath();
            ctx.stroke();
        }
        for(var j = 20; j <= canvas.width-20; j = j + gridPixelSize)
        {
            ctx.beginPath();
            ctx.moveTo(j, 20);
            ctx.lineTo(j, canvas.height-20);
            ctx.closePath();
            ctx.stroke();
        }
        ctx.restore();
    }
   renderGrid(10, "grey");

            ctx.beginPath();
            ctx.strokeStyle = 'black';
            ctx.moveTo(20, canvas.height-20);
            ctx.lineTo(canvas.width-20, canvas.height-20);
            ctx.closePath();
            ctx.stroke();

            ctx.beginPath();
    ctx.strokeStyle = 'black';
            ctx.moveTo(20, 20);
            ctx.lineTo(20, canvas.height-20);
            ctx.closePath();
            ctx.stroke();
            ctx.font = "bold 16px Arial";

            function getMousePos(canvas, evt) {
                var rect = canvas.getBoundingClientRect(), root = document.documentElement;

                // return relative mouse position
                var mouseX = evt.clientX - rect.top - root.scrollTop;
                var mouseY = evt.clientY - rect.left - root.scrollLeft;
                return {
                  x: mouseX,
                  y: mouseY
                };
              }
    function getFunctionForTimeout(j){
                var i=0,currx=30,info=graphInfo[j],x5=j*5;
                var fTimeout=function(){
                    var h=Math.max(info.data[i]-x5,0);
                    var m=info.label[i];
                    ctx.fillStyle='black'
                    ctx.fillRect(currx+(10*x5)+2,canvas.height-h-20,width+2,h-1);
                    ctx.fillStyle=info.color;                   
                    ctx.fillRect(currx+(10*x5),canvas.height-h-21,width,h);                 
                    ctx.fillText(m, currx+(10*x5)+20, canvas.height-5);
                    currx+=120;  
                    i++;
                    if(i<info.data.length)setTimeout(fTimeout,0);
                     canvas.addEventListener('mousemove',function onMouseover(e) {
                        var mx = e.clientX - 8;
                        var my = e.clientY - 8;
                        ctx.save();
                        var str='X : ' + mx + ', ' + 'Y :' + my;
                        ctx.fillStyle = '#00ff00';
                        ctx.fillRect(mx + 10, my + 10, 70, 20);
                        ctx.fillStyle = '#000';
                        ctx.font = 'bold 20px verdana';
                        ctx.fillText(str, mx + 10, my + 25, 60);
                        ctx.restore();
                    }, 0);
                };
                return fTimeout;
    }

            for(var j=graphInfo.length-1;j>=0;j--) {
                setTimeout(getFunctionForTimeout(j),2000);
            }
        };
        </script>
    </head>
    <body>
        <canvas id="mycanvas" height="400" width="800" style="border:1px solid #000000;">
    </body>
</html>
于 2012-07-27T12:45:38.027 回答