How to create a ruler a tool for canvas? - javascript

Like the standard paint program in windows, I'm trying to create a very basic sketch canvas program where the the user can select a ruler tool to draw with on the canvas. How do I achieve this?
I'm quite a beginner so I'd appreciate if the answer is as simple as possible...
Thanks!!

You can use 2 overlapping canvases wrapped in a container div.
Then draw your ruler marks on the bottom canvas.
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/8hVC2/
<!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; padding:20px; }
#wrapper{
position:relative;
width:315px;
height:215px;
}
#canvasBottom{
position:absolute; top:0px; left:0px;
border:1px solid red;
}
#canvasTop{
position:absolute; top:15px; left:15px;
border:1px solid red;
}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvasTop");
var ctx=canvas.getContext("2d");
var canvas2=document.getElementById("canvasBottom");
var ctx2=canvas2.getContext("2d");
ctx2.beginPath();
for(var i=0;i<canvas.width;i+=10){
var y=(i/100==parseInt(i/100))?0:10;
ctx2.moveTo(i+15,y);
ctx2.lineTo(i+15,15);
var x=(i/100==parseInt(i/100))?0:10;
ctx2.moveTo(x,i+15);
ctx2.lineTo(15,i+15);
}
ctx2.stroke();
var canvasOffset=$("#canvasTop").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
function handleMouseMove(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
$("#movelog").html("Move: "+ mouseX + " / " + mouseY);
// Put your mousemove stuff here
}
$("#canvasTop").mousemove(function(e){handleMouseMove(e);});
}); // end $(function(){});
</script>
</head>
<body>
<p id="movelog">Move</p>
<div id="wrapper">
<canvas id="canvasBottom" width=315 height=215></canvas>
<canvas id="canvasTop" width=300 height=200></canvas>
</div>
</body>
</html>

If I may suggest you could use my easyCanvas library. It's a library that wraps around standard canvas and let you use it as ordinary but adds some handy functionality (GPL3).
If this is an option you could create what you need simply by doing this assumimg the easyCanvas script is already included:
var ez = new easyCanvas();
// enable background handling when drawing
ez.autoClear = true;
// mouse down/up is handled internally so all we need to draw the line
ez.onmousemove = function(e) {
ez1.line(ez.firstX, ez.firstY, e.x, e.y);
}
(you can use an existing canvas element as well - this will create a canvas that covers the window and auto-resizes it when window size changes, please see documentation for the details).
Update: easyCanvas is now legacy and is located at GitHub to avoid link-rot.

Related

HTML Canvas (SVG) - Draw image on cylinder surface

