foreach循环中的画布元素?

时间:2013-11-18 19:50:08

标签: javascript jquery html5 canvas

好的,所以我的javascript和canvas在循环之外工作,但是当它在循环中时会出现问题。

  1. 我必须在控制台内手动运行javascript(只需复制粘贴原始代码然后点击运行),这将触发然后返回Object[canvas#myCanvas],部分javascript工作,然后手动输入到控制台,但有些功能不会。手动运行一切正常。

  2. 即使在手动运行之后,其他循环项目中的canvas元素也不起作用,因此它只适用于第一个元素。

  3. Javascript: 我在页脚中设置了它(当它在标题内部没有正确加载时,在画布下会导致代码循环,所以页脚效果最好)。我使用了window.onload$(document).ready(),但它没有工作,因为它是在页脚之后加载的。

    var canvas = document.getElementById("myCanvas");
    var ctx = canvas.getContext("2d");
    
    var canvasOffset = $("#myCanvas").offset();
    var offsetX = canvasOffset.left;
    var offsetY = canvasOffset.top;
    
    var img = new Image();
    img.onload = function () {
        canvas.width = img.width;
        canvas.height = img.height;
        ctx.lineWidth = 5;
    }
    img.src = "http://localhost/stat-tracker/images/basketball-court.png";
    
    function is2Point(x, y) {
        ctx.beginPath();
        ctx.moveTo(0, 31);
        console.log(ctx.bezierCurveTo(260, 50, 200, 250, 0, 257));
        ctx.closePath();
        if (ctx.isPointInPath(x, y)) {
            ctx.fillStyle = "gold";
            ctx.fill();
            return (true);
        }
        return (false);
    }
    
    function isInside(x, y) {
        ctx.beginPath();
        ctx.rect(76, 190, 125, 90);
        if (ctx.isPointInPath(x, y)) {
            ctx.fillStyle = "green";
            ctx.fill();
            return (true);
        }
        return (false);
    }
    
    function handleMouseMove(e) {
        x = parseInt(e.clientX - offsetX);
        y = parseInt(e.clientY - offsetY);
    
        ctx.clearRect(0, 0, canvas.width, canvas.height);
    
        if (!isInside(x, y) && !is2Point(x, y)) {
            ctx.beginPath();
            ctx.rect(0, 0, canvas.width, canvas.height);
            ctx.strokeStyle = "red";
            ctx.stroke();
        }
    
    }
    
    $("#myCanvas").mousemove(function (e) {
        console.log(handleMouseMove(e));
    });
    

    PHP: 它嵌套在更多div中,但这里有一个想法是如何循环。

    <?php foreach($playerData as $key => $player): ?>
      <?php foreach($player as $teamkey => $team): ?>
        <div class="<?php echo $teamkey ?>">
        <?php foreach($team as $playernamekey => $playername): ?>
          <?php foreach($playername as $statskey => $stats): ?>
            <div class="add-stat-data"> 
            <!-- Shot chart here -->
            <img id="court-image" src="./images/basketball-court.png">
            <canvas id="myCanvas" width=300 height=300></canvas>
            </div>
          <?php endforeach;  ?>
        <?php endforeach;  ?>
        </div>
      <?php endforeach;  ?>
    <?php endforeach;  ?>
    

    我得到的结果(参考fiddle)是鼠标移动时没有显示某些功能,特别是绿色和黄色。

    再次测试一次,将画布/图像复制到身体附近的顶部工作,很好。所以我想说我98%肯定这是foreach。 @Pointy 指出并且是对的我不应该使用ID循环元素?这就是问题所在,我需要把它变成一个类吗?

    更新:我用超时更新了我的代码,我用var zoneCanvas = function() {}包装了上面的javascript,然后在函数上设置了5秒超时。它工作,但不是一个想法的解决方案,是因为我的画布是在脚本之后加载的吗?

    setTimeout(function() {
        zoneCanvas();
    },5000)
    

    更新:好的我不确定这是否理想,但我将var canvas = document.querySelector(".chart-is-opened .myCanvas")设置为包含画布的活动元素,我还设置了超时setTimeout(function() { zoneCanvas(); },0)函数在click事件中,所以当打开一个新图表时它重新加载该函数,然后canvas元素现在是活动元素。

    希望有道理感觉很高兴发布更多代码,但是我害怕这会导致DOM冒泡或者它不是理想的解决方案吗?有关每次超时重新加载函数的建议吗?

1 个答案:

答案 0 :(得分:1)

我有一个包含多个画布的项目,这些画布会被循环播放,我遇到的问题是需要将上下文设置为当前画布。我最终将变量ctx设为全局,并将其设置在任何使用画布的函数上,例如:

function startBrush(canvasID, color, lineWidth, x1, y1) { // called from mouse down
    ctx=$('#'+canvasID)[0].getContext('2d');
    ctx.moveTo(x1, y1);
    ctx.beginPath();
}

function drawBrush(canvasID, color, lineWidth, x1, y1) { // called from mouse move
    ctx.strokeStyle=color;
    ctx.lineWidth=lineWidth;
    ctx.lineTo(x1, y1);
    ctx.stroke();
    ctx.moveTo(x1, y1);
}