0

我有一个带有 HTML5 画布的网页,我用它来显示许多图像以及画布上的四个“描述框”。

目的是用户将能够将图像拖放到他们匹配的描述框中,但是,我在拖放工作时遇到了一些麻烦。

我为添加拖放功能而编写的函数基于我在此页面上找到的教程:http: //simonsarris.com/blog/510-making-html5-canvas-useful

显然,我稍微修改了代码,因为我不想做教程中建议的所有事情,而且因为我正在画布上绘制图像(而不是形状)。但是,当在浏览器中查看我的页面时,尽管所有图像都显示在画布上,但拖放功能并未与我根据该教程编写的新 JavaScript 文件一起添加。

我在 Firebug 控制台中没有收到任何错误,并且页面显示的内容与添加新 JS 函数之前的状态完全相同。

谁能发现我错过了什么?

我的 HTML 是:

<!DOCTYPE html>
<html>
<head>
<script src = "kinetic.js" type = "text/javascript"></script>
<title>Home</title>

<script src = "drawLevelOneElements.js" type = "text/javascript"></script>
<script src = "layers&analytics.js" type = "text/javascript"></script>
<script src = "startGameDrawGameElementsDrawStartButton.js" type = "text/javascript"></script>
<script src = "interaction.js" type = "text/javascript"></script>
<script src = "dragAndDrop.js" type = "text/javascript"></script>


</head>

<body onLoad="startGame()">

<section hidden>
<img id="StartButton" src="StartButton.png" alt="Start Button" width="179" height="180" href="javascript:drawLevelOneElements();"/>
</section>

    <h1>Home</h1>
    <p>The purpose of this website is to teach users the basic principles of running a business by playing the game below. <br /><br /></p>

    <canvas id="gameCanvas" width="1000" height="500" style="border:1px solid">
    Your browser does not support the canvas element.
    </canvas>

    <br /><br />
    <p>Use this paragraph to enter text that provides the user with instructions for how to play the game. <br />
        Update the instructions so that they're appropriate to whatever level the user is currently playing.</p>

<script src = "layers&analytics.js" type = "text/javascript"></script>
<script src = "startGameDrawGameElementsDrawStartButton.js" type = "text/javascript"></script>
<script src = "variables&preloadingImages.js" type = "text/javascript"></script>
<script src = "drawLevelOneElements.js" type = "text/javascript"></script>
<script src = "interaction.js" type = "text/javascript"></script>-->
    <script src = "variables&preloadingImages.js" type = "text/javascript"></script>
</body>

页面底部的所有脚本标签(除了最后一个)实际上在我的文件中都被注释掉了,我只需要删除注释才能让它显示在此处的代码块中。

我为拖放功能添加的 javaScript 是:

function canvasState(myGameCanvas){

var bounding_box = myGameCanvas.getBoundingClientRect();
var mouseX = (mouse_event.clientX-bounding_box.left) * (myGameCanvas.width/bouding_box.width);
var mouseY = (mouse_event.clientY-bounding_box.top) * (myGameCanvas.height/bounding_box.height);
var pixels = context.getImageData(mouseX, mouseY, 1, 1);

this.valid = false; /*When set to true, the canvas will redraw everything */
this.allImagesArray; /*This is the array holding all of the images to be drawn */
this.dragging = false; /*Keep track of when the current selected object is being dragged */
this.selection = null;
this.dragOffX = 0; /*See mousedown and mousemove events for explanation */
this.dragOffY = 0;

this.interval = 30; /*This variable will be used to determine how often the draw method is called. */

/*Save a reference to the canvasState so that I'm still using this particular canvasState. */
var myState = this;

/*This stops double clicking on the canvas selecting text on the canvas */
myGameCanvas.addEventListener('selectstart', function(e) {e.preventDefault(); return false; }, false);
/*Up, down and move are for dragging */
myGameCanvas.addEventListener('mousedown', function(e){
    var mouse = myState.getMouse(e);
    var mX = mouse.x;
    var mY = mouse.y;
    var allImages = myState.allImagesArray;
    var NoOfImages = allImages.length;
    for (var i = 1-1; i >= 0; i--){
        if(allImages[i].contains(mX, mY)){
            var mySelection = allImages[i];
            /*Keep track of where in the object was clicked, so that it can be 
                moved smoothly (see mousemove) */
            myState.dragOffX = mX - mySelection.x;
            myState.dragOffY = mY - mySelection.y;
            myState.dragging = true;
            myState.selection = mySelection;
            myState.valid = false;
            return;
        }
    }
    /*If the code hasn't returned, it means that nothing has been selected.
    If there was an object selected, then deselect it. */
    if (myState.selection){
        myState.selection = null;
        myState.valid = false; /*Need to clear the old selection border */

    }
}, true);

/*This event checks to see if the dragging flag has been set to true. If it has, it gets the
current mouse position and moves the selected object to that position, remembering the offset
where it was selected. If the dragging flag is false, the event does nothing. */
myGameCanvas.addEventListener('mousemove', function(e){
    if(myState.dragging){
        var mouse = myState.getMouse(e);
        /*I don't want to drag the object by its top left corner, I want to drag from where the
        object was clicked. That's why I saved the offset and use it here. */
        myState.selection.x = mouse.x - myState.dragOffX;
        myState.selection.y = mouse.y - myState.dragOffY;
        myState.valid = false; /*Something's dragging, so I must redraw */
    }
}, true);

/*All the mouseup event has to do is update the canvas state so that it is no longer dragging.
So, once the mouse button is lifted, the mousemove event should be back to doing nothing. */
myGameCanvas.addEventListener('mouseup', function(e){
    myState.dragging = false;
}, true);

setInterval(function(){ myState.draw(); }, myState.interval);

canvasState.prototype.draw = function(){
    /*If the state is invalid,redraw and validate. */
    if (!this.valid){
        var context = this.context;
        var images = this.images;
        this.clear();

        /*Redraw the game elements here */
        drawLevelOneElements();
    }
}


}

dragAndDrop.js 的代码:

function canvasState(myGameCanvas){

var bounding_box = myGameCanvas.getBoundingClientRect();
var mouseX = (mouse_event.clientX-bounding_box.left) * (myGameCanvas.width/bouding_box.width);
var mouseY = (mouse_event.clientY-bounding_box.top) * (myGameCanvas.height/bounding_box.height);
var pixels = context.getImageData(mouseX, mouseY, 1, 1);

this.valid = false; /*When set to true, the canvas will redraw everything */
this.allImagesArray; /*This is the array holding all of the images to be drawn */
this.dragging = false; /*Keep track of when the current selected object is being dragged */
this.selection = null;
this.dragOffX = 0; /*See mousedown and mousemove events for explanation */
this.dragOffY = 0;

this.interval = 30; /*This variable will be used to determine how often the draw method is called. */

/*Save a reference to the canvasState so that I'm still using this particular canvasState. */
var myState = this;

/*This stops double clicking on the canvas selecting text on the canvas */
myGameCanvas.addEventListener('selectstart', function(e) {e.preventDefault(); return false; }, false);
console.log("Event Listener 'selectstart' added to canvas.");
/*Up, down and move are for dragging */
myGameCanvas.addEventListener('mousedown', function(e){
    console.log("Event Listener 'mousedown' added to canvas");
    var mouse = myState.getMouse(e);
    var mX = mouse.x;
    var mY = mouse.y;
    var allImages = myState.allImagesArray;
    var NoOfImages = allImages.length;
    for (var i = 1-1; i >= 0; i--){
        if(allImages[i].contains(mX, mY)){
            var mySelection = allImages[i];
            /*Keep track of where in the object was clicked, so that it can be 
                moved smoothly (see mousemove) */
            myState.dragOffX = mX - mySelection.x;
            myState.dragOffY = mY - mySelection.y;
            myState.dragging = true;
            myState.selection = mySelection;
            myState.valid = false;
            return;
        }
    }
    /*If the code hasn't returned, it means that nothing has been selected.
    If there was an object selected, then deselect it. */
    if (myState.selection){
        myState.selection = null;
        myState.valid = false; /*Need to clear the old selection border */

    }
}, true);

/*This event checks to see if the dragging flag has been set to true. If it has, it gets the
current mouse position and moves the selected object to that position, remembering the offset
where it was selected. If the dragging flag is false, the event does nothing. */
myGameCanvas.addEventListener('mousemove', function(e){
    console.log("Event listener 'mousemove' added to canvas.");
    if(myState.dragging){
        var mouse = myState.getMouse(e);
        /*I don't want to drag the object by its top left corner, I want to drag from where the
        object was clicked. That's why I saved the offset and use it here. */
        myState.selection.x = mouse.x - myState.dragOffX;
        myState.selection.y = mouse.y - myState.dragOffY;
        myState.valid = false; /*Something's dragging, so I must redraw */
    }
}, true);

/*All the mouseup event has to do is update the canvas state so that it is no longer dragging.
So, once the mouse button is lifted, the mousemove event should be back to doing nothing. */
myGameCanvas.addEventListener('mouseup', function(e){
    console.log("Event listener 'mouseup' added to canvas.");
    myState.dragging = false;
}, true);

setInterval(function(){ myState.draw(); }, myState.interval);

canvasState.prototype.draw = function(){
    /*If the state is invalid,redraw and validate. */
    if (!this.valid){
        var context = this.context;
        var images = this.images;
        this.clear();

        /*Redraw the game elements here */
        drawLevelOneElements();
    }
}


}

drawLevelOneElements.js 的代码:(现在包括对 canvasState(); 的调用)

function drawLevelOneElements(){
            /*First, clear the canvas */ 
            context.clearRect(0, 0, myGameCanvas.width, myGameCanvas.height);
            /*This line clears all of the elements that were previously drawn on the canvas. */
            /*Then redraw the game elements */
            drawGameElements(); 
            /*Call the function to enable drag and drop */
            canvasState(document.getElementById('gameCanvas'));

            /*Create the four description areas, and place them near the bottom of the canvas */
            /*Create boxes with rounded corners for the description areas */
            CanvasRenderingContext2D.prototype.drawDescriptionArea = function(x, y, width, height, radius, stroke){
                if(typeof stroke == "undefined" ){
                    stroke = true;
                }
                if(typeof radius === "undefined"){
                    radius = 5;
                }
                this.beginPath();
                this.moveTo(x + radius, y);
                this.lineTo(x + width - radius, y);
                this.quadraticCurveTo(x + width, y, x + width, y + radius);
                this.lineTo(x + width, y + height - radius);
                this.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
                this.lineTo(x + radius, y + height);
                this.quadraticCurveTo(x, y + height, x, y + height - radius);
                this.lineTo(x, y + radius);
                this.quadraticCurveTo(x, y, x + radius, y);
                this.closePath();
                if(stroke){
                    context.stroke();
                }
            }

            context.drawDescriptionArea(70, 400, 120, 70);
            context.font = '25pt Calibri';
            context.strokeText('Asset', 90, 440);

            context.drawDescriptionArea(300, 400, 120, 70);
            context.strokeText('Liability', 310, 440);

            context.drawDescriptionArea(540, 400, 120, 70);
            context.strokeText('Income', 550, 440);

            context.drawDescriptionArea(750, 400, 180, 70);
            context.strokeText('Expenditure', 760, 440);

            /*Now draw the images to the canvas */
            /*First, create variables for the x & y coordinates of the image that will be drawn.
                the x & y coordinates should hold random numbers, so that the images will be 
                drawn in random locations on the canvas.*/
                var imageX = Math.floor(Math.random()*100);
                var imageY = Math.floor(Math.random()*100);

                /*Create a 'table' of positions that the images will be drawn to */
                var imagePositionsX = [20, 80, 140, 200, 260, 320, 380, 440, 500, 560];
                var imagePositionsY = [20, 60, 100, 140, 180, 220, 260, 300, 340, 380];

            /*Draw all images from assetsImageArray */
            /*Use a while loop to loop through the array, get each item and draw it. */
            var arrayIteration = 0;
            console.log('All Images Array length: ' + allImagesArray.length); /*Display the length of the array in the console, to check it's holding the correct number of images. */
            while(arrayIteration < allImagesArray.length){
                var randomPositionX = Math.floor(Math.random()*10);
                var randomPositionY = Math.floor(Math.random()*10);
                context.drawImage(allImagesArray[arrayIteration], imageX, imageY, 50, 50);
                console.log(arrayIteration); /*Display the current array position that's being drawn */
                arrayIteration = arrayIteration+1;
                /*Now try changing the values of imageX & imageY so that the next image is drawn to a 
                    different location*/
                imageX = imagePositionsX[randomPositionX];  /* imageX+(Math.floor(Math.random()*100)); */
                imageY = imagePositionsY[randomPositionY];  /* imageY+(Math.floor(Math.random()*100));  */

            }

        }
4

1 回答 1

0

作为评论的总结,我可以回答你:在你的代码中的某个地方,你必须调用 canvasState() 函数,仅仅定义它是不够的。您必须在哪里调用它很大程度上取决于您何时需要它的功能。例如,如果你想在页面加载时设置拖放功能,你有一个用于 body 的 load 事件的事件处理程序:

<body onLoad="startGame()">

在 startGame() 函数的代码中,您可以调用 canvasState()。如果您在按下 StartButton 时需要它,您应该从 drawLevelOneElements() 函数中调用它。由于您正在学习教程,因此事情发生的顺序可能很重要,因此您可能需要在特定位置调用您的函数。

还有一个建议。因为您似乎正在学习,所以从基础开始,然后深入了解您所学的内容,不要只是遵循随机教程。

于 2012-12-05T12:05:21.367 回答