I'm working with HTML5 Canvas now. I have one image file and and a mug image file. I want the image file to be drawn on that cylinder surface. Something like the images below.
Are there any Javascript canvas (or maybe SVG) libraries that can help me archive that?
Thank you very much
You can achieve your "wrap" effect by slicing your image into 1px wide vertical slices and changing the "Y" coordinate of each slice to fit the curve of your cup.
Here's example code that uses this technique to "stretch" an image.
Feel free to modify this code to fit along the curve of your cup.
Example code and a Demo: http://jsfiddle.net/m1erickson/krhQW/
<!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 img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/warp.png";
function start(){
var iw=img.width;
var ih=img.height;
canvas.width=iw+20;
canvas.height=ih+20;
var x1=0;
var y1=50;
var x2=iw;
var y2=0
var x3=0;
var y3=ih-50;
var x4=iw;
var y4=ih;
// calc line equations slope & b (m,b)
var m1=Math.tan( Math.atan2((y2-y1),(x2-x1)) );
var b1=y2-m1*x2;
var m2=Math.tan( Math.atan2((y4-y3),(x4-x3)) );
var b2=y4-m2*x4;
// draw vertical slices
for(var X=0;X<iw;X++){
var yTop=m1*X+b1;
var yBottom=m2*X+b2;
ctx.drawImage( img,X,0,1,ih, X,yTop,1,yBottom-yTop );
}
// outline
ctx.beginPath();
ctx.moveTo(x1,y1);
ctx.lineTo(x2,y2);
ctx.lineTo(x4,y4);
ctx.lineTo(x3,y3);
ctx.closePath();
ctx.stroke();
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

Draw lines between 2 elements in html page

i need to draw lines between 2 element on html page
the results should be like this:
http://img2.timg.co.il/forums/1_173873919.JPG
i wondered what the best way do this
using canvas and html5
using background image.
make by ajax dynamic the image
i would like to know what the best way and if there is a simple demo on the web
thanks
Lots of ways to solve your need:
Here's one solution using an html canvas: http://jsfiddle.net/m1erickson/86f4C/
Example code (could be fully automated with jquery+css-classes):
<!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>
<script src="http://code.jquery.com/ui/1.9.2/jquery-ui.min.js"></script>
<style>
body{ background-color: ivory; margin:0; padding:0; }
#canvas{
position:absolute;
border:1px solid red;
width:100%;height:100%;
}
.draggable{
width:50px;
height:30px;
background:skyblue;
border:1px solid green;
}
.right{
margin-left:100px;
background:salmon;
}
#wrap2{margin-top:-95px;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
ctx.lineWidth=3;
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var $0=$("#0");
var $1=$("#1");
var $2=$("#2");
var $0r=$("#0r");
var $1r=$("#1r");
var $2r=$("#2r");
var connectors=[];
connectors.push({from:$0,to:$0r});
connectors.push({from:$1,to:$0r});
connectors.push({from:$2,to:$2r});
connect();
$(".draggable").draggable({
// event handlers
start: noop,
drag: connect,
stop: noop
});
function noop(){}
function connect(){
ctx.clearRect(0,0,canvas.width,canvas.height);
for(var i=0;i<connectors.length;i++){
var c=connectors[i];
var eFrom=c.from;
var eTo=c.to;
var pos1=eFrom.offset();
var pos2=eTo.offset();
var size1=eFrom.size();
var size2=eTo.size();
ctx.beginPath();
ctx.moveTo(pos1.left+eFrom.width()+3,pos1.top+eFrom.height()/2);
ctx.lineTo(pos2.left+3,pos2.top+eTo.height()/2);
ctx.stroke();
}
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
<div>
<div id="0" class="draggable">0</div>
<div id="1" class="draggable">1</div>
<div id="2" class="draggable">2</div>
</div>
<div id="wrap2">
<div id="0r" class="draggable right">0</div>
<div id="1r" class="draggable right">1</div>
<div id="2r" class="draggable right">2</div>
</div>
</body>
</html>
There is a very simple way of achieving this with some Javascript and the HTML canvas tag.
DEMO HERE showing how to draw the most complicated element on your example which has one field with lines branching to two other fields.
How it (basically) works is as follows.
Start the drawing function with:
context.beginPath();
Pass the desired coordinates to the function with:
context.moveTo(100, 150);
context.lineTo(450, 50);
Then execute the draw with:
context.stroke();
There's some great tutorials HERE
use <canvas> if you want to use simple things like circles and images and stuff - for divs, you would want to look for alternatives like in Jquery or - like you said - javascript. For <canvas> you could try this and this
here's a link to a gist that uses javascript (jquery) to draw a path (and redraw it in case of window resizing) between any 2 html elements.
demo
For GameRefCard I've using leader-line. It worked extremely well for me and is very popular it seems, if you are to trust GitHub statistics. I found out about from this other StackOverflow answer.

Multi canvas layer paint application in HTML5 [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 9 years ago.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Improve this question
I am building a paint tool with eraser option using HTML5 canvas. The canvas loads a backgroung image and on the image users can draw paintings. But on using the eraser tool only the painted part should be erased(not the part of the image). I know that i must use more than one canvas for it. please help me with some code example if you can. Thanks in advance.
Yes, you can use 2 canvases to support both an indestructible background and a sketching foreground.
BTW, The background doesn't need to be a canvas. It could be just an image or div with content.
A quick Illustration
You can wrap your background and sketching canvases in a wrapper div:
<div id="wrapper">
<canvas id="canvas2" width=300 height=200></canvas>
<canvas id="canvas" width=300 height=200></canvas>
</div>
Then use CSS to position the sketching canvas directly on top of the background canvas:
body{ background-color: ivory; }
#wrapper{
position:relative;
width:300px;
height:200px;
}
#canvas,#canvas2{
position:absolute; top:0px; left:0px;
border:1px solid green;
width:100%;
height:100%;
}
#canvas2{
border:2px solid red;
}
Here is a small illustration app that uses the background canvas to display a blue background.
The sketching canvas (on top) is used to draw and erase.
Here's code and a Fiddle: http://jsfiddle.net/m1erickson/G6JAK/
<!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>
<!--[if lt IE 9]><script type="text/javascript" src="../excanvas.js"></script><![endif]-->
<style>
body{ background-color: ivory; }
#wrapper{
position:relative;
width:300px;
height:200px;
}
#canvas,#canvas2{
position:absolute; top:0px; left:0px;
border:1px solid green;
width:100%;
height:100%;
}
#canvas2{
border:2px solid red;
}
</style>
<script>
$(function(){
var canvas2=document.getElementById("canvas2");
var ctx2=canvas2.getContext("2d");
ctx2.fillStyle="skyBlue";
ctx2.lineWidth=5;
ctx2.fillRect(0,0,canvas2.width,canvas2.height);
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.lineWidth=3;
var lastX;
var lastY;
var mouseX;
var mouseY;
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var isMouseDown=false;
function handleMouseDown(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mousedown stuff here
lastX=mouseX;
lastY=mouseY;
isMouseDown=true;
}
function handleMouseUp(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mouseup stuff here
isMouseDown=false;
}
function handleMouseOut(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mouseOut stuff here
isMouseDown=false;
}
function handleMouseMove(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mousemove stuff here
if(isMouseDown){
ctx.beginPath();
if(mode=="pen"){
ctx.globalCompositeOperation="source-over";
ctx.moveTo(lastX,lastY);
ctx.lineTo(mouseX,mouseY);
ctx.stroke();
}else{
ctx.globalCompositeOperation="destination-out";
ctx.arc(lastX,lastY,5,0,Math.PI*2,false);
ctx.fill();
}
lastX=mouseX;
lastY=mouseY;
}
}
$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mousemove(function(e){handleMouseMove(e);});
$("#canvas").mouseup(function(e){handleMouseUp(e);});
$("#canvas").mouseout(function(e){handleMouseOut(e);});
var mode="pen";
$("#pen").click(function(){ mode="pen"; });
$("#eraser").click(function(){ mode="eraser"; });
}); // end $(function(){});
</script>
</head>
<body>
<div id="wrapper">
<canvas id="canvas2" width=300 height=200></canvas>
<canvas id="canvas" width=300 height=200></canvas>
</div>
<button id="pen">Pen</button>
<button id="eraser">Eraser</button>
</body>
</html>

