首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >html5画布向画布上绘制的图像添加拖放操作

html5画布向画布上绘制的图像添加拖放操作
EN

Stack Overflow用户
提问于 2012-12-03 21:31:50
回答 1查看 2.8K关注 0票数 0

我有一个带有HTML5画布的网页,我用它在画布上显示一些图像和四个“描述框”。

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

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

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

我在Firebug控制台中没有得到任何错误,页面显示与我添加新JS函数之前完全一样。

有人能发现我错过了什么吗?

我的HTML是:

代码语言:javascript
运行
复制
<!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是:

代码语言: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代码:

代码语言: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);
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();的调用)

代码语言:javascript
运行
复制
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));  */

            }

        }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-12-05 20:05:21

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

代码语言:javascript
运行
复制
<body onLoad="startGame()">

在startGame()函数的代码中,您可以调用canvasState()。如果在按下StartButton时需要它,则应该从drawLevelOneElements()函数中调用它。因为您正在学习教程,所以事情发生的顺序可能很重要,所以可能有一个特定的地方需要调用您的函数。

再提一个建议。因为你似乎正在学习,所以从基础开始,深入理解你到目前为止学到的东西,而不是只遵循随机的教程。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13684314

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档