Drag & drop image on canvas image - html

I want to drag & drop text above image. For that I am using canvas. I am using this code
<img id="scream" src="http://127.0.0.1/demo/images.jpg" alt="The Scream" style="display:none;" width="220" height="277"><p>Canvas:</p>
<canvas id="canvas" width="300" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
var c=document.getElementById("canvas");
var ctx1=c.getContext("2d");
var img=document.getElementById("scream");
ctx1.drawImage(img,10,10);
var canvas;
var ctx;
var x = 75;
var y = 50;
var dx = 5;
var dy = 3;
var WIDTH = 400;
var HEIGHT = 300;
var dragok = false,
text = "Hey there im moving!",
textLength = (text.length * 14)/2;
function rect(x,y,w,h) {
ctx.font = "14px Arial";
ctx.strokeText("Hey there im a moving!!", x, y);
}
function clear() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
}
function init() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
return setInterval(draw, 10);
}
function draw() {
clear();
ctx.fillStyle = "#FAF7F8";
ctx.fillStyle = "#444444";
rect(x - 15, y + 15, textLength, 30);
}
function myMove(e){
if (dragok){
x = e.pageX - canvas.offsetLeft;
y = e.pageY - canvas.offsetTop;
}
}
function myDown(e){
if (e.pageX < x + textLength + canvas.offsetLeft && e.pageX > x - textLength + canvas.offsetLeft && e.pageY < y + 15 + canvas.offsetTop &&
e.pageY > y -15 + canvas.offsetTop){
x = e.pageX - canvas.offsetLeft;
y = e.pageY - canvas.offsetTop;
dragok = true;
canvas.onmousemove = myMove;
}
}
function myUp(){
dragok = false;
canvas.onmousemove = null;
}
init();
canvas.onmousedown = myDown;
canvas.onmouseup = myUp;
I either able to show image or drag & drop text but I want both, please help me where I am wrong. You can check here:- http://jsfiddle.net/FWdSv/11/

When you're clearing the canvas, you're also clearing your image.
So the easy fix is to redraw the image in your draw function:
function draw() {
clear();
ctx.drawImage(img,0,0);
ctx.fillStyle = "#FAF7F8";
ctx.fillStyle = "#444444";
rect(x - 15, y + 15, textLength, 30);
}
Alternatively:
You could display your image underneath your canvas so it's not affected when you clear the canvas.

Related

Canvas Image rearrangement and rotation (center)