How to give a colour to particular div by selecting a colour in html5

I am an intermediate in javascript. I am making an app for children .. I am developing in it HTML5/javascript. My app motive is to select the letter and practice them by sketching the outline of letters..
Here is my app design in below picture
In the app I want to select the color of the required one from the colour given in pencil and paint in the outline of A. and I have to erase with the eraser given..
I had almost finished the app except the colouring part..
Please anyone help and guide me how to do this..
I just want to know how to make this to colour outline by selecting the colours.. if there any code available or demo available please tell me about that.
Experts shed light on this problem
[Revised answer based on changed request]
Here’s how to let the child draw anywhere within a bounding box around the letter
First, define the area that the drawing will be restricted to.
Any drag-draws outside the drawable area won't be visible.
// define the drawable area
var minX=60;
var maxX=250;
var minY=140;
var maxY=380;
Then in mousemove, draw only if the mouse is inside that drawable area:
if(mouseX>minX && mouseX<maxX && mouseY>minY && mouseY<maxY){
ctx.beginPath();
ctx.moveTo(startX,startY);
ctx.lineTo(mouseX,mouseY);
ctx.stroke();
}
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/tAkAy/
<!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; }
#wrapper{
position:relative;
width:637px;
height:477px;
}
#canvas,#bkImg{
position:absolute; top:0px; left:0px;
border:1px solid green;
width:100%;
height:100%;
}
#canvas{
border:1px solid red;
}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.strokeStyle="red";
ctx.lineWidth=25;
ctx.lineCap="round";
// define the drawable area
// any drag-draws outside the drawable area won't be visible
var minX=60;
var maxX=250;
var minY=140;
var maxY=380;
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var startX;
var startY;
var isDown=false;
function handleMouseDown(e){
startX=parseInt(e.clientX-offsetX);
startY=parseInt(e.clientY-offsetY);
isDown=true;
}
function handleMouseUp(e){
if(!isDown){return;}
isDown=false;
}
function handleMouseMove(e){
if(!isDown){return;}
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
if(mouseX>minX && mouseX<maxX && mouseY>minY && mouseY<maxY){
ctx.beginPath();
ctx.moveTo(startX,startY);
ctx.lineTo(mouseX,mouseY);
ctx.stroke();
}
startX=mouseX;
startY=mouseY;
}
$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mousemove(function(e){handleMouseMove(e);});
$("#canvas").mouseup(function(e){handleMouseUp(e);});
$("#canvas").mouseout(function(e){handleMouseOut(e);});
}); // end $(function(){});
</script>
</head>
<body>
<div id="wrapper">
<img id="bkImg" src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/game1.png" width=637 height=477>
<canvas id="canvas" width=637 height=477></canvas>
</div>
</body>
</html>
[ Original answer ]
How to draw lines on a canvas in a selected color
Here is some code for you to start with.
The important points are:
Mousedown starts a line and sets it beginning point
Mouseup ends a line and sets its endpoint. This is a permanent line.
Mousemove draws a temporary line until the user releases the mouse.
All permanent lines must be redrawn when a temporary line is being drawn because the canvas must be erased to create the “moving” temporary line.
Html canvas draws a line using it's context like this:
function drawLine(line){
ctx.beginPath();
ctx.moveTo(line.x1,line.y1);
ctx.lineTo(line.x2,line.y2);
ctx.stroke();
}
To set/change the line color, you set the context's strokeStyle:
context.strokeStyle="blue";
To erase all drawings on the canvas, you use context's clearRect:
context.clearRect(0,0,canvas.width,canvas.height);
If you're not used to specifying hit zones, it's pretty simple.
Specify a bounding box (top-left and bottom-right) of the area you might hit (eg. the blue crayon)
Then if the mouse clicks inside that bounding box, you have a hit.
The canvas is layered over the game image and all lines are being drawn on the canvas, not the image.
The rest is just straightforward javascript stuff.
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/G6eWn/
<!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; }
#wrapper{
position:relative;
width:637px;
height:477px;
}
#canvas,#bkImg{
position:absolute; top:0px; left:0px;
border:1px solid green;
width:100%;
height:100%;
}
#canvas{
border:1px solid red;
}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.strokeStyle="red";
ctx.lineWidth=25;
ctx.lineCap="round";
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var startX;
var startY;
var isDown=false;
var lines=[];
var eraser={x:446,y:413,right:516,bottom:475};
var pens=[
{x:240,y:413,right:275,bottom:475,color:"red"},
{x:276,y:413,right:308,bottom:475,color:"green"},
{x:309,y:413,right:341,bottom:475,color:"orange"},
{x:342,y:413,right:375,bottom:475,color:"blue"},
{x:376,y:413,right:412,bottom:475,color:"yellow"},
{x:412,y:413,right:447,bottom:475,color:"pink"},
];
function selectPenColor(x,y){
for(var i=0;i<pens.length;i++){
var pen=pens[i];
if(x>=pen.x && x<=pen.right && y>=pen.y && y<=pen.bottom){
ctx.strokeStyle=pen.color;
drawLines();
return(true);
}
}
return(false);
}
function drawLines(){
ctx.clearRect(0,0,canvas.width,canvas.height);
for(var i=0;i<lines.length;i++){
drawLine(lines[i]);
}
}
function drawLine(line){
ctx.beginPath();
ctx.moveTo(line.x1,line.y1);
ctx.lineTo(line.x2,line.y2);
ctx.stroke();
}
function selectEraser(x,y){
if(x>=eraser.x && x<=eraser.right && y>=eraser.y && y<=eraser.bottom){
lines=[];
ctx.clearRect(0,0,canvas.width,canvas.height);
return(true);
}
return(false);
}
function handleMouseDown(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// select a pen color or erase
// if so, don't start a line
if(selectPenColor(mouseX,mouseY)){return;}
if(selectEraser(mouseX,mouseY)){return;}
startX=mouseX;
startY=mouseY;
isDown=true;
}
function handleMouseUp(e){
if(!isDown){return;}
isDown=false;
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
lines.push({x1:startX,y1:startY,x2:mouseX,y2:mouseY});
drawLines();
}
function handleMouseOut(e){
handleMouseUp(e);
}
function handleMouseMove(e){
if(!isDown){return;}
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
drawLines();
drawLine({x1:startX,y1:startY,x2:mouseX,y2:mouseY});
}
$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mousemove(function(e){handleMouseMove(e);});
$("#canvas").mouseup(function(e){handleMouseUp(e);});
$("#canvas").mouseout(function(e){handleMouseOut(e);});
}); // end $(function(){});
</script>
</head>
<body>
<div id="wrapper">
<img id="bkImg" src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/game1.png" width=637 height=477>
<canvas id="canvas" width=637 height=477></canvas>
</div>
</body>
</html>

