How can I make an image in a canvas to act as a link?
I am not able to put < a href > tag on the < image > tag as I dont want it to be displayed first until the user click on a button.
Is there any line of code I need to insert in the javascript?
window.onload = function () {
var endCan = document.getElementById("endCan");
var end = endCan.getContext("2d");
var img = document.getElementById("end");
end.drawImage(img, 0, 0, img.width / 2, img.height / 2);
};
<img id="end" style="display: none;" src="img/WellDone_Rectangle.png"/>
<canvas id="endCan" class="wrapper" width="1000" height="600"></canvas>
$(".buttonNext6").click(function () {
$("#endCan").fadeIn();
});
You need to add a click event handler to the canvas, and then when it's clicked you check the co-ordinates to see if it was clicked where your image was drawn.
Here's an example, using a rectangle drawn on a canvas...
var endCan = document.getElementById("endCan");
var endCtx = endCan.getContext("2d");
endCtx.rect(10, 20, 150, 100);
endCtx.fill();
endCan.addEventListener("click", function(e) {
if (e.clientX >= 10 && e.clientX <= 160 &&
e.clientY >= 20 && e.clientY <= 120) {
alert("clicked");
}
});
<canvas id="endCan" class="wrapper" width="500" height="300"></canvas>
window.onload = function () {
var endCan = document.getElementById("endCan");
var end = endCan.getContext("2d");
var img = document.getElementById("end");
end.drawImage(img, 0, 0, img.width / 2, img.height / 2);
};
//$(".buttonNext6").click(function () {
// $("#endCan").fadeIn();
//});
function canvasCallback() {
console.log('clicked')
}
<img id="end" style="display: none;" src="https://picsum.photos/200/300"/>
<canvas onclick="canvasCallback()" id="endCan" class="wrapper" width="1000" height="600"></canvas>
Related
I want to zoom in and out of the section image with my fingers and then return to the original image size again.
Currently, after the image is enlarged, the image will not come back to the original.
The desired order list.
1. Zoom in and out of the image -> ok
2. Resize the image back to its original size. -> fail
3. Center the coordinates of the image -> fail
var canvas;
var gMarginWidth = 0;
var gMarginHeight = 0;
var gImageWidth = 0;
var gRatio = 0;
$(document).ready(function() {
canvas_result();
});
function canvas_result(){
//canvas
canvas = new fabric.Canvas('c',
{
selection : false,
controlsAboveOverlay:true,
centeredScaling:true,
allowTouchScrolling: false
}
);
gRatio = 0;
gMarginWidth = 0;
gMarginHeight = 0;
function resizeCanvas(imageWidth) {
canvas.setHeight(window.innerHeight*0.5);
canvas.setWidth(imageWidth);
canvas.renderAll();
}
fabric.Image.fromURL("http://59.25.178.93:8080/homesys/rest/testservice/0/imgLoadAdm.do?fileId=HF201801221742200845&fileSn=2", function(img) {
var xRatio = $('#canvasWrapper').width()/img.width;
var yRatio = (window.innerHeight*0.5)/img.height;
gRatio = xRatio < yRatio ? xRatio : yRatio;//길이에 맞게 조절할 배율
gImageWidth = img.width * gRatio;
gMarginWidth = ($('#canvasWrapper').width() - img.width * gRatio) / 2;
gMarginHeight = (600- img.height * gRatio)/2;
resizeCanvas($('#canvasWrapper').width());
canvas.setBackgroundImage(img);
canvas.setZoom(gRatio);//평면도 가로 길이가 canvas에 꽉 차도록 zoom
canvas.renderAll();
});
//캔버스 마우스 클릭 이벤트
canvas.on({
'mouse:up': function(event) {
self.canvas.zoomToPoint(new fabric.Point(canvas.width / 2, canvas.height / 2), 0.305);
},
//캔버스 터치 이벤트 확대, 축소
'touch:gesture': function(event) {
// Handle zoom only if 2 fingers are touching the screen
if (event.e.touches && event.e.touches.length == 2) {
// Get event point
var point = new fabric.Point(event.self.x, event.self.y);
// Remember canvas scale at gesture start
if (event.self.state == "start") {
zoomStartScale = self.canvas.getZoom();
}
var delta = zoomStartScale * event.self.scale ;
// Zoom to pinch point
// self.canvas.zoomToPoint(new fabric.Point(canvas.width / 2, canvas.height / 2), delta);
self.canvas.zoomToPoint(point, delta);
}
}
});
}
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.0.0/fabric.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<div class="card" style="background-color: #fff;">
<label style="margin-bottom:5px; margin-top:25px;">
<font size="3" style="margin-left: 10px">Zoom in/ out</font>
<font id="clocks" style="margin-left: 10px" size="1"></font>
</label>
<hr class="style1" style="margin-bottom: 20px; margin-left: 30px; margin-right: 30px; margin-top: 0px;">
<div id="canvasWrapper">
<canvas class="img-responsive img-rounded" id="c"></canvas>
</div>
</div>
snippet ok
https://jsfiddle.net/6kjL3xe4/6/
I solved the answer to my question.
The correct answer is console.log (self.canvas); Respectively.
And the viewportTransform found there is my gem.
'mouse:up': function(event) { [zoomStartScale,0,0,zoomStartScale,0,0];
},
//캔버스 터치 이벤트 확대, 축소
'touch:gesture': function(event) {
// Handle zoom only if 2 fingers are touching the screen
if (event.e.touches && event.e.touches.length == 2) {
// Get event point
var point = new fabric.Point(event.self.x, event.self.y);
//point_x = -1 * event.self.x;
//point_y = -1 * event.self.y;
// Remember canvas scale at gesture start
if (event.self.state == "start") {
zoomStartScale = self.canvas.getZoom();
}
var delta = zoomStartScale * event.self.scale ;
// Zoom to pinch point
// self.canvas.zoomToPoint(new fabric.Point(canvas.width / 2, canvas.height / 2), delta);
self.canvas.zoomToPoint(point, delta);
}
}
});
I am trying to get an HTML 5 slider working. I’m trying to get it to change the value of the variable moveX. Line 52 works but that is for static. Lines 53 and 54 are what I have tried, but it just creates erratic movement. could somebody help me?
Here is a link to the page:http://hyque.com/ani/drawImageBtnFwd.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>DrawImage with Buttons</title>
</head>
<body>
<button id="startBtn">Start</button>
<button id="stopBtn">Pause</button><br />
<p>
<strong>Speed</strong>
<input id="slider1" type="range" min="1" max="10" value="0" step="1">
</p>
<canvas id="myCanvas" width="1200" height="187" style="border:1px solid #d3d3d3;">
<script>
window.onload = function() {
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = new Image();
img.src = "http://hyque.com/ani/adam.png";
var xPos = 0;
var moveX = 0;
var scaleSlider = document.getElementById("slider1");
ctx.drawImage(img, 0, 0, 120, 182, 0, 0, 120, 182);
//number(scaleSlider);
var el = document.getElementById('startBtn');
el.addEventListener('click', strt, false);
var el2 = document.getElementById('stopBtn');
el2.addEventListener('click', stopIt, false);
function imageXPosition() {
ctx.clearRect(0, 0, 1200, 182); // This clears the canvas
ctx.drawImage(img, xPos, 0, 120, 182, moveX, 0, 120, 182); //Draws the individual frames
xPos += 120; //adds the width
//moveX += 5;
moveX += scaleSlider.value;
//scaleSlider.onchange = function(e){moveX = e.target.value;}
//This adds 1 to the second frame
if(xPos == 120){
xPos += 1;
}
if(xPos > 841){xPos = 0;} // This resets to 0 after the las frame
if(moveX >= 1200){moveX = 0;}
}
var intStp; // declared outside the strt() function, because
function strt(){
clearInterval(intStp); //without this lin the animation will speed up eachtime you click "Start Button"
intStp = setInterval(imageXPosition, 200);
}
function stopIt(){
clearInterval(intStp);
}
}
</script>
</body>
</html>
From what I see this line is problematic:
moveX += scaleSlider.value;
scaleSlider.value returns a string.
moveX is also a string.
When the line above is called you are having something like this
"0" += "1" this results is "01"
after it "01" += "2" which results in "012" etc.
Before solving anything else make sure you use parseInt(moveX, 10);
This will allow you to continue.
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>
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.
So I have 2 problems. first is the clearInterval does not seem to be working as the image continues to rotate when the mouse cursor is over the image. second is the rightDisc is the setInterval seems to not work on the rightDisc. all the other functions do work. I tried looking into threading with web workers but that's all sorts of confusing me.
<html>
<head>
<script src="../js/jquery-1.6.4.min.js"></script>
<script src="../js/imgRotate.js"></script>
<script>
$(function()
{
$("#leftDisc").rotate();
$("#rightDisc").rotate();
});
</script>
</head>
<body>
<div>
<img id="turnTableImage" src="turntable.jpg" height="400" width="600" alt="" />
</div>
<div id="leftDisc" style="margin-top: -280px; margin-left: 50px">
left<img id="leftDiscImg" class="discs" height="200" src="disc.png" alt="" />
</div>
<div id="rightDisc" style="margin-top: -300px; margin-left: 350px">
<img id="rightDiscImg" class="discs" src="disc.png" alt="" />right
</div>
</body>
imgRotate.js
(function($) {
$.fn.rotate = function() {
var img = this.find(".discs");
var imgpos = img.position();
var x, y, xCenter, yCenter, x1, y1, deg = 1, drag = false;
var interval = setInterval(function() {
deg++;
$("#leftDiscImg").css("transform","rotate("+deg+"deg)");
$("#leftDiscImg").css("-moz-transform","rotate("+deg+"deg)");
$("#leftDiscImg").css("-webkit-transform","rotate("+deg+"deg)");
$("#leftDiscImg").css("-o-transform","rotate("+deg+"deg)");
$("#leftDiscImg").css("ms-transform","rotate("+deg+"deg)");
}, 20);
$(window).load(function() {
img.removeAttr("width");
img.removeAttr("height");
xCenter = imgpos.left + (img.width() / 2);
yCenter = imgpos.top + (img.height() / 2);
});
img.mousemove(function(e) {
x1 = e.pageX;
y1 = e.pageY;
x = x1 - xCenter;
y = y1 - yCenter;
r = 360 - ((180/Math.PI) * Math.atan2(y,x));
if (drag == true) {
img.css("transform","rotate(-"+r+"deg)");
img.css("-moz-transform","rotate(-"+r+"deg)");
img.css("-webkit-transform","rotate(-"+r+"deg)");
img.css("-o-transform","rotate(-"+r+"deg)");
img.css("ms-transform","rotate(-"+r+"deg)");
}
});
img.mouseover(function() {
clearInterval(interval);
deg = 1;
if (drag == false) {
drag = true;
} else {
drag = false;
}
});
img.mouseout(function() {
drag = false;
interval = setInterval(function() {
deg++;
$("#leftDiscImg").css("transform","rotate("+deg+"deg)");
$("#leftDiscImg").css("-moz-transform","rotate("+deg+"deg)");
$("#leftDiscImg").css("-webkit-transform","rotate("+deg+"deg)");
$("#leftDiscImg").css("-o-transform","rotate("+deg+"deg)");
$("#leftDiscImg").css("ms-transform","rotate("+deg+"deg)");
}, 20);
});
};
})( jQuery );