I want to be able to spawn a new image to the canvas at the click of a button, rather than having to manually edit the code.
I have the following HTML5/JavaScript code that allows images to be dragged and dropped between multiple canvases and it works perfectly for what I require.
What I am doing:
<canvas style="float: left" height="125" width="400" id="cvs1">[No canvas support]</canvas>
<canvas style="float: left; margin-left: 100px" height="125" width="400" id="cvs2">[No canvas support]</canvas>
<script src="http://www.rgraph.net/libraries/RGraph.common.core.js" ></script>
<script>
window.onload = function ()
{
var canvas1 = document.getElementById("cvs1");
var canvas2 = document.getElementById("cvs2");
var context1 = canvas1.getContext('2d');
var context2 = canvas2.getContext('2d');
var imageXY = {x: 5, y: 5};
/**
* This draws the image to the canvas
*/
function Draw ()
{
//Clear both canvas first
canvas1.width = canvas1.width
canvas2.width = canvas2.width
//Draw a red rectangle around the image
if (state && state.dragging) {
state.canvas.getContext('2d').strokeStyle = 'red';
state.canvas.getContext('2d').strokeRect(imageXY.x - 2.5,
imageXY.y - 2.5,
state.image.width + 5,
state.image.height + 5);
}
// Now draw the image
state.canvas.getContext('2d').drawImage(state.image, imageXY.x, imageXY.y);
}
canvas2.onclick =
canvas1.onclick = function (e)
{
if (state && state.dragging) {
state.dragging = false;
Draw();
return;
}
var mouseXY = RGraph.getMouseXY(e);
state.canvas = e.target;
if ( mouseXY[0] > imageXY.x
&& mouseXY[0] < (imageXY.x + state.image.width)
&& mouseXY[1] > imageXY.y
&& mouseXY[1] < (imageXY.y + state.image.height)) {
state.dragging = true;
state.originalMouseX = mouseXY[0];
state.originalMouseY = mouseXY[1];
state.offsetX = mouseXY[0] - imageXY.x;
state.offsetY = mouseXY[1] - imageXY.y;
}
}
canvas1.onmousemove =
canvas2.onmousemove = function (e)
{
if (state.dragging) {
state.canvas = e.target;
var mouseXY = RGraph.getMouseXY(e);
// Work how far the mouse has moved since the mousedon event was triggered
var diffX = mouseXY[0] - state.originalMouseX;
var diffY = mouseXY[1] - state.originalMouseY;
imageXY.x = state.originalMouseX + diffX - state.offsetX;
imageXY.y = state.originalMouseY + diffY - state.offsetY;
Draw();
e.stopPropagation();
}
}
/**
* Load the image on canvas1 initially and set the state up with some defaults
*/
state = {}
state.dragging = false;
state.canvas = document.getElementById("cvs1");
state.image = new Image();
state.image.src = 'http://www.rgraph.net/images/logo.png';
state.offsetX = 0;
state.offsetY = 0;
state.image.onload = function ()
{
Draw();
}
}
</script>
This can also be seen on this JS Fiddle (Note: you have to click the image before you can drag it)
The problem I am having:
I would like to add more images to the canvases so that any of the images can then be dragged and dropped between however many canvases I choose to create.
I can quite easily add more canvases to the page to drag and drop between, however when it comes to adding/spawning more images to the canvases I cannot get it to work.
The only way I can think of being able to do this is by repeating the Draw() function for every single image that gets added. That would mean if I wanted 30 images to be able to drag and drop between 10 different canvases for example, I would need to repeat the Draw() function 30 times. Surely that cannot be the best way to do this?
Unless I am missing something very obvious I cannot see another way of doing this?
Here’s how to configure your code to create multiple objects and click-drag between canvases.
Demo: http://jsfiddle.net/m1erickson/Bnb6A/
Code an object factory function that creates new draggable objects and put all new objects in an array.
Keep this information about each draggable object:
dragging (true/false) indicating if this object is currently being dragged
image: the image for this object
x,y: the current top,left position of this object
width,height: the size of this object
offsetX,offsetY: indicates where the mouse clicked relative to top,left of this object
draw: (a function) that allows this object to draw itself (surrounded by a red rect if it’s being dragged)
On click:
Get the mouse position
Clear both canvases
Iterate through the object array
If an object is being dragged, unset the dragging flag
If an object is now selected, set the dragging flag and set the offsetX,offsetY for the starting mouse position relative to this object.
Redraw all objects
On mousemove:
Get the mouse position
Clear both canvases
Iterate through the object array
If an object is being dragged, move it to the mouse position (setting x,y adjusted for the offset)
Redraw all objects
Code:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:20px; }
canvas{ border: 1px solid #808080; }
</style>
<script>
$(function(){
var canvas1 = document.getElementById("cvs1");
var canvas2 = document.getElementById("cvs2");
var contexts=[];
contexts.push(canvas1.getContext('2d'));
contexts.push(canvas2.getContext('2d'));
function clearAll(){
//Clear both canvas first
canvas1.width = canvas1.width
canvas2.width = canvas2.width
}
canvas1.onclick=function(e){ handleClick(e,1); };
canvas2.onclick=function(e){ handleClick(e,2); };
//
function handleClick(e,contextIndex){
e.stopPropagation();
var mouseX=parseInt(e.clientX-e.target.offsetLeft);
var mouseY=parseInt(e.clientY-e.target.offsetTop);
clearAll();
for(var i=0;i<states.length;i++){
var state=states[i];
if(state.dragging){
state.dragging=false;
state.draw();
continue;
}
if ( state.contextIndex==contextIndex
&& mouseX>state.x && mouseX<state.x+state.width
&& mouseY>state.y && mouseY<state.y+state.height)
{
state.dragging=true;
state.offsetX=mouseX-state.x;
state.offsetY=mouseY-state.y;
state.contextIndex=contextIndex;
}
state.draw();
}
}
canvas1.onmousemove = function(e){ handleMousemove(e,1); }
canvas2.onmousemove = function(e){ handleMousemove(e,2); }
//
function handleMousemove(e,contextIndex){
e.stopPropagation();
var mouseX=parseInt(e.clientX-e.target.offsetLeft);
var mouseY=parseInt(e.clientY-e.target.offsetTop);
clearAll();
for(var i=0;i<states.length;i++){
var state=states[i];
if (state.dragging) {
state.x = mouseX-state.offsetX;
state.y = mouseY-state.offsetY;
state.contextIndex=contextIndex;
}
state.draw();
}
}
var states=[];
var img=new Image();
img.onload=function(){
states.push(addState(0,0,img));
}
img.src="http://www.rgraph.net/images/logo.png";
function addState(x,y,image){
state = {}
state.dragging=false;
state.contextIndex=1;
state.image=image;
state.x=x;
state.y=y;
state.width=image.width;
state.height=image.height;
state.offsetX=0;
state.offsetY=0;
state.draw=function(){
var context=contexts[this.contextIndex-1];
if (this.dragging) {
context.strokeStyle = 'red';
context.strokeRect(this.x,this.y,this.width+5,this.height+5)
}
context.drawImage(this.image,this.x,this.y);
}
state.draw();
return(state);
}
$("#more").click(function(){
states.push(addState(states.length*100,0,img));
});
}); // end $(function(){});
</script>
</head>
<body>
<button id="more">Add Image</button><br>
<canvas height="125" width="300" id="cvs1">[No canvas support]</canvas><br>
<canvas height="125" width="300" id="cvs2">[No canvas support]</canvas>
</body>
</html>
Related
I have an HTML page with 2 canvases side-by-side. The left one has a clickable upper region. The right one is where all the drawing takes place. I want the user to click the region on the left, which will load a new image on the right, and replace the one that is already there, but I have to click twice for the new image to show up. Why is this? See code.
THE HTML
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<style>
#centerAll {
margin-left:auto;
margin-right:auto;
width:1300px;
}
</style>
</head>
<body>
<div id="centerAll">
<canvas id="TheLeftCanvas" width="300" height="500"
style="border:2px solid #999999;"></canvas>
<canvas id="TheRightCanvas" width="900" height="500"
style="border:2px solid #999999;"></canvas>
<script type="text/javascript" src="whyClickTwiceForImage.js">
</script>
</div>
</body>
</html>
AND THE JAVASCRIPT
window.addEventListener("load", eventWindowLoaded, false);
function eventWindowLoaded () {
canvasApp();
}
function canvasApp() {
var rightCanvas = document.getElementById("TheRightCanvas");
//THE EMPTY CANVAS ON THE RIGHT, WHICH DRAWS THINGS
var rightCtx = rightCanvas.getContext("2d");
var leftCanvas = document.getElementById("TheLeftCanvas");
//THE EMPTY CANVAS ON THE LEFT, WHICH HANDLES USER CLICKS
var leftCtx = leftCanvas.getContext("2d");
var currentMouseXcoor = 0;
var currentMouseYcoor = 0;
var imagesToLoad = 0; //USED TO PRE-LOAD SOME OTHER VISUALS, BEFORE THE USER STARTS
var imagesLoaded = 0;
var picturesTheUserCanChoose = ["pic01.png", "pic02.png",
"pic03.png", "pic04.png", "pic05.png"];
var nameOfPicTheUserChose = "pic05.png"; //LET'S JUST SAY "pic05.png" IS A PLACEHOLDER PICTURE... TO START OFF
var legitMouseClick = 0; //DID THE USER CLICK IN THE UPPER REGION OF THE LEFT CANVAS?
var loaded = function(){ // "LOADED" AND "LOAD IMAGE" ARE USED TO PRELOAD ALL THOSE OTHER VISUALS BEFORE THE USER STARTS
imagesLoaded += 1;
if(imagesLoaded === imagesToLoad){
imagesToLoad = 0;
imagesLoaded = 0;
drawScreen(); // OK... ALL LOADED.... SO DRAW THE SCREEN
}
}
var loadImage = function(url){ // "LOADED" AND "LOAD IMAGE" ARE USED TO PRELOAD ALL THOSE OTHER PICS BEFORE THE USER STARTS
var image = new Image();
image.addEventListener("load",loaded);
imagesToLoad += 1; // ADD THE NUMBER TO THE IMAGES NEEDED TO BE LOADED
image.src = url;
return image; // ...AND RETURN THE IMAGE
}
//--------------------------------------------------------------
leftCanvas.addEventListener('mouseup', function(evt) { var
mousePos = doMouseUp(leftCanvas, evt);
currentMouseXcoor = mousePos.x; currentMouseYcoor =
mousePos.y; processMousePosition();}, false);
//--------------------------------------------------------------
function drawScreen(){
clearScreen();
rightCtx.drawImage(picture1,0,0,100,100);
}
//THIS FUNCTION PRESUMABLY LOADS IMAGES ON-THE-FLY... BUT WHY DOES THE LEFT CANVAS REGION HAVE TO BE CLICKED TWICE FOR THE NEW IMAGE TO SHOW?
function processMousePosition() {
if(currentMouseYcoor >= 0 && currentMouseYcoor <= 50){
//IF THE CLICK IS IN THE UPPER REGION OF THE LEFT CANVAS
nameOfPicTheUserChose = picturesTheUserCanChoose[0];
//WE'LL SAY THE USER CHOSE THE VERY FIRST PIC IN THE ARRAY
picture1.src = ("picturesFolder/"+ nameOfPicTheUserChose);
picture1.onload = legitMouseClick = 1;//I JUST MADE UP FOR SOMETHING TO HAPPEN WHEN THE NEW PICTURE LOADS???
alert(nameOfPicTheUserChose); // THE ALERT CORRECTLY SHOWS THE NAME OF THE FIRST PIC IN THE ARRAY
}
drawScreen();
}
function doMouseUp(leftCanvas, evt){
var rect = leftCanvas.getBoundingClientRect();
return { x: evt.clientX - rect.left, y: evt.clientY - rect.top};
}
function clearScreen(){
rightCtx.clearRect(0, 0, 900, 500);
leftCtx.clearRect(0, 0, 300, 500);
}
//var someOtherVisual1 =
//loadImage("backgroundArtFolder/someOtherVisual1.jpg");
//var someOtherVisual2 =
//loadImage("backgroundArtFolder/someOtherVisual2.png");
//var someOtherVisual3 =
//loadImage("backgroundArtFolder/someOtherVisual3.png");
//var someOtherVisual4 =
//loadImage("backgroundArtFolder/someOtherVisual4.png");
//var someOtherVisual5 =
//loadImage("backgroundArtFolder/someOtherVisual5.png");
var picture1 = loadImage("picturesFolder/pic05.png");
//LET'S JUST PRELOAD "pic05.png" AS A PLACEHOLDER... TO START OFF
}
You can change the image load on click in js file picture1.src = ("picturesFolder/"+ nameOfPicTheUserChose); to picture1 = loadImage("picturesFolder/"+nameOfPicTheUserChose); and picture1.onload = legitMouseClick = 1; to 'legitMouseClick = 1'
I'm having trouble creating a click event for my Javascript canvas game. So far I have been following a tutorial, however the way you interact with the game is through mouse hover. I would like to change it so that instead of hovering over objects in the canvas to interact, I instead use a mouse click.
The following is the code I use to detect the mouse hover.
getDistanceBetweenEntity = function (entity1,entity2) //return distance
{
var vx = entity1.x - entity2.x;
var vy = entity1.y - entity2.y;
return Math.sqrt(vx*vx+vy*vy);
}
testCollisionEntity = function (entity1,entity2) //return if colliding
{
var distance = getDistanceBetweenEntity(entity1,entity2);
return distance < 50;
}
I then use this in a loop to interact with it.
var isColliding = testCollisionEntity(player,nounList[key]);
if(isColliding)
{
delete nounList[key];
player.score = player.score + 10;
}
Below is a complete copy of my game at its current state.
<canvas id="ctx" width="500" height="500" style="border:1px solid #000000;"></canvas>
<script>
var ctx = document.getElementById("ctx").getContext("2d");
ctx.font = '30px Arial';
//Setting the height of my canvas
var HEIGHT = 500;
var WIDTH = 500;
//Player class
var player =
{
x:50,
spdX:30,
y:40,
spdY:5,
name:'P',
score:0,
};
//Creating arrays
var nounList ={};
var adjectivesList ={};
var verbsList ={};
getDistanceBetweenEntity = function (entity1,entity2) //return distance
{
var vx = entity1.x - entity2.x;
var vy = entity1.y - entity2.y;
return Math.sqrt(vx*vx+vy*vy);
}
testCollisionEntity = function (entity1,entity2) //return if colliding
{
var distance = getDistanceBetweenEntity(entity1,entity2);
return distance < 50;
}
Nouns = function (id,x,y,name)
{
var noun =
{
x:x,
y:y,
name:name,
id:id,
};
nounList[id] = noun;
}
Adjectives = function (id,x,y,name)
{
var adjective =
{
x:x,
y:y,
name:name,
id:id,
};
adjectivesList[id] = adjective;
}
Verbs = function (id,x,y,name)
{
var verb =
{
x:x,
y:y,
name:name,
id:id,
};
verbsList[id] = verb;
}
document.onmousemove = function(mouse)
{
var mouseX = mouse.clientX;
var mouseY = mouse.clientY;
player.x = mouseX;
player.y = mouseY;
}
updateEntity = function (something)
{
updateEntityPosition(something);
drawEntity(something);
}
updateEntityPosition = function(something)
{
}
drawEntity = function(something)
{
ctx.fillText(something.name,something.x,something.y);
}
update = function ()
{
ctx.clearRect(0,0,WIDTH,HEIGHT);
drawEntity(player);
ctx.fillText("Score: " + player.score,0,30);
for(var key in nounList)
{
updateEntity(nounList[key]);
var isColliding = testCollisionEntity(player,nounList[key]);
if(isColliding)
{
delete nounList[key];
player.score = player.score + 10;
}
}
for(var key in adjectivesList)
{
updateEntity(adjectivesList[key])
var isColliding = testCollisionEntity(player,adjectivesList[key]);
if(isColliding)
{
delete adjectivesList[key];
player.score = player.score - 1;
}
}
for(var key in verbsList)
{
updateEntity(verbsList[key])
var isColliding = testCollisionEntity(player,verbsList[key]);
if(isColliding)
{
delete verbsList[key];
player.score = player.score - 1;
}
}
if(player.score >= 46)
{
ctx.clearRect(0,0,WIDTH,HEIGHT);
ctx.fillText("Congratulations! You win!",50,250);
ctx.fillText("Refresh the page to play again.",50,300);
}
}
Nouns('N1',150,350,'Tea');
Nouns('N2',400,450,'Park');
Nouns('N3',250,150,'Knee');
Nouns('N4',50,450,'Wall');
Nouns('N5',410,50,'Hand');
Adjectives('A1',50,100,'Broken');
Adjectives('A2',410,300,'Noisy');
Verbs('V1',50,250,'Smell');
Verbs('V2',410,200,'Walk');
setInterval(update,40);
To summarize all I want to do is change it so that instead of mousing over words to delete them you have to click.
(Apologies for not using correct terminology in places, my programming knowledge is quite limited.)
You can have your canvas listen for mouse clicks on itself like this:
// get a reference to the canvas element
var canvas=document.getElementById('ctx');
// tell canvas to listen for clicks and call "handleMouseClick"
canvas.onclick=handleMouseClick;
In the click handler, you'll need to know the position of your canvas relative to the viewport. That's because the browser always reports mouse coordinates relative to the viewport. You can get the canvas position relative to the viewport like this:
// get the bounding box of the canvas
var BB=canvas.getBoundingClientRect();
// get the left X position of the canvas relative to the viewport
var BBoffsetX=BB.left;
// get the top Y position of the canvas relative to the viewport
var BBoffsetY=BB.top;
So your mouseClickHandler might look like this:
// this function will be called when the user clicks
// the mouse in the canvas
function handleMouseClick(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// get the canvas postion relative to the viewport
var BB=canvas.getBoundingClientRect();
var BBoffsetX=BB.left;
var BBoffsetY=BB.top;
// calculate the mouse position
var mouseX=e.clientX-BBoffsetX;
var mouseY=e.clientY-BBoffsetY;
// report the mouse position using the h4
$position.innerHTML='Click at '+parseInt(mouseX)+' / '+parseInt(mouseY);
}
If your game doesn't let the window scroll or resize then the canvas postion won't change relative to the viewport. Then, for better performance, you can move the 3 lines relating to getting the canvas position relative to the viewport to the top of your app.
// If the browser window won't be scrolled or resized then
// get the canvas postion relative to the viewport
// once at the top of your app
var BB=canvas.getBoundingClientRect();
var BBoffsetX=BB.left;
var BBoffsetY=BB.top;
function handleMouseClick(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// calculate the mouse position
var mouseX=e.clientX-BBoffsetX;
var mouseY=e.clientY-BBoffsetY;
// report the mouse position using the h4
$position.innerHTML='Click at '+parseInt(mouseX)+' / '+parseInt(mouseY);
}
I am using fabric.js to handle two canvases. I also set two canvases to compare two images in a same page.
like this:
<canvas id="firstImg" width="843" height="1200"></canvas>
<canvas id="secondImg" width="843" height="1200"></canvas>
I want to move a image when i drag the other image in the other canvas.
I mean when I drag a image to change the position in firstImg canvas, I also move the other image in secondImg canvas at same time.
Is it possible??
Were you looking for something like this?
I've made a simple function to draw an image on a canavs. When you drag the image you simply call the function for both canvas.
http://jsfiddle.net/Niddro/96rdnv3L/
var canvasOne = document.getElementById("canvasOne");
var ctxOne = canvasOne.getContext("2d");
var canvasTwo = document.getElementById("canvasTwo");
var ctxTwo = canvasTwo.getContext("2d");
var mouseX=0;
var mouseY=0;
var imageX=0;
var imageY=0;
var drag = false;
canvasOne.addEventListener("mousedown", function(){drag=true;}, false);
canvasOne.addEventListener("mouseup", function(){drag=false;}, false);
canvasOne.addEventListener("mousemove", moveImage, false);
var myImage = new Image();
myImage.src = "http://home.niddro.com/HTML5/flxprt/img/logo_orange_small.png";
function moveImage(event) {
if (drag) {
var x = new Number();
var y = new Number();
var canvas = document.getElementById("canvasOne");
if (event.x != undefined && event.y != undefined)
{
x = event.x;
y = event.y;
}
else // Firefox method to get the position
{
x = event.clientX + document.body.scrollLeft +
document.documentElement.scrollLeft;
y = event.clientY + document.body.scrollTop +
document.documentElement.scrollTop;
}
x -= canvas.offsetLeft;
y -= canvas.offsetTop;
var deltaX = mouseX-x;
var deltaY = mouseY-y;
drawImage(imageX-deltaX,imageY-deltaY,ctxOne,canvasOne,myImage);
drawImage(imageX-deltaX,imageY-deltaY,ctxTwo,canvasTwo,myImage);
}
}
drawImage(imageX,imageY,ctxOne,canvasOne,myImage);
drawImage(imageX,imageY,ctxTwo,canvasTwo,myImage);
function drawImage(x,y,ctx,canvas,img) {
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(img,x,y);
}
canvas {
border: 1px solid black;
}
<canvas id="canvasOne" width="500" height="300"></canvas><br />
<canvas id="canvasTwo" width="500" height="300"></canvas>
I have have a problem I am hoping someone will be able to help with...
On my application I require the facility to be able to drag and drop images between multiple canvases.
There are a few pre-made examples of dragging and dropping between multiple canvases avaliable online, and I have found the perfect example for my needs courtesy of 'Richard Heyes' of RGraph which you can see here (NOTE: you must click the image before you can start dragging it).
As you can see, on his website this drag and drop feature works perfectly, however when I transfer the javascript, html and css to my application the ability to drag and drop the image does not work.
What I am doing:
<!DOCTYPE html>
<html>
<body>
<h1>My First Heading</h1>
<p>My first paragraph.</p>
<style type="text/css">
canvas {
border: 1px solid #808080;
}
</style>
<canvas style="float: left" height="125" width="400" id="cvs1">[No canvas support]</canvas>
<canvas style="float: left; margin-left: 100px" height="125" width="400" id="cvs2">[No canvas support]</canvas>
<script>
window.onload = function ()
{
var canvas1 = document.getElementById("cvs1");
var canvas2 = document.getElementById("cvs2");
var context1 = canvas1.getContext('2d');
var context2 = canvas2.getContext('2d');
var imageXY = {x: 5, y: 5};
/**
* This draws the image to the canvas
*/
function Draw ()
{
//Clear both canvas first
canvas1.width = canvas1.width
canvas2.width = canvas2.width
//Draw a red rectangle around the image
if (state && state.dragging) {
state.canvas.getContext('2d').strokeStyle = 'red';
state.canvas.getContext('2d').strokeRect(imageXY.x - 2.5,
imageXY.y - 2.5,
state.image.width + 5,
state.image.height + 5);
}
// Now draw the image
state.canvas.getContext('2d').drawImage(state.image, imageXY.x, imageXY.y);
}
canvas2.onclick =
canvas1.onclick = function (e)
{
if (state && state.dragging) {
state.dragging = false;
Draw();
return;
}
var mouseXY = RGraph.getMouseXY(e);
state.canvas = e.target;
if ( mouseXY[0] > imageXY.x
&& mouseXY[0] < (imageXY.x + state.image.width)
&& mouseXY[1] > imageXY.y
&& mouseXY[1] < (imageXY.y + state.image.height)) {
state.dragging = true;
state.originalMouseX = mouseXY[0];
state.originalMouseY = mouseXY[1];
state.offsetX = mouseXY[0] - imageXY.x;
state.offsetY = mouseXY[1] - imageXY.y;
}
}
canvas1.onmousemove =
canvas2.onmousemove = function (e)
{
if (state.dragging) {
state.canvas = e.target;
var mouseXY = RGraph.getMouseXY(e);
// Work how far the mouse has moved since the mousedon event was triggered
var diffX = mouseXY[0] - state.originalMouseX;
var diffY = mouseXY[1] - state.originalMouseY;
imageXY.x = state.originalMouseX + diffX - state.offsetX;
imageXY.y = state.originalMouseY + diffY - state.offsetY;
Draw();
e.stopPropagation();
}
}
/**
* Load the image on canvas1 initially and set the state up with some defaults
*/
state = {}
state.dragging = false;
state.canvas = document.getElementById("cvs1");
state.image = new Image();
state.image.src = 'http://www.rgraph.net/images/logo.png';
state.offsetX = 0;
state.offsetY = 0;
state.image.onload = function ()
{
Draw();
}
}
</script>
</body>
</html>
<!-- CODE COURTESY OF RICHARD HEYES OF RGRAPH
http://www.rgraph.net/blog/2013/january/an-example-of-html5-canvas-drag-n-drop.html -->
I have created the same thing on this JSFiddle but the dragging and dropping still does not work.
I am new to html5 and javascript so I am sure it must be something very simple I am overlooking, but I cannot work out what it is.
Your help with this would be much appreciated, thank you very much.
I have inserted your JavaScript code between tags <script> and </script> and move it from JavaScript to HTML and I have added new script link from the example page:
<script src="http://www.rgraph.net/libraries/RGraph.common.core.js" ></script>
JSFiddle - working example
So I think, that you must download and insert core files of RGraph to your code from this page.
I have written a javascript that is supposed to scroll pictures across the screen using canvas. I am unable to get this to work and would appreciate any help. I was able to get this to work using one picture and no Array but I want to be able to use an Array and load pictures one after another with a small space between them.
Here's a JSFiddle with my code.
var img = new Image[];
img[0] = new Image;
img[0].src = 'Images/Juniors.jpg';
img[1] = new Image;
img[1].src = 'Images/minis.jpg';
img[2] = new Image;
img[2].src = 'Images/senior.jpg';
var CanvasXSize = 1040;
var CanvasYSize = 240;
var speed = 40; //lower is faster
var scale = 1.05;
var y = -4.5; //vertical offset
var dx = 0.75;
var imgW;
var imgH;
var x = 0;
var clearX;
var clearY;
var ctx;
img.onload = function() {
imgW = img.width*scale;
imgH = img.height*scale;
if (imgW > CanvasXSize) { x = CanvasXSize-imgW; } // image larger than canvas
if (imgW > CanvasXSize) { clearX = imgW; } // image larger than canvas
else { clearX = CanvasXSize; }
if (imgH > CanvasYSize) { clearY = imgH; } // image larger than canvas
else { clearY = CanvasYSize; }
ctx = document.getElementById('canvas').getContext('2d'); //Get Canvas Element
}
function draw() {
//Clear Canvas
ctx.clearRect(0,0,clearX,clearY);
//If image is <= Canvas Size
if (imgW <= CanvasXSize) {
//reset, start from beginning
if (x > (CanvasXSize)) { x = 0; }
//draw aditional image
if (x > (CanvasXSize-imgW)) {
ctx.drawImage(img, x-CanvasXSize+1, y, imgW, imgH);
}
}
//If image is > Canvas Size
else {
//reset, start from beginning
if (x > (CanvasXSize)) { x = CanvasXSize-imgW; }
//draw aditional image
if (x > (CanvasXSize-imgW)) { ctx.drawImage(img[0],x-imgW+1,y,imgW,imgH); }
}
for(i = 0; i < img.length; i++) {
ctx.drawImage(img[i],x,y,imgW,imgH);
//amount to move
x += dx;
}
}
To have multiple images loaded when you need them, you shoud use image preloader code:
var imgs=[];
var imagesOK=0;
var imageURLs=[];
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house1.jpg");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house2.jpg");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house3.jpg");
loadAllImages();
function loadAllImages(){
for (var i = 0; i < imageURLs.length; i++) {
// put each image in the imgs array
var img = new Image();
imgs.push(img);
// after each image has been loaded, execute this function
img.onload = function(){
// add 1 to imagesOK
imagesOK++;
// if imagesOK equals the # of images in imgs
// we have successfully preloaded all images
// into imgs[]
if (imagesOK>=imageURLs.length ) {
// all loaded--start drawing the images
drawImages();
}
}; // end onload
img.src = imageURLs[i];
} // end for
}
At this point the images are all loaded, so draw the images
You can use context.translate and context.rotate to tilt your images.
What you do is translate (move) to the center of the image you want to rotate. Then do the rotation from that centerpoint. That way the image will rotate around its center. The rotate function takes a radian angle so you can translate degrees to radians like this: 30 degrees = 30 * Math.PI/180 radians
ctx.translate( left+width/2, topp+height/2 )
ctx.rotate( degrees*Math.PI/180 );
Then you draw your image offset by its centerpoint (remember you’re rotating around that centerpoint)
ctx.drawImage(img,0,0,img.width,img.height,-width/2,-height/2,width,height);
It’s a lot to wrap your head around so here’s example code and a Fiddle: http://jsfiddle.net/m1erickson/t49kU/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var imgs=[];
var imagesOK=0;
var imageURLs=[];
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house1.jpg");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house2.jpg");
imageURLs.push("https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house3.jpg");
loadAllImages();
function loadAllImages(){
for (var i = 0; i < imageURLs.length; i++) {
var img = new Image();
imgs.push(img);
img.onload = function(){
imagesOK++;
if (imagesOK>=imageURLs.length ) {
drawImages();
}
}; // end onload
img.src = imageURLs[i];
} // end for
}
ctx.lineWidth=2;
var left=25;
var topp=30;
var width=100;
var height=100;
var rotations=[ -10, 0, 10 ];
function drawImages(){
for(var i=0;i<imgs.length;i++){
var img=imgs[i];
ctx.save()
ctx.beginPath();
ctx.translate( left+width/2, topp+height/2 )
ctx.rotate(rotations[i]*Math.PI/180);
ctx.drawImage(img,0,0,img.width,img.height,-width/2,-height/2,width,height);
ctx.rect(-width/2,-height/2,width,height);
ctx.stroke();
ctx.restore();
left+=125;
}
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=400 height=200></canvas>
</body>
</html>