Paint Text field implementation in javascript

Is it possible to implement the paint text feature in javascript on a canvas?
A text button say "A" ,on click of this like in paint one should be able to draw a text box on canvas wherever the user clicked mouse.Also should be able to type text init.Also should be able to move this text box anywhere on the canvas.
Any suggestion/solution is appreciable.
Thanks.
This basic framework should get you started.
This code allows the user to enter their text.
Then they click on the canvas and their text is drawn at the mouse position.
Of course, you will want to take it from here to design it to fit your needs.
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/7GHvj/
<!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>
<!--[if lt IE 9]><script type="text/javascript" src="../excanvas.js"></script><![endif]-->
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var lastX;
var lastY;
var strokeColor="red";
var strokeWidth=2;
var canMouseX;
var canMouseY;
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
function handleMouseDown(e){
canMouseX=parseInt(e.clientX-offsetX);
canMouseY=parseInt(e.clientY-offsetY);
$("#downlog").html("Down: "+ canMouseX + " / " + canMouseY);
// Put your mousedown stuff here
var text=document.getElementById("text").value;
ctx.font = 'italic 20px sans-serif';
ctx.fillText(text,canMouseX,canMouseY);
}
$("#canvas").mousedown(function(e){handleMouseDown(e);});
}); // end $(function(){});
</script>
</head>
<body>
<p>Enter the text here first</p>
<input id="text" type="text" name="text" value="My Text."><br>
<p>Then click on the canvas to draw the text.</p>
<canvas id="canvas" width=576 height=307></canvas>
</body>
</html>

Categories