I have a canvas where on "mousemove" i want draw on it:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
var isDown = false;
var lastPoint = {x: 0, y: 0};
function onMouseDown(event) {
isDown = true;
var point = getCanvasPointOfMouseEvent(event);
ctx.beginPath();
ctx.moveTo(point.x, point.y);
lastPoint = point;
}
function onMouseMove(event) {
if ( isDown !== false) {
var point = getCanvasPointOfMouseEvent(event);
ctx.beginPath();
ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
ctx.lineWidth = '10';
ctx.lineJoin = 'round';
ctx.moveTo(lastPoint.x, lastPoint.y);
ctx.lineTo(point.x, point.y);
ctx.closePath();
ctx.stroke();
lastPoint = point;
}
}
function onMouseUp(event) {
isDown = false;
ctx.closePath();
}
function getCanvasPointOfMouseEvent(event) {
var canvasX = (event.pageX - canvas.offsetLeft);
var canvasY = (event.pageY - canvas.offsetTop);
return {x: canvasX, y: canvasY};
}
#canvas {
border: 1px solid red;
cursor: crosshair;
}
<canvas width="250px" height="250px" onmousedown="onMouseDown(event)" onmousemove="onMouseMove(event)" onmouseup="onMouseUp(event)" id="canvas">
Your browser doesn't support canvas!
</canvas>
The output is lines with dots:
but i want only lines, like this:
how fix it?
Basics is clear all and redraw all.
To achieve this, you'll have to store all the coordinates in an array, and each time you want to draw, to create a new sub-path with all the stored coordinates.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
var isDown = false;
var points = [];
function onMouseDown(event) {
var point = getCanvasPointOfMouseEvent(event);
points.push(point); // store
redrawAll(); // clearAll and redraw
isDown = true; // make it last so we can grab the isStart below
}
function onMouseMove(event) {
if ( isDown !== false) {
var point = getCanvasPointOfMouseEvent(event);
points.push(point); // store
redrawAll(); // clear all and redraw
}
}
function redrawAll() {
// clear all
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
ctx.lineWidth = '10';
ctx.lineJoin = 'round';
// redraw as a single sub-path
ctx.beginPath();
points.forEach(function(pt) {
if(pt.isStart) ctx.moveTo(pt.x, pt.y);
else ctx.lineTo(pt.x, pt.y);
});
ctx.stroke();
}
function onMouseUp(event) {
isDown = false;
}
function getCanvasPointOfMouseEvent(event) {
var canvasX = (event.pageX - canvas.offsetLeft);
var canvasY = (event.pageY - canvas.offsetTop);
return {x: canvasX, y: canvasY, isStart: !isDown};
}
#canvas {
border: 1px solid red;
cursor: crosshair;
}
<canvas width="250px" height="250px" onmousedown="onMouseDown(event)" onmousemove="onMouseMove(event)" onmouseup="onMouseUp(event)" id="canvas">
Your browser doesn't support canvas!
</canvas>
If you want each mouseup to create a new sub-path (and hence have these mix up when passing twice at the same coords), you just have to slightly modify the redrawAll function:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
var isDown = false;
var points = [];
function onMouseDown(event) {
var point = getCanvasPointOfMouseEvent(event);
points.push(point);
redrawAll();
isDown = true;
}
function onMouseMove(event) {
if ( isDown !== false) {
var point = getCanvasPointOfMouseEvent(event);
points.push(point);
redrawAll();
}
}
function redrawAll() {
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
ctx.lineWidth = '10';
ctx.lineJoin = 'round';
ctx.beginPath();
points.forEach(function(pt) {
if(pt.isStart){
ctx.stroke(); // draw previous
ctx.beginPath(); // begin a new sub-path
}
ctx.lineTo(pt.x, pt.y); // will moveTo automatically if needed
});
ctx.stroke();
}
function onMouseUp(event) {
isDown = false;
}
function getCanvasPointOfMouseEvent(event) {
var canvasX = (event.pageX - canvas.offsetLeft);
var canvasY = (event.pageY - canvas.offsetTop);
return {x: canvasX, y: canvasY, isStart: !isDown};
}
#canvas {
border: 1px solid red;
cursor: crosshair;
}
<canvas width="250px" height="250px" onmousedown="onMouseDown(event)" onmousemove="onMouseMove(event)" onmouseup="onMouseUp(event)" id="canvas">
Your browser doesn't support canvas!
</canvas>
Related
It is a simple code trying to change the color of a polygon in javascript
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var polygon = [
[100, 100],
[100, 200],
[200, 200],
[200, 100]
];
// Draw the polygon
ctx.fillStyle = "black";
ctx.beginPath();
ctx.moveTo(polygon[0][0], polygon[0][1]);
for (var i = 1; i < polygon.length; i++) {
ctx.lineTo(polygon[i][0], polygon[i][1]);
}
ctx.closePath();
ctx.fill();
// Add event listener to change the color of the polygon when clicked
canvas.addEventListener("click", function(event) {
var x = event.pageX - canvas.offsetLeft;
var y = event.pageY - canvas.offsetTop;
ctx.beginPath();
ctx.moveTo(polygon[0][0], polygon[0][1]);
for (var i = 1; i < polygon.length; i++) {
ctx.lineTo(polygon[i][0], polygon[i][1]);
}
ctx.closePath();
if (ctx.isPointInPath(x, y)) {
if (ctx.fillStyle == "black") {
ctx.fillStyle = "red";
} else {
ctx.fillStyle = "pink";
}
ctx.fill();
}
});
<canvas id="myCanvas" width="400" height="400"></canvas>
It changes the color to pink on first click. It does not matter if instead of Color Names I use Hex Values or RGB (Red; #FF0000; rgb(255,0,0))
I works to me using HEX values:
<html>
<body>
<canvas id="myCanvas" width="400" height="400"></canvas>
<script>
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var polygon = [
[100, 100],
[100, 200],
[200, 200],
[200, 100]
];
// Draw the polygon
ctx.fillStyle = "black";
ctx.beginPath();
ctx.moveTo(polygon[0][0], polygon[0][1]);
for (var i = 1; i < polygon.length; i++) {
ctx.lineTo(polygon[i][0], polygon[i][1]);
}
ctx.closePath();
ctx.fill();
// Add event listener to change the color of the polygon when clicked
canvas.addEventListener("click", function(event) {
var x = event.pageX - canvas.offsetLeft;
var y = event.pageY - canvas.offsetTop;
ctx.beginPath();
ctx.moveTo(polygon[0][0], polygon[0][1]);
for (var i = 1; i < polygon.length; i++) {
ctx.lineTo(polygon[i][0], polygon[i][1]);
}
ctx.closePath();
if (ctx.isPointInPath(x, y)) {
if (ctx.fillStyle == "#ffc0cb") {
ctx.fillStyle = "#ff0000";
} else {
ctx.fillStyle = "#ffc0cb";
}
ctx.fill();
}
});
</script>
</body>
</html>
To do that I just created another variable and used it:
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var ctx_color = "black";
...
if (ctx.isPointInPath(x, y)) {
console.log(ctx.fillStyle);
if (ctx_color == "black") {
ctx.fillStyle = "red";
ctx_color = "red";
} else {
ctx.fillStyle = "pink";
ctx_color = "pink";
}
ctx.fill();
}
If you want to change your color by rgb u can check this link How do I write a RGB color value in JavaScript?
I try to make paint app in javascript. I need to make square grid and by pushing button. I made such grid but it is not on the background. How should I pass grid made by js on the background?
function print_grid()
{
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillRect(0, 0, 5100, 5100);
ctx.clearRect(0, 0, 5100, 5100);
ctx.beginPath();
for (let i = 0; i < 39; i++)
{
ctx.lineWidth = 1;
ctx.moveTo(50*i, 0);
ctx.lineTo(50*i, 5100);
ctx.moveTo(0, 50*i);
ctx.lineTo(5100, 50*i);
}
ctx.stroke();
}
<!DOCTYPE html>
<html>
<body>
<h1>Board</h1>
<button onclick="print_grid()">square</button>
<p >draw!!!</p>
<canvas id="myCanvas" width="1000" height="1000" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
</body>
</html>
One easy solution is using two canvases layered on top of each other. This way you can draw the grid onto the background layer independent from the canvas in the foreground.
Here's an example:
const canvas = document.getElementById('canvas2');
const ctx = canvas.getContext('2d');
let coordinates = {
x: 0,
y: 0
};
let painting = false;
function getPosition(event) {
coordinates.x = event.clientX - canvas.offsetLeft;
coordinates.y = event.clientY - canvas.offsetTop;
}
function startPainting(event) {
painting = true;
getPosition(event);
}
function stopPainting() {
painting = false;
}
function draw(event) {
if (!painting) return;
ctx.beginPath();
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.strokeStyle = 'red';
ctx.moveTo(coordinates.x, coordinates.y);
getPosition(event);
ctx.lineTo(coordinates.x, coordinates.y);
ctx.stroke();
}
function clearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
function printGrid() {
let backgroundCanvas = document.getElementById('canvas');
let context = backgroundCanvas.getContext("2d");
context.beginPath();
for (let a = 0; a < 10; a++) {
context.moveTo(0, parseInt(a * (backgroundCanvas.height / 9)));
context.lineTo(backgroundCanvas.width, parseInt(a * (backgroundCanvas.height / 9)));
context.moveTo(parseInt(a * (backgroundCanvas.width / 9)), 0);
context.lineTo(parseInt(a * (backgroundCanvas.width / 9)), backgroundCanvas.height);
}
context.stroke();
context.closePath();
}
printGrid();
document.addEventListener('mousedown', startPainting);
document.addEventListener('mouseup', stopPainting);
document.addEventListener('mousemove', draw);
<button onclick='clearCanvas();'>Clear</button>
<div>
<canvas id='canvas' style='position: absolute'></canvas>
<canvas id='canvas2' style='position: absolute'></canvas>
</div>
I have a canvas code to draw a signature. The code works perfectly fine with chrome and Firefox but does not draw at all on IE 11.
My canvas is:
<canvas id="signitureCanvas" style="border: 3px solid #000; cursor:crosshair; background-color:white;"></canvas>
My code is as below:
var canvas = document.getElementById('signitureCanvas');
var ctx = canvas.getContext('2d');
var canvasWidth = 200;
var canvasLength = 120;
canvas.width = canvasWidth;
canvas.height = canvasLength;
var canvasx = $(canvas).offset().left;
var canvasy = $(canvas).offset().top;
var last_mousex = last_mousey = 0;
var mousex = mousey = 0;
var mousedown = false;
var tooltype = 'draw';
//Mousedown
$(canvas).on('mousedown', function (e) {
last_mousex = mousex = parseInt(e.clientX - canvasx);
last_mousey = mousey = parseInt(e.clientY - canvasy);
mousedown = true;
});
//Mouseup
$(canvas).on('mouseup', function (e) {
mousedown = false;
});
//Mousemove
$(canvas).on('mousemove', function (e) {
mousex = parseInt(e.clientX - canvasx);
mousey = parseInt(e.clientY - canvasy);
if (mousedown) {
ctx.beginPath();
if (tooltype == 'draw') {
ctx.globalCompositeOperation = 'source-over';
ctx.strokeStyle = 'black';
ctx.lineWidth = 3;
} else {
ctx.globalCompositeOperation = 'destination-out';
ctx.lineWidth = 10;
}
ctx.moveTo(last_mousex, last_mousey);
ctx.lineTo(mousex, mousey);
ctx.lineJoin = ctx.lineCap = 'round';
ctx.stroke();
}
last_mousex = mousex;
last_mousey = mousey;
});
function ClearCanvas() {
var canvas = document.getElementById('signitureCanvas');
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
Is IE 11 in particular having problems?
Edit:
I figured out the problem is with my Iframe:
When height and width are set to 300 everything works fine:
<embed id="fred" type="application/pdf" style="border:1px solid #666CCC" title="PDF in an i-Frame" src="#Model.FilePath" frameborder="1" scrolling="yes" height="300" width="300" />
When I set it to 1000, it won't work:
<embed id="fred" type="application/pdf" style="border:1px solid #666CCC" title="PDF in an i-Frame" src="#Model.FilePath" frameborder="1" scrolling="yes" height="1000" width="1000" />
I believe it's something with the offset but I can't figure how to fix it.
any help?
For further knowledge to whom might ask:
I have found this piece of code that works on all browsers, layerX and layerY are different for firefox browsers:
var canvas = document.getElementById('signitureCanvas');
var ctx = canvas.getContext('2d');
var canvasWidth = 200;
var canvasLength = 120;
canvas.width = canvasWidth;
canvas.height = canvasLength;
var x = 0;
var y = 0;
function tool_pencil() {
var tool = this;
this.started = false;
// This is called when you start holding down the mouse button
// This starts the pencil drawing
this.mousedown = function (ev) {
ctx.beginPath();
ctx.strokeStyle = 'black';
ctx.lineWidth = 3;
ctx.lineJoin = ctx.lineCap = 'round';
ctx.moveTo(x, y);
tool.started = true;
};
// This function is called every time you move the mouse. Obviously, it only
// draws if the tool.started state is set to true (when you are holding down
// the mouse button)
this.mousemove = function (ev) {
if (tool.started) {
ctx.lineTo(x, y);
ctx.stroke();
}
};
// This is called when you release the mouse button
this.mouseup = function (ev) {
if (tool.started) {
tool.mousemove(ev);
tool.started = false;
}
};
}
// The general-purpose event handler. This function just determines
// the mouse position relative to the <canvas> element
function ev_canvas(ev) {
// Firefox
if (ev.offsetX || ev.offsetX == 0) {
x = ev.offsetX;
y = ev.offsetY;
// Opera
} else if (ev.layerX || ev.layerX == 0) {
x = ev.layerX;
y = ev.layerX;
}
// Call the event handler of the tool
var func = tool[ev.type];
if (func) {
func(ev);
}
}
function ClearCanvas() {
var canvas = document.getElementById('signitureCanvas');
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
I need help trying to rotate the rectangle that I have drawn on the canvas. I would like the top of the rectangle to pivot either to the right or left once I press on the arrow keys on my keyboard. This is my code so far:
HTML:
<body >
<div id="canvas-container">
<canvas id="canvas" width="500" height="400"></canvas>
</div>
</body>
CSS:
canvas {
display: inline;
}
Javascript:
document.addEventListener("DOMContentLoaded", function() {
drawBorder();
});
var canvas;
var context;
var size;
drawRectangle();
drawHalfCircle();
function drawBorder() {
canvas = document.getElementById("canvas");
context = canvas.getContext('2d');
size = {
x: canvas.width,
y: canvas.height
};
//have to set colors etc befor it is drawn
context.strokeStyle = 'black';
//takes 4 parameters
context.strokeRect(0, 0, size.x, size.y);
}
function drawRectangle() {
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
ctx.rect(246, 290, 8, 80);
ctx.stroke();
}
function drawHalfCircle(){
var c= document.getElementById("canvas");
var ctx=c.getContext("2d");
ctx.beginPath();
ctx.arc(250,579,308,1.2*Math.PI, 1.8*Math.PI);
ctx.stroke();
}
I have mocked something up is this along the correct lines of what you are wanting.
document.addEventListener("DOMContentLoaded", function() {
drawBorder();
});
var canvas = document.getElementById("canvas");
var context = canvas.getContext('2d');
var size;
var angle = 0;
setInterval(function () {
context.save();
context.clearRect(0, 0, canvas.width, canvas.height);
drawBorder();
drawHalfCircle();
drawRectangle();
context.restore();
}, 100);
function drawBorder() {
size = {
x: canvas.width,
y: canvas.height
};
//have to set colors etc befor it is drawn
context.strokeStyle = 'black';
//takes 4 parameters
context.strokeRect(0, 0, size.x, size.y);
}
function drawRectangle() {
context.rotate(Math.PI / 180 * (angle));
context.rect(246, 290, 8, 80);
context.stroke();
}
function drawHalfCircle(){
context.beginPath();
context.arc(250,579,308,1.2*Math.PI, 1.8*Math.PI);
context.stroke();
}
document.onkeydown = function(e) {
var event = window.event ? window.event : e;
if (e.keyCode == '37') {
angle += 5;
}
else if (e.keyCode == '39') {
angle -= 5;
}
}
Basically set an interval and redraw (ie frames like in a movie) and rotate via a variable.
See a demo here
https://jsbin.com/qititacazu/edit?js,output
If you want to translate it so it will rotate around a different point do something like this.
context.translate(246, 290);
context.rotate(Math.PI / 180 * (angle));
context.rect(-4, 0, 4, 80);
Can you please take a look at following demo and let me know how I can enable the code to draw 100% straight Line on the canvas?
$(function() {
var drawLine = false;
var theCanvas = document.getElementById('map');
var ctx = theCanvas.getContext('2d');
theCanvas.width = 420;
theCanvas.height = 300;
var canvasOffset = $('#map').offset();
$('#map').mousemove(function(e) {
if (drawLine === true) {
ctx.lineTo(e.pageX - canvasOffset.left, e.pageY - canvasOffset.top);
ctx.stroke();
}
});
$('#map').mousedown(function() {
drawLine = true;
ctx.strokeStyle = 'blue';
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(e.pageX - canvasOffset.left, e.pageY - canvasOffset.top);
});
$(window).mouseup(function() {
drawLine = false;
});
});
#map{border:solid; margin-top: 50px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<canvas id="map"></canvas>
As you can see the code is working fine but what I want is drawing a straight line on drawing
Thanks
You would need to have 2 canvases:
temporary for animation
permanent to store drawing.
Algorithm:
ondown write start coordinates.
onmove record endpoint, clear canvas 1, draw a line on canvas 1 from start point to end point.
onup draw final line on 2nd canvas clear 1st canvas.
Too lazy create second canvas (it'll clear it every try now);
Put a comment where pass different canvas for permanent draw
$(function() {
var drawLine = false;
var theCanvas = document.getElementById('map');
var finalPos = {x:0, y:0};
var startPos = {x:0, y:0};
var ctx = theCanvas.getContext('2d');
theCanvas.width = 420;
theCanvas.height = 300;
var canvasOffset = $('#map').offset();
function line(cnvs) {
cnvs.beginPath();
cnvs.moveTo(startPos.x, startPos.y);
cnvs.lineTo(finalPos.x, finalPos.y);
cnvs.stroke();
}
function clearCanvas()
{
ctx.clearRect(0, 0, theCanvas.width, theCanvas.height);
}
$('#map').mousemove(function(e) {
if (drawLine === true) {
finalPos = {x: e.pageX - canvasOffset.left, y:e.pageY - canvasOffset.top};
clearCanvas();
line(ctx);
}
});
$('#map').mousedown(function(e) {
drawLine = true;
ctx.strokeStyle = 'blue';
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.beginPath();
startPos = { x: e.pageX - canvasOffset.left, y: e.pageY - canvasOffset.top};
});
$(window).mouseup(function() {
clearCanvas();
// Replace with var that is second canvas
line(ctx);
finalPos = {x:0, y:0};
startPos = {x:0, y:0};
drawLine = false;
});
});
#map{border:solid; margin-top: 50px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<canvas id="map"></canvas>