Canvas has an image and rectangle. Image should be rotated around center of canvas therefore I use translate to achive center but translate won't allow to drag the objects(dont know why).
When I drag, image and rectangle should be draggable together. When I rotate, only image should be rotatable and rectangle should be static(intact to rotation).
Anyone can help on the following code?
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var canvasOffset = $("#canvas").offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var startX;
var startY;
var isDown = false;
var pi2 = Math.PI * 2;
var resizerRadius = 6;
var rr = resizerRadius * resizerRadius;
var draggingResizer = {
x: 0,
y: 0
};
var imageX = 0;
var imageY = 0;
var imageWidth, imageHeight, imageRight, imageBottom;
var draggingImage = false;
var startX;
var startY;
var img = new Image();
img.onload = function() {
imageWidth = img.width;
imageHeight = img.height;
imageRight = imageX + imageWidth;
imageBottom = imageY + imageHeight
draw();
}
img.src = "http://www.w3.org/html/logo/downloads/HTML5_Logo_128.png";
var x = canvas.width / 2, y = canvas.height / 2;
function draw() {
canvas.width = canvas.width;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
//I have problem here!
//ctx.translate(x + imageX, y + imageY);
ctx.rotate($('#rvalue').val() * Math.PI / 180);
ctx.drawImage(img, imageX, imageY);
ctx.restore();
ctx.rect(imageX + 160, imageY + 30, 120, 40);
ctx.strokeStyle = "red";
ctx.stroke();
}
function hitImage(x, y) {
return (x > imageX && x < imageX + imageWidth && y > imageY && y < imageY + imageHeight);
}
function handleMouseDown(e) {
startX = parseInt(e.clientX - offsetX);
startY = parseInt(e.clientY - offsetY);
draggingImage = hitImage(startX, startY);
}
function handleMouseUp(e) {
draggingImage = false;
draw();
}
function handleMouseOut(e) {
handleMouseUp(e);
}
function handleMouseMove(e) {
if (draggingImage) {
imageClick = false;
mouseX = parseInt(e.clientX - offsetX);
mouseY = parseInt(e.clientY - offsetY);
var dx = mouseX - startX;
var dy = mouseY - startY;
imageX += dx;
imageY += dy;
imageRight += dx;
imageBottom += dy;
startX = mouseX;
startY = mouseY;
draw();
}
}
$("#canvas").mousedown(function(e) {
handleMouseDown(e);
});
$("#canvas").mousemove(function(e) {
handleMouseMove(e);
});
$("#canvas").mouseup(function(e) {
handleMouseUp(e);
});
$("#canvas").mouseout(function(e) {
handleMouseOut(e);
});
$("#rotate").click(function(event) {
var c = parseInt($('#rvalue').val());
$('#rvalue').val(c + 90);
draw();
});
<!DOCTYPE HTML>
<html lang="en"><head>
<meta charset="UTF-8" />
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<style type="text/css">#canvas { border: 1px solid #000; }</style>
</head>
<body>
<input type=text value="0" id="rvalue" />
<button id=rotate>Rotate</button><br>
<canvas id="canvas" width=600 height=400></canvas>
</body>
</html>
I'm a bit rusty with canvas, but would it help to translate, rotate, translate back, and THEN draw?
ctx.translate( centerx, centery );
ctx.rotate( $('#rvalue').val() * Math.PI / 180 );
ctx.translate( -centerx, -centery );
ctx.drawImage(img, imageX, imageY);

HTML5 canvas drawing on background scalling

i have problem i have background image and changing it scale and position with mousewheel and can drawing with mousedown and mousemove events. me example: http://jsfiddle.net/74MCQ/ Now see first drawing and second zoom we don't see drawing lines. I need make like a paint if drawing on me select position and if zoom i need see equal position with equal zoom scale.
You need a way to store the drawings of your user, either within another canvas, or by storing coordinates.
I suggest you store coordinates, below here's some code that will store the lines within an array, each line being an array of coordinates like : [x0, y0, x1, y1, x2, y2, ... ].
Edit : now i simplified the things, the coordinates are stored relative to the center of canvas.
See the fiddle, it is mostly working.
fiddle :
http://jsfiddle.net/gamealchemist/74MCQ/4/
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
var x = evt.clientX - rect.left;
var y = evt.clientY - rect.top;
var sx = (x-cw/2)/scale;
var sy = (y-ch/2)/scale;
return {
x: x,
y: y,
sx : sx,
sy:sy
};
}
/****** PAINT ******/
var isDrawing = false;
var color = "#000000";
var brushWidth = 10;
//var previousEvent = false;
ctx.strokeStyle = '#000000';
var currentLine = null;
var allLines = [];
$("#canvas").mousedown(function (e) {
var mousePos = getMousePos(canvas, e);
ctx.moveTo(mousePos.x, mousePos.y);
isDrawing = true;
if (currentLine) allLines.push(currentLine);
currentLine = [];
currentLine.push(mousePos.sx, mousePos.sy);
});
$("#canvas").mouseup(function () {
isDrawing = false;
if (currentLine) allLines.push(currentLine);
currentLine = null;
});
$("#canvas").mouseout(function () {
isDrawing = false;
if (currentLine) allLines.push(currentLine);
currentLine = null;
});
$("#canvas").mousemove(function (e) {
if (isDrawing === true) {
var mousePos = getMousePos(canvas, e);
currentLine.push(mousePos.sx, mousePos.sy);
//paint tools, effects
ctx.lineWidth = 10;
ctx.strokeStyle = color;
ctx.shadowBlur = 1;
ctx.shadowColor = 'rgb(0, 0, 0)';
ctx.lineTo(mousePos.x, mousePos.y);
ctx.stroke();
}
});
function drawStoredLines() {
var thisLine;
for (var i = 0; i < allLines.length; i++) {
thisLine = allLines[i];
drawLine(thisLine);
}
}
function drawLine(ptArray) {
if (ptArray.length <= 2) return;
ctx.beginPath();
ctx.moveTo(ptArray[0], ptArray[1]);
for (var p = 2; p < ptArray.length; p += 2) {
ctx.lineTo(ptArray[p], ptArray[p + 1]);
}
ctx.lineWidth = 10;
ctx.strokeStyle = color;
ctx.shadowBlur = 1;
ctx.shadowColor = 'rgb(0, 0, 0)';
ctx.stroke();
}
Notice that i couldn't resist reducing your 175 lines code to select the scale to a 25 lines one :-)
var zoomSteps = [0.1, 0.2, 0.4, 0.6, 0.8, 1.0, 1.5, 2.0, 3.0, 4.0];
var zoomIndex = zoomSteps.indexOf(1);
function doScroll(e) {
e = window.event || e;
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
zoomIndex = zoomIndex + delta;
if (zoomIndex < 0) zoomIndex = 0;
if (zoomIndex >= zoomSteps.length) zoomIndex = zoomSteps.length - 1;
scale = zoomSteps[zoomIndex];
imageWidthZoomed = imageWidth * scale;
imageHeightZoomed = imageHeight * scale;
var mousePos = getMousePos(canvas, e);
draw(mousePos.x, mousePos.y, scale);
}

Ball movement path in canvas, and other ideas you may have?

I've created this animation for my project that had to use any form of physics.
I am a total beginner, too :) Anyway, this is my project now :
Bouncing Balls
You can setup gravity and force, then click play, and just drag and drop to shoot the balls. You can change the values and hit update too see an effect.
My question is, how can I create an effect that when I press ratio button (for example) I can see the path that ball makes? Is it complicated? As I was saying I am a beginner, so no complex code for me :)
Also, doyou have any ideas to make the project better? Any additional "physics" effects? Or maybe you know a website that shows tutorials for simile (please) effects made in HTML5/js so I can add additional effects to my project.
One possibility (as you're clearing the canvas each frame) would be to draw ball paths onto a secondary canvas, which would not be cleared each frame. Then, when you come to clear the first frame, render the second frame after clearing, and before rendering the balls.
The second canvas would of course have to be the same dimensions as the first, so that all of the ball points line up correctly. The second canvas should also have a z-index lower than the first, so that it is only shown when you specifically render it to the first canvas (i.e. when the radio button is checked).
To decrease any lag while the radio is not checked, you could skip drawing the ball paths to the second canvas, although I don't think you would see any great increase in performance.
On each frame update, you would mark the position of each ball with a pixel, or line (from the previous position to the current) on the second canvas.
Looking at your code, you seem pretty competent, so I've skipped writing an example as I think this would be good experience for you :)
Modified 'script.js' source demonstrating solution
window.onload = function(){
$("#canvas").hide();
var howManyPaths = 0;
var showPath=false;
// SLIDERS
var gravitySlider = document.getElementById('gravitySlider');
var gravityVal = document.getElementById('gravityValue');
gravitySlider.onchange = function(){
gravityVal.value = gravitySlider.value;
}
gravityVal.onkeyup = function(){
gravitySlider.value = gravityVal.value;
}
var forceSlider = document.getElementById('forceSlider');
var forceValue = document.getElementById('forceValue');
forceSlider.onchange = function(){
forceValue.value = forceSlider.value;
}
forceValue.onkeyup = function(){
forceSlider.value = forceValue.value;
}
// GLOBAL VARIABLES
var test = false;
var gravityCount = $("#gravity").val();
var forceCount = $("#rectangles").val();
// CSS :
var playCSS = document.getElementById("play");
var restartCSS = document.getElementById("restart");
var clickableCSS = document.getElementById("setup");
var clickableBG = document.getElementById("img");
//restartCSS.style.visibility="hidden";
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var canvas2 = document.getElementById("canvas2");
var ctx2 = canvas2.getContext("2d");
//var ctx;
var gravity = 9.86;
var forceFactor = 0.5;
var mouseDown = false;
var balls = new Array();
var mousePos = new Array();
// EVENT HANDLER
function onMouseDown(evt){
mouseDown = true;
mousePos['downX'] = evt.pageX;
mousePos['downY'] = evt.pageY;
}
function onMouseUp(evt){
mouseDown = false;
setup.style.visibility="visible";
if(test == true && !( mousePos['downX'] < 200 && mousePos['downY'] < 150) ){
restartCSS.style.visibility="visible";
forceFactor = forceCount;
balls.push(new ball(mousePos["downX"],
mousePos["downY"],
(evt.pageX - mousePos["downX"]) * forceFactor,
(evt.pageY - mousePos["downY"]) * forceFactor,
10 + (Math.random() * 10),
0.8,
randomColor()
));
}
ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
}
function onMouseMove(evt){
mousePos['currentX'] = evt.pageX;
mousePos['currentY'] = evt.pageY;
}
function resizeWindow(evt){
//canvas.height = 960;
//canvas.width = 720;
canvas.height = $(window).height()-6;
canvas.width = $(window).width();
canvas2.height = $(window).height()-6;
canvas2.width = $(window).width();
}
$(document).mousedown(onMouseDown);
$(document).mouseup(onMouseUp);
$(document).mousemove(onMouseMove);
$(window).bind("resize", resizeWindow);
// GRAPHICS CODE
function circle(x, y, r, col){
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI*2, true);
ctx.closePath;
// fill
ctx.fillStyle = col;
ctx.fill();
// stroke
ctx.lineWidth = r * 0.1;
ctx.strokeStyle = "#000000";
ctx.stroke();
}
function circlePath(x, y)
{
ctx2.clearRect(0, 0, canvas2.width, canvas2.height);
ctx2.fillStyle = '#3f4043';
ctx2.fillRect(x, y, 5, 5);
ctx2.strokeStyle = "black";
ctx2.strokeRect(x, y, 5, 5);
}
function randomColor(){
var letter = "0123456789ABCDEF".split("");
var color = "#";
for(var i=0; i<6; i++){
color += letter[Math.round(Math.random()*15)];
}
return color;
}
function arrow(fromX, fromY, toX, toY, color){
// path
ctx.beginPath();
var headLen = 10;
var angle = Math.atan2(toY - fromY, toX - fromX);
ctx.moveTo(fromX, fromY);
ctx.lineTo(toX, toY);
ctx.lineTo(toX - headLen * Math.cos(angle - Math.PI/6), toY - headLen * Math.sin(angle - Math.PI/6));
ctx.moveTo(toX, toY);
ctx.lineTo(toX - headLen * Math.cos(angle + Math.PI/6), toY - headLen * Math.sin(angle + Math.PI/6));
// style
ctx.lineWith = 1;
ctx.strokeStyle = color;
ctx.lineCap = "butt";
ctx.stroke();
}
function drawBall(){
// Gravity
gravity = gravityCount;
this.speedY += gravity * 0.5; // v = a * t
this.x += this.speedX * 0.05; // s = v * t
this.y += this.speedY * 0.05;
// prawa ściana
if(this.x + this.r > canvas.width){
this.x = canvas.width - this.r;
this.speedX *= -1 * this.bounce;
}
// lewa ściana
if(this.x - this.r < 0){
this.x = this.r;
this.speedX *= -1 * this.bounce;
}
// dolna ściana
if(this.y + this.r > canvas.height){
this.y = canvas.height - this.r;
this.speedY *= -1 * this.bounce;
}
// górna ściana
if(this.y - this.r < 0){
this.y = this.r;
this.speedY *= -1 * this.bounce;
}
// zwalnianie na ziemi
if (this.speedX > 0.25){
this.speedX -= 0.25;
if (this.speedY > 0.25)
this.speedY -= 0.25;
}
if (this.speedX < -0.25){
this.speedX += 0.25;
//if (this.speedY < -0.25)
// this.speedY += 0.25;
}
circle(this.x, this.y, this.r, this.col);;
}
// OBJECTS
function ball(positionX, positionY, sX, sY, radius, b, color){
this.x = positionX;
this.y = positionY;
this.speedX = sX;
this.speedY = sY;
this.r = radius;
this.bounce = b;
this.col = color;
this.draw = drawBall;
}
//GAME LOOP
function gameLoop(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
//grab the context from your destination canvas
//if path drawing is enabled, first draw the path canvas to the display canvas
if (showPath) ctx.drawImage(canvas2,0,0);
if(mouseDown == true){
// ctx.clearRect(0, 0, canvas.width, canvas.height); /* !important !!!!!!!!!!!!!!! */
arrow(mousePos['downX'], mousePos['downY'], mousePos['currentX'], mousePos['currentY'], "red");
}
for(var i=0; i<balls.length; i++){
balls[i].draw();
if (i==balls.length-1) {
//draw path
ctx2.fillStyle = '#3f4043';
ctx2.fillRect(balls[i].x, balls[i].y, 5, 5);
ctx2.strokeStyle = "black";
ctx2.strokeRect(balls[i].x, balls[i].y, 5, 5);
}
}
ctx.fillStyle = "#000000";
ctx.font = "15px Arial";
ctx.fillText("Balls: " + balls.length + " " + gravityCount + " " + forceCount + " " + howManyPaths, 10, canvas.height -10);
}
// START THE GAME
function init(){
//$("#setup").hide();
$("#canvas").show();
$("#canvas2").hide();
ctx = $('canvas')[0].getContext("2d");
canvas.height = $(window).height()-6;
canvas.width = $(window).width();
//canvas.width = 960;
//canvas.height = 720;
canvas2.height = $(window).height()-6;
canvas2.width = $(window).width();
return setInterval(gameLoop, 10);
}
$("#play").click(function() {
test = true;
playCSS.style.visibility="hidden";
gravityCount = $("#gravitySlider").val();
forceCount = $("#forceSlider").val();
init();
});
$("#restart").click(function() {
window.location.href="index.html";
});
$("#refresh").click(function() {
gravityCount = $("#gravitySlider").val();
forceCount = $("#forceSlider").val();
});
$("#showPath").click(function() {
showPath=true;
});
$("#hidePath").click(function() {
showPath=false;
});
}

HTML5 canvas background image repeat

I have a html5 canvas that draws a sound wave. I have set the background as an background image, however, I want this background image to repeat. Can anyone tell me how I would do this and what I need to add into my code:
var backgroundImage = new Image();
backgroundImage.src = 'http://www.samskirrow.com/client-kyra/images/main-bg.jpg';
var canvas;
var context;
function init(c) {
canvas = document.getElementById(c);
context = canvas.getContext("2d");
soundManager.onready(function() {
initSound(clientID, playlistUrl);
});
aniloop();
}
function aniloop() {
requestAnimFrame(aniloop);
drawWave();
}
function drawWave() {
var step = 10;
var scale = 60;
// clear
context.drawImage(backgroundImage, 0, 0);
// left wave
context.beginPath();
context.moveTo(0, 256);
for ( var i = 0; i < 256; i++) {
context.lineTo(6 * i, 257 + waveLeft[i] * 80.);
}
context.lineWidth = 1;
context.strokeStyle = "#000";
context.stroke();
// right wave
context.beginPath();
context.moveTo(0, 256);
for ( var i = 0; i < 256; i++) {
context.lineTo(6 * i, 256 + waveRight[i] * 80.);
}
context.lineWidth = 1;
context.strokeStyle = "#000";
context.stroke();
}
function updateWave(sound) {
waveLeft = sound.waveformData.left;
}
return {
init : init
};
})();
You can see this code in action here:
http://www.samskirrow.com/client-kyra
Use the canvas' createPattern function
const canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
img = new Image();
img.src = 'https://www.google.nl/images/srpr/logo3w.png';
img.addEventListener('load', () => {
const ptrn = context.createPattern(img, 'repeat'); // Create a pattern with this image, and set it to "repeat".
context.fillStyle = ptrn;
context.fillRect(0, 0, canvas.width, canvas.height); // context.fillRect(x, y, width, height);
})
<canvas id="canvas" width="600px" height="600px"></canvas>
(This is the fastest of the 2 samples).
Or, try a manual implementation:
const canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
img = new Image();
img.src = 'https://www.google.nl/images/srpr/logo3w.png';
img.addEventListener('load', () => {
for (let w = 0; w < canvas.width; w += img.width) {
for (let h = 0; h < canvas.height; h += img.height) {
context.drawImage(img, w, h);
}
}
})
<canvas id="canvas" width="600px" height="600px"></canvas>

Drag and Drop functionality inside canvas using HTML5

Hello all can we place drag and drop functionality inside canvas using html5??
My actual requirement is to drag the image into textbox that should be done inside the canvas...
please share your ideas..The following link i used to learn drag and drop but it should be done inside the canvas..
http://www.w3schools.com/html5/tryit.asp?filename=tryhtml5_draganddrop
You can learn more in this tutorial: http://html5.litten.com/how-to-drag-and-drop-on-an-html5-canvas/
From your limited description in your question, it sounds like you drag items over the canvas and this tutorial is likely the best match.
This is the actual code you can paste into file and open in HTML5 compliant browser and it will work:
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>Canvas Drag and Drop Test</title>
</head>
<body>
<section>
<div>
<canvas id="canvas" width="400" height="300">
This text is displayed if your browser does not support HTML5 Canvas.
</canvas>
</div>
<script type="text/javascript">
var canvas;
var ctx;
var x = 75;
var y = 50;
var WIDTH = 400;
var HEIGHT = 300;
var dragok = false;
function rect(x,y,w,h) {
ctx.beginPath();
ctx.rect(x,y,w,h);
ctx.closePath();
ctx.fill();
}
function clear() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
}
function init() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
return setInterval(draw, 10);
}
function draw() {
clear();
ctx.fillStyle = "#FAF7F8";
rect(0,0,WIDTH,HEIGHT);
ctx.fillStyle = "#444444";
rect(x - 15, y - 15, 30, 30);
}
function myMove(e){
if (dragok){
x = e.pageX - canvas.offsetLeft;
y = e.pageY - canvas.offsetTop;
}
}
function myDown(e){
if (e.pageX < x + 15 + canvas.offsetLeft && e.pageX > x - 15 +
canvas.offsetLeft && e.pageY < y + 15 + canvas.offsetTop &&
e.pageY > y -15 + canvas.offsetTop){
x = e.pageX - canvas.offsetLeft;
y = e.pageY - canvas.offsetTop;
dragok = true;
canvas.onmousemove = myMove;
}
}
function myUp(){
dragok = false;
canvas.onmousemove = null;
}
init();
canvas.onmousedown = myDown;
canvas.onmouseup = myUp;
</script>
</section>
</body>
</html>