html5画布,用户点击图像时显示文字

时间:2012-12-31 13:52:22

标签: javascript html5 html5-canvas kineticjs

我有一个带有HTML5画布的页面,其上显示了几个图像。有四个“描述框”图像和许多其他图像,每个图像属于一个描述框。

用户需要将每个图像拖动到相应的描述框中。

目前可以在画布上拖动图像,但我还没有添加将它们放到框中的功能。

在此之前,我想为用户添加一些“提示和提示”。我想这样做的方法是,每次点击其中一个“可拖动”图像时,在画布区域外向用户显示文本提示,或将光标悬停在描述框上。文本提示将只包含有关用户选择/悬停的图标的更多信息。

我在画布下方的页面上添加了一个HTML5文本区域,这是我想要显示提示和提示的地方。

我有几个JS数组,一个包含画布上显示的所有图像,另一个包含所有提示。提示只会在一个项目中显示一个,因为很明显,光标只能在任何给定时间在一个地方。

所以,我想要发生的是使用'if'语句,这样如果用户点击图像,那么对应于该图像的文本提示将显示在文本框中,或者如果光标将鼠标悬停在描述框上,然后文本框中将显示与该描述框对应的文本提示。

我已经使用kinetic.js库为我画布上的图像添加了拖放功能,虽然我使用的是我本地保存的库的副本,因为我需要更改一些东西关于它的功能。 (我需要改变的东西是最初的,图书馆清除画布上任何被绘制的东西,除了拖放图像之外的拖放功能,只是重新绘制拖放功能的图像正在被添加回来,所以我丢失了一些其他的东西,我正在绘制画布,我不想被拖拽。)

我知道我需要编辑我正在进一步使用的kinetic.js库以便使用提示添加此功能,但我只是想知道是否有人知道如何在我的数组中显示提示文本区域我已添加到我的页面?

我已经看过w3schools上的'HTML5 textarea标签'页面,但我看不到任何允许您定义文本区域中显示的文本的属性。我还看了一下从该页面链接的“事件属性”页面,但是看不到任何看起来像执行我想要的功能的属性。

当用户选择图片或将鼠标悬停在我的某个描述框上时,textarea是用来显示我想要显示的文字的最佳选择吗?或者是否有其他东西可以显示文本(最好是在页面的画布区域之外),并允许我更改动态显示的文本?

修改以显示HTML 31/12/2012 @ 14:40

<!DOCTYPE HTML>
<html>
  <head>
  <style>
    body {
      margin: 0px;
      padding: 0px;
    }
  canvas{
    border: 1px solid #9C9898;
    background:#F5F5F5;
  }
</style>
<div id="container"></div>
<script src="kinetic.js"></script>
<script src="drawdescriptionboxes.js"></script>
<script src="drawLevelOneElements.js"></script>
<script src="startgamedrawgameelementsdrawstartbutton.js"></script>
<script>
/*Add the game elements' global variables */
var currentLevel = 1;
var totalLevels = 3;
var currentScore = 0;
var currentScorePositionX = 950;
var currentScorePositionY = 10;

/*Add code to draw images to random locations here */
    //var imageX = Math.floor(Math.random()*950);
    //var imageY = Math.floor(Math.random()*450);

    var stage = new Kinetic.Stage({
      container: "container",
      width: 1000,
      height: 500
    });
    var imagesLayer = new Kinetic.Layer();
    var canvas = imagesLayer.getCanvas();
    var context = canvas.getContext("2d");
    console.log("Foo ");

/*Load the images from the HTML into the JavaScript */
function loadImages(sources, callback){
    var imagesDir = "";
    var images = {};
    var loadedImages = 0;
    var numImages = 0;

    //console.log("length " + sources.length);
    for (var src in sources){
        numImages++;
    }
    //console.log("Num Images " + numImages);

    var index=0;
    console.log("length " + sources.length);
    for (index=0;index < numImages ;index++){
        console.log(index);
        images[index] = new Image();
        images[index].src = sources[index];
        console.log("Adding " + sources[index]);
        callback(images[index]);
        console.log("images array length = " + images.length);
    }

    stage.add(imagesLayer); // should only be added once!!
}

/*Function to check whether the item being dragged is near its description box */
function isNearDescriptionBox(itemImage, descriptionBox){
    var ii = itemImage;
    var db = descriptionBox;
    if(ii.attrs.x > db.x - 20 && ii.attrs.x < db.x + 20 && ii.attrs.y > db.y - 20 && ii.attrs.y < db.y +20){
        return true;
    }else{
        return false;
    }
}

/* This function draws the game elements */
function drawGameElements(){
    /* Draw a line for the 'score bar'. */
    context.moveTo(0, 25);
    context.lineTo(1000, 25);
    context.stroke();

    /* Draw current level/ total levels on the left, and current score on the right. */
    context.font = "11pt Calibri"; /* Text font & size */
    context.strokeStyle = "black"; /* Font colour */
    context.strokeText(currentLevel + "/" + totalLevels, 10, 15);
    context.strokeText(currentScore, 750, 15);
}

function initStage(images){
    var stage = new Kinetic.Stage({
        container: "container",
        width: 1000,
        height: 500
    });
    var descriptionLayer = new Kinetic.Layer();
    //var imagesLayer = new Kinetic.Layer();
    var allImages = [];
    var currentScore = 0;

    var descriptionBoxes = {
        assetsDescriptionBox: {
            x: 70,
            y: 400
        },
        liabilitiesDescriptionBox: {
            x: 300,
            y: 400
        },
        incomeDescriptionBox: {
            x: 530,
            y: 400
        },
        expenditureDescriptionBox: {
            x: 760,
            y: 400
        },
    };

    /*Code to detect whether image has been dragged to correct description box */
    for (var key in sources){
        /*Anonymous function to induce scope */
        (function(){
            var privateKey = key;
            var imageSource = sources[key];

            /*Check if image has been dragged to the correct box, and add it to that box's
                array and remove from canvas if it has */
            canvasImage.on("dragend", function(){
                var descriptionBox = descriptionBoxes[privateKey];
                if(!canvasImage.inRightPlace && isNearDescriptionBox(itemImage, descriptionBox)){
                    context.remove(canvasImage);
                    /*Will need to add a line in here to add the image to the box's array */
                }
            })

        })();
    }

}

function drawImage(imageObj) {
    //var layer = new Kinetic.Layer();

    var canvasImage = new Kinetic.Image({
      image: imageObj,
      width: 50,
      height: 50,
      // puts the image in teh middle of the canvas
      x: stage.getWidth() / 2 - 50 / 2,
      y: stage.getHeight() / 2 - 50 / 2,
      draggable: true
    });

    // add cursor styling
    canvasImage.on('mouseover', function() {
      document.body.style.cursor = 'pointer';
    });
    canvasImage.on('mouseout', function() {
      document.body.style.cursor = 'default';
    });

    imagesLayer.add(canvasImage);
}

/*This code loads the images to the canvas when the browser window loads */
window.onload = function(){
    var sources = {};
        /*I've removed the code from here which simply adds the images in the hidden section of the html to the 'sources' JS array */


    loadImages(sources, drawImage);
    drawGameElements();
    drawDescriptionBoxes();
};
/*Try adding an if statement to display the text corresponding to whichever icon is selected */
if(document.body.innerText){
    var message = div.innerText;
} else {
    var message = div.innerHTML.replace(/\&lt;br\&gt;/gi,"\n").replace(/(&lt;([^&gt;]+)&gt;)/gi, "");
}

/*What I want to do here is, detect where on the canvas the mouse has been clicked, then if the click is
    on a part of the canvas that is displaying an image, get the ID belonging to that image, and display 
    the corresponding tip from the tips array in tips.js on the page below the canvas.*/
function isClickOnImage(event){
    var clickX = event.clientX;
    var clickY = event.clientY;

    var imageCheckIteration = 0;
    while(imageCheckIteration < sources.length){
        if((clickX > sources[imageCheckIteration].x && clickX < sources[imageCheckIteration].x + imageWidth) &&
        (clickY > sources[imageCheckIteration].y && clickY < sources[imageCheckIteration].y + imageHeight)){
            /*This is where I need to print the variable that holds the text I want to display, but I need to display its contents
            outside the canvas, in the <p></p> tags below. */
            document.getElementById("tipsParagraph").innerHTML = tips[imageCheckIteration];
        }
    }
}

</script>


</head>
<body>

<p><textarea>This is where the text will be displayed.</textarea></p>

<section hidden>
/*The code in this hidden section simply loads a number of images into the html, giving them an 'id', a 'src' and an 'alt' tag. */



</section>
</body>
</html>

我删除了用于将图像添加到HTML中的隐藏部分的代码,并将其从那里添加到JS数组中,只是为了减少显示的代码量。

编辑07/01/2013 @ 15:00

我编辑了代码以显示函数“isClickOnImage(event)”。当我编写这个函数时,我希望它将标记为“tipsParagraph”的

标签中的文本更改为与所单击图像对应的'tips'数组中的任何元素。但出于某种原因,当我点击画布上的图像时,我希望更新的段落没有任何反应。知道为什么吗?

1 个答案:

答案 0 :(得分:0)

您不需要使用KineticJS的一些本机实现,在这种情况下,您只需要它用于事件,只需将JQuery添加到项目中,并使用选择器来更改文本区域的文本。

  //this can easily be used in your KineticJS event function.
  $("textarea").val(message);

我建议你给你的文本区域一个id并使用$('#textAreaId')。val('hello world');设置你的信息