Note that there are some explanatory texts on larger screens.

plurals
  1. POhtml5 canvas drag and drop images
    primarykey
    data
    text
    <p>I have a web page with an HTML5 canvas that's displaying a number of images on the canvas using JavaScript. I also have four 'description areas' on the canvas, which have been drawn using the following JavaScript function:</p> <pre><code>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(); } } </code></pre> <p>I want to add drag and drop functionality to the images that I've displayed on the canvas, so that the user can drag each one onto its corresponding description area. When each image is dragged onto its corresponding description area, it should then disappear from the canvas. If an image is dragged to the wrong description area, the image should remain on the canvas, and a message should be displayed stating that the user has made an incorrect selection.</p> <p>I'm currently working on adding the drag and drop functionality to the images, but I'm having a bit of trouble getting this working.</p> <p>I've found an example of what I'm trying to do online, and am trying to follow this, but obviously to make it work in the context I'm using it. The example I'm following is at: <a href="http://html5demos.com/drag" rel="nofollow">http://html5demos.com/drag</a></p> <p>I've viewed the source from this example, and am trying to reuse the code to add the drag and drop functionality to the images on my canvas. This is what I've got so far:</p> <pre><code>&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;script src = "kinetic.js" type = "text/javascript"&gt;&lt;/script&gt; &lt;title&gt;Home&lt;/title&gt; &lt;script src = "drawLevelOneElements.js" type = "text/javascript"&gt;&lt;/script&gt; &lt;script src = "layers&amp;analytics.js" type = "text/javascript"&gt;&lt;/script&gt; &lt;script src = "startGameDrawGameElementsDrawStartButton.js" type = "text/javascript"&gt;&lt;/script&gt; &lt;script src = "interaction.js" type = "text/javascript"&gt;&lt;/script&gt; &lt;script src = "dragAndDrop.js" type = "text/javascript"&gt;&lt;/script&gt; &lt;script src="http://www.html5canvastutorials.com/libraries/kinetic-v4.0.5.js"&gt;&lt;/script&gt; &lt;script src="http://www.html5canvastutorials.com/libraries/kinetic-v4.1.2.js"&gt;&lt;/script&gt; &lt;script src="draggable.js"&gt;&lt;/script&gt; &lt;/head&gt; &lt;body onLoad="startGame()"&gt; &lt;section hidden&gt; &lt;img id="StartButton" src="StartButton.png" alt="Start Button" width="179" height="180" href="javascript:drawLevelOneElements();"/&gt; &lt;img id="building" src="images/assets/building.png" alt="Asset" draggable="true" ondragstart="drag(event)"/&gt; &lt;img id="chair" src="images/assets/chair.gif" alt="Asset"/&gt; &lt;img id="drink" src = "images/assets/drink.jpg" alt="Asset"/&gt; &lt;img id="food" src = "images/assets/food.gif" alt="Asset"/&gt; &lt;img id="fridge" src = "images/assets/fridge.png" alt="Asset"/&gt; &lt;img id="land" src = "images/assets/land.jpg" alt="Asset"/&gt; &lt;img id="money" src = "images/assets/money.jpg" alt="Asset"/&gt; &lt;img id="oven" src = "images/assets/oven.jpg" alt="Asset"/&gt; &lt;img id="table" src = "images/assets/table.gif" alt="Asset"/&gt; &lt;img id="van" src = "images/assets/van.jpg" alt="Asset"/&gt; &lt;img id="burger" src = "images/expenses/direct/burger.png" alt="Direct Expense"/&gt; &lt;img id="chips" src = "images/expenses/direct/chips.png" alt="Direct Expense"/&gt; &lt;img id="drink" src = "images/expenses/direct/drink.jpg" alt="Direct Expense"/&gt; &lt;img id="franchiseFee" src = "images/expenses/direct/franchiseFee.jpg" alt="Direct Expense"/&gt; &lt;img id="wages" src = "images/expenses/direct/wages.jpg" alt="Direct Expense"/&gt; &lt;img id="admin" src = "images/expenses/indirect/admin.jpg" alt="Indirect Expense"/&gt; &lt;img id="cleaners" src = "images/expenses/indirect/cleaners.gif" alt="Indirect Expense"/&gt; &lt;img id="electricity" src = "images/expenses/indirect/electricity.gif" alt="Indirect Expense"/&gt; &lt;img id="insurance" src = "images/expenses/indirect/insurance.jpg" alt="Indirect Expense"/&gt; &lt;img id="manager" src = "images/expenses/indirect/manager.jpg" alt="Indirect Expense"/&gt; &lt;img id="rates" src = "images/expenses/indirect/rates.jpg" alt="Indirect Expense"/&gt; &lt;img id="training" src = "images/expenses/indirect/training.gif" alt="Indirect Expense"/&gt; &lt;img id="water" src = "images/expenses/indirect/water.gif" alt="Indirect Expense"/&gt; &lt;img id="burger" src = "images/income/burger.png" alt="Income"/&gt; &lt;img id="chips" src = "images/income/chips.png" alt="Income"/&gt; &lt;img id="drink" src = "images/income/drink.jpg" alt="Income"/&gt; &lt;img id="creditors" src = "images/liabilities/creditors.gif" alt="Liability"/&gt; &lt;img id="electricity" src = "images/liabilities/electricity.png" alt="Liability"/&gt; &lt;img id="food" src = "images/liabilities/food.jpg" alt="Liability"/&gt; &lt;img id="hirePurchase" src = "images/liabilities/hirePurchase.jpg" alt="Liability"/&gt; &lt;img id="loan" src = "images/liabilities/loan.png" alt="Liability"/&gt; &lt;img id="overdraft" src = "images/liabilities/overdraft.jpg" alt="Liability"/&gt; &lt;img id="payeTax" src = "images/liabilities/payeTax.jpg" alt="Liability"/&gt; &lt;img id="tax" src = "images/liabilities/tax.jpg" alt="Liability"/&gt; This code has been added based on example at: http://html5demos.com/drag#view-source Code as far as the end of the section. &lt;div id="bin"&gt;&lt;/div&gt; &lt;ul&gt; &lt;li&gt;&lt;a id="building" href="#"&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" id="chair"&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" id="drink"&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" id="food"&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" id="fridge"&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" id="land"&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" id="money"&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" id="oven"&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" id="table"&gt;&lt;/li&gt; &lt;li&gt;&lt;a href="#" id="van"&gt;&lt;/li&gt; &lt;/ul&gt; &lt;script&gt; var drop = ['Correct!', 'Incorrect!']; var feedback = document.createElement('p'); var msie = /*@cc_on!@*/0; feedback.style.opacity = 1; var imagesToMakeDraggable = document.querySelectorAll('li &gt; a'), el = null; for (var i = 0; i &lt; imagesToMakeDraggable.length; i++){ el = imagesToMakeDraggable[i]; el.setAttribute('draggable', 'true'); addEvent(el, 'dragstart', function(e){ e.dataTransfer.effectAllowed = 'copy'; /*Only dropEffect='copy' will be dropable */ e.dataTransfer.setData('Image', this.id); /*Required otherwise, doesn't work */ }); } var bin = document.querySelector('#bin'); addEvent(bin, 'dragover', function(e){ if(e.preventDefault) e.preventDefault(); /*Allows us to drop */ this.className = 'over'; e.dataTransfer.dropEffect = 'copy'; return false; }); /*To get IE to work */ addEvent(bin, 'dragenter', function(e){ this.className = 'over'; return false; }); addEvent(bin, 'dragleave', function(){ this.className = ''; }); addEvent(bin, 'drop', function(e){ if(e.stopPropagation) e.stopPropagation(); /*Stops the browser from redirecting... why? */ var el = document.getElementById(e.dataTransfer.getData('Image')); el.parentNode.removeChild(el); /*Stupid nom text &amp; fade effect */ bin.className = ''; feedback.innerHTML = drop[parseInt(Math.random() * drop.length)]; var f = feedback.cloneNode(true); bin.appendChild(f); setTimeout(function(){ var t = setInterval(function(){ if(f.style.opacity &lt;= 0){ if(msie) { /*Don't bother with the animation */ f.style.display = 'none'; } clearInterval(t); } else { f.style.opacity -= 0.1; } }, 50); }, 250); return false; }); &lt;/script&gt; &lt;/section&gt; &lt;h1&gt;Home&lt;/h1&gt; &lt;p&gt;The purpose of this website is to teach users the basic principles of running a business by playing the game below. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt; &lt;canvas id="gameCanvas" width="1000" height="500" style="border:1px solid"&gt; Your browser does not support the canvas element. &lt;/canvas&gt; &lt;br /&gt;&lt;br /&gt; &lt;p&gt;Use this paragraph to enter text that provides the user with instructions for how to play the game. &lt;br /&gt; Update the instructions so that they're appropriate to whatever level the user is currently playing.&lt;/p&gt; &lt;script src = "variables&amp;preloadingImages.js" type = "text/javascript"&gt;&lt;/script&gt; &lt;/body&gt; </code></pre> <p></p> <p>I have quite a large number of images that I'm drawing to the canvas, so I've only tried to add the drag and drop functionality to the first group of images to start off with.</p> <p>However, when I now view my page in the browser, having added the code below the line </p> <blockquote> <p>This code has been added based on example at: <a href="http://html5demos.com/drag#view-source" rel="nofollow">http://html5demos.com/drag#view-source</a> Code as far as the end of the section.</p> </blockquote> <p>based on the example found at the webpage I previously mentioned, for some reason, the browser seems to think that the whole page is now a hyperlink (i.e. the cursor is a 'hand' rather than a 'pointer' when hovering over almost anywhere on the entire page, and all of the text and the canvas border have become purple and underlined, as if it was all a hyperlink.</p> <p>If I click anywhere on the page where the cursor has become a 'hand', than all of the text and the canvas border change from purple to red, such as when a hyperlink is clicked.</p> <p>Clicking the 'start button' that's displayed on the canvas calls the function 'drawLevelOneElements()', which draws all of the images and the description areas to the canvas, however it is still not possible to drag and drop and of the images around the canvas.</p> <p>Can anyone see what I'm doing wrong here, and what I need to do to enable the images to be dragged and dropped around the canvas?</p> <p>The code for my 'drawLevelOneImages()' function is:</p> <pre><code>/* This function draws the elements for level 1. */ 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 &amp; y coordinates of the image that will be drawn. the x &amp; 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); var imageWidth = 50; var imageHeight = 50; /*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 &lt; allImagesArray.length){ //var randomPositionX = Math.floor(Math.random()*10); //var randomPositionY = Math.floor(Math.random()*10); context.drawImage(allImagesArray[arrayIteration], imageX, imageY, imageWidth, imageHeight); /*Declare variables for image height and width, so it can be accessed elsewhere */ //allImagesArray[arrayIteration].setDraggable = "true"; allImagesArray[arrayIteration].setAttribute('draggable', 'true'); console.log(arrayIteration); /*Display the current array position that's being drawn */ arrayIteration = arrayIteration+1; /*Now try changing the values of imageX &amp; 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)); */ imageX = Math.floor(Math.random()*950); imageY = Math.floor(Math.random()*350); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload