So, I have a canvas, and I have a bunch of functions on it, but I was trying to make it so that it would show the x and y positions of the mouse on the canvas in the label above. But, when I run the mouse over, the x and y positions of the mouse on the canvas do not match the x and y positions shown on the label, and I cannot figure out why. Can you please help? My Code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Canvas Library</title>
</head>
<body>
<p id="text">Unknown</p>
<canvas width="400" height="400" id="canvas"></canvas>
<script>
var Canvas = document.getElementById("canvas");
var label = document.getElementById("text");
//Declare the Canvas Object
var canvas = function(src) {
//The Canvas to draw on
this.src = src;
//The context of source(used for drawing)
this.ctx = this.src.getContext("2d");
//The Mouse Move Function
this.showCoordinates = function(e) {
console.log(e);
label.innerHTML = "<b>x: </b>" + e.layerX + " <b>y: </b>" + e.layerY;
}
//Show coordinates variable
this.showCoordinatesBool = true;
//The boolean to tell if we should use stroke
var useStroke = true;
//The fill style and stroke style(can be color, pattern, or gradient)
this.fillStyle = "#000000";
this.strokeStyle = "#000000";
//The Line cap style (can be butt, square, or round)
this.lineCap = "butt";
//The Stroke Weight (how wide the strokes are)
this.strokeWeightVar = "default";
//The corner style (how the corners are drawn)
this.cornerStyle = "miter";
//Function to set the fill style
this.fill = function(style) {
this.fillStyle = style;
this.ctx.fillStyle = style;
}
//Function to set the stroke style
this.stroke = function(style) {
this.useStroke = true;
this.strokeStyle = style;
this.ctx.strokeStyle = style;
}
//Function to delete the stroke
this.noStroke = function() {
this.useStroke = false;
}
//Function to draw a rectangle
this.rect = function(x, y, width, height) {
this.ctx.fillRect(x, y, width, height);
if(this.useStroke) {
this.ctx.strokeRect(x, y, width, height);
}
}
//Function to draw a corner
this.corner = function(style, startX, startY, x1, y1, x2, y2) {
this.ctx.lineJoin = style;
this.cornerStyle = style;
this.ctx.beginPath();
this.ctx.moveTo(startX, startY);
this.ctx.lineTo(x1, y1);
this.ctx.lineTo(x2, y2);
this.ctx.stroke();
}
//Function to draw a hollow rectangle
this.hollowRect = function(x, y, width, height) {
this.ctx.strokeRect(x, y, width, height);
}
//Function to set the canvas background
this.background = function(style) {
this.fillStyle = style;
this.ctx.fillStyle = style;
this.ctx.fillRect(0, 0, this.src.width, this.src.height);
}
//Function to draw a line
this.line = function(startX, startY, endX, endY) {
this.ctx.beginPath();
this.ctx.moveTo(startX, startY);
this.ctx.lineTo(endX, endY);
this.ctx.stroke();
}
//Function to change line style
this.lineCap = function(mode) {
this.ctx.lineCap = mode;
this.lineCap = mode;
}
//Function to change stroke weight
this.strokeWeight = function(weight) {
this.ctx.lineWidth = weight;
this.strokeWeightVar = weight;
}
//Function to clear a certain area
this.clearArea = function(x, y, width, height) {
this.ctx.clearRect(x, y, width, height);
}
//Turn the show coordinate function on
this.enableCoordinates = function() {
this.showCoordinatesBool = true;
this.src.addEventListener("mousemove", this.showCoordinates);
}
}
//Create a new canvas
var myCanvas = new canvas(Canvas);
//Set the Background Color
myCanvas.background("#ff0000");
//Set the fill color
myCanvas.fill("#0000ff");
//Set the Stroke Color
myCanvas.stroke("#00ff00");
//Draw a rectangle
myCanvas.rect(164, 153, 50, 100);
//Draw a hollow rectangle
myCanvas.hollowRect(300, 300, 50, 50);
//Disable the Stroke
myCanvas.noStroke();
//Draw a rectangle with no stroke
myCanvas.rect(21, 18, 50, 50);
//Change the Stroke color
myCanvas.stroke("#ffff00");
//Change the stroke weight
myCanvas.strokeWeight(10);
//Change the line cap
myCanvas.lineCap("round");
//Draw a line
myCanvas.line(350, 30, 250, 80);
//Draw a corner
myCanvas.corner("miter", 50, 135, 100, 185, 100, 110)
//Enable the Coordinates
myCanvas.enableCoordinates();
//Clear a space from the canvas
myCanvas.clearArea(6, 245, 100, 100);
</script>
</body>
</html>
You can get proper mouse coordinates relative to the canvas, using offsetX and offsetY property of MouseEvent.
...
this.showCoordinates = function(e) {
label.innerHTML = "<b>x: </b>" + e.offsetX + " <b>y: </b>" + e.offsetY;
}
...
var Canvas = document.getElementById("canvas");
var label = document.getElementById("text");
//Declare the Canvas Object
var canvas = function(src) {
//The Canvas to draw on
this.src = src;
//The context of source(used for drawing)
this.ctx = this.src.getContext("2d");
//The Mouse Move Function
this.showCoordinates = function(e) {
//console.log(e);
label.innerHTML = "<b>x: </b>" + e.offsetX + " <b>y: </b>" + e.offsetY;
}
//Show coordinates variable
this.showCoordinatesBool = true;
//The boolean to tell if we should use stroke
var useStroke = true;
//The fill style and stroke style(can be color, pattern, or gradient)
this.fillStyle = "#000000";
this.strokeStyle = "#000000";
//The Line cap style (can be butt, square, or round)
this.lineCap = "butt";
//The Stroke Weight (how wide the strokes are)
this.strokeWeightVar = "default";
//The corner style (how the corners are drawn)
this.cornerStyle = "miter";
//Function to set the fill style
this.fill = function(style) {
this.fillStyle = style;
this.ctx.fillStyle = style;
}
//Function to set the stroke style
this.stroke = function(style) {
this.useStroke = true;
this.strokeStyle = style;
this.ctx.strokeStyle = style;
}
//Function to delete the stroke
this.noStroke = function() {
this.useStroke = false;
}
//Function to draw a rectangle
this.rect = function(x, y, width, height) {
this.ctx.fillRect(x, y, width, height);
if (this.useStroke) {
this.ctx.strokeRect(x, y, width, height);
}
}
//Function to draw a corner
this.corner = function(style, startX, startY, x1, y1, x2, y2) {
this.ctx.lineJoin = style;
this.cornerStyle = style;
this.ctx.beginPath();
this.ctx.moveTo(startX, startY);
this.ctx.lineTo(x1, y1);
this.ctx.lineTo(x2, y2);
this.ctx.stroke();
}
//Function to draw a hollow rectangle
this.hollowRect = function(x, y, width, height) {
this.ctx.strokeRect(x, y, width, height);
}
//Function to set the canvas background
this.background = function(style) {
this.fillStyle = style;
this.ctx.fillStyle = style;
this.ctx.fillRect(0, 0, this.src.width, this.src.height);
}
//Function to draw a line
this.line = function(startX, startY, endX, endY) {
this.ctx.beginPath();
this.ctx.moveTo(startX, startY);
this.ctx.lineTo(endX, endY);
this.ctx.stroke();
}
//Function to change line style
this.lineCap = function(mode) {
this.ctx.lineCap = mode;
this.lineCap = mode;
}
//Function to change stroke weight
this.strokeWeight = function(weight) {
this.ctx.lineWidth = weight;
this.strokeWeightVar = weight;
}
//Function to clear a certain area
this.clearArea = function(x, y, width, height) {
this.ctx.clearRect(x, y, width, height);
}
//Turn the show coordinate function on
this.enableCoordinates = function() {
this.showCoordinatesBool = true;
this.src.addEventListener("mousemove", this.showCoordinates);
}
}
//Create a new canvas
var myCanvas = new canvas(Canvas);
//Set the Background Color
myCanvas.background("#ff0000");
//Set the fill color
myCanvas.fill("#0000ff");
//Set the Stroke Color
myCanvas.stroke("#00ff00");
//Draw a rectangle
myCanvas.rect(164, 153, 50, 100);
//Draw a hollow rectangle
myCanvas.hollowRect(300, 300, 50, 50);
//Disable the Stroke
myCanvas.noStroke();
//Draw a rectangle with no stroke
myCanvas.rect(21, 18, 50, 50);
//Change the Stroke color
myCanvas.stroke("#ffff00");
//Change the stroke weight
myCanvas.strokeWeight(10);
//Change the line cap
myCanvas.lineCap("round");
//Draw a line
myCanvas.line(350, 30, 250, 80);
//Draw a corner
myCanvas.corner("miter", 50, 135, 100, 185, 100, 110)
//Enable the Coordinates
myCanvas.enableCoordinates();
//Clear a space from the canvas
myCanvas.clearArea(6, 245, 100, 100);
<p id="text">Unknown</p>
<canvas width="400" height="400" id="canvas"></canvas>
Related
I would like to create a pettern with canvas. The Picture which should be used should also be gernerated first. I already did something like this with this code:
document.addEventListener('DOMContentLoaded', function () {
async function draw() {
var canvas = document.getElementById('canvas1')
var ctx = canvas.getContext("2d");
var canvas = ctx.createImageData(500, 300);
ctx.fillStyle = "#7289DA";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Select the color of the stroke
ctx.strokeStyle = '#74037b';
// Draw a rectangle with the dimensions of the entire canvas
ctx.strokeRect(0, 0, canvas.width, canvas.height);
ctx.font = 'bold 70px sans-serif';
// Select the style that will be used to fill the text in
ctx.save();
ctx.rotate(1.7*Math.PI);
ctx.fillStyle = '#23272A';
ctx.fillText('Text', -70, 300);
ctx.restore();
// Actually fill the text with a solid color
}
draw();
});
<canvas id="canvas" width="1500" height="900">Beispiel für eine Kachelung eines Musters in Canvas.</canvas>
Now I want to create some kind of grid with it, it should look like this
How can I do that?
The best way would be using two for loops to go over the x and y values! You can surround the part that draws text with these loops and use the changing x and y values instead of hard-coded ones.
async function draw() {
var canvas = document.getElementById('canvas1')
var ctx = canvas.getContext("2d");
var canvas = ctx.createImageData(500, 300);
ctx.fillStyle = "#7289DA";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Select the color of the stroke
ctx.strokeStyle = '#74037b';
// Draw a rectangle with the dimensions of the entire canvas
ctx.strokeRect(0, 0, canvas.width, canvas.height);
ctx.font = 'bold 70px sans-serif';
ctx.fillStyle = '#23272A';
// Select the style that will be used to fill the text in
for (var x = 0; x < canvas.width; x += 100 ) { // 100 is the width
for (var y = 0; y < canvas.height; y += 70) { // 70 is the height
ctx.save();
ctx.translate(x, y); // offset the text
ctx.rotate(1.7*Math.PI);
ctx.fillText('Text', -70, 300);
ctx.restore();
// Actually fill the text with a solid color
}
}
}
The reason ctx.translate(x, y) is used instead of ctx.fillText('Text', x - 70, y + 300) is because using fillText would move the grid at an angle instead of just rotating the letters.
I have an ASP.NET application that allows users to click or tap on a Canvas to indicate pain locations on a body image. A body image is displayed on the Canvas and is the same size as the Canvas.
function drawBodyMap() {
var c = document.getElementById('myCanvas');
var ctx = c.getContext('2d');
var imageObj = new Image();
imageObj.src = 'https://.../body.jpg';
imageObj.onload = function () {
ctx.drawImage(imageObj, 0, 0, 600, 367);
};
}
<canvas id="myCanvas" width="600" height="367"></canvas>
<script>
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
canvas.addEventListener('mouseup', function (evt) {
if (ixPos > 9)
return;
var mousePos = getMousePos(canvas, evt);
bodyX[ixPos] = mousePos.x;
bodyY[ixPos] = mousePos.y;
painType[ixPos] = pain_type;
ixPos++;
ctx.beginPath();
ctx.arc(mousePos.x, mousePos.y, 8, 0, 2 * Math.PI);
if (pain_type == 1)
ctx.fillStyle = "#DC143C";
else if (pain_type == 2)
ctx.fillStyle = "#EA728A";
else if (pain_type == 3)
ctx.fillStyle = "#DAA520";
else if (pain_type == 4)
ctx.fillStyle = "#008000";
else if (pain_type == 5)
ctx.fillStyle = "#4169E1";
ctx.fill();
}, false);
</script>
The X,Y points added to the Canvas on the body image are saved to a database. These points are then loaded into a WPF application that displays the same body image on an XAML Canvas. C# code then adds the points over the image.
WPF CODE:
private void DisplayBodyPain()
{
List<BodyPain> pain = gFunc.sws.GetBodyPain(MemberID);
foreach (BodyPain bp in pain)
{
Border b = new Border();
b.Tag = bp.PainType.ToString();
b.Cursor = Cursors.Hand;
b.Width = 16;
b.Height = 16;
b.CornerRadius = new CornerRadius(8);
b.Background = GetPainBrush((byte)bp.PainType);
cvsBody.Children.Add(b);
Canvas.SetTop(b, bp.YPos);
Canvas.SetLeft(b, bp.XPos);
}
}
The problem I have is that the points drawn on the XAML Canvas are all slightly different from the points that were drawn on the HTML Canvas. Each point is not in exactly the same location.
Is there a way I can fix this? Should I be doing it differently?
HTML Canvas
WPF Canvas
I think you need to subtract the size of the marker from the coordinate where you want to place it. For the last two lines, try this instead:
Canvas.SetTop(b, bp.YPos - (b.Height / 2));
Canvas.SetLeft(b, bp.XPos - (b.Width / 2));
By subtracting half the marker's height and width, the center of the marker is placed on the desired coordinates.
I have this simple canvas webpage that lets user upload photo from camera by using HTML input type file. The idea is to let user make free drawing on their image. However, I have one problem.
On some devices, the image from camera is drawn onto the canvas with wrong orientation, so I have to provide users a button to rotate their image to get the drawing with correct orientation.
The problem is that after the canvas has been transformed and rotated to get the correct orientation, the drawing coordinates seems to be way off. For example, if I draw straight horizontal line, I get instead straight vertical line after the image has been rotated once. I think the problem lies in that fact that canvas orientation is changed.
So how can I correct back the drawing coordinate after image has been transformed and rotate? My code is below..
window.onload = init;
var canvas, ctx, file, fileURL;
var mousePressed = false;
var lastX, lastY;
function init(){
canvas = document.getElementById('myCanvas')
ctx = canvas.getContext('2d')
canvas.addEventListener('mousedown', touchstartHandler, false)
canvas.addEventListener('mousemove', touchmoveHandler, false)
canvas.addEventListener('mouseup', touchendHandler, false)
canvas.addEventListener('mouseleave', touchcancelHandler, false)
}
function touchstartHandler(e){
e.preventDefault()
mousePressed = true;
Draw(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, false);
}
function touchmoveHandler(e){
e.preventDefault()
if (mousePressed) {
Draw(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
}
}
function touchendHandler(e){
e.preventDefault()
if (mousePressed) {
mousePressed = false;
}
}
function touchcancelHandler(e){
e.preventDefault()
if (mousePressed) {
mousePressed = false;
}
}
function Draw(x, y, isDown) {
if (isDown) {
ctx.beginPath();
ctx.strokeStyle = "blue";
ctx.lineWidth = 12;
ctx.lineJoin = "round";
ctx.moveTo(lastX, lastY);
ctx.lineTo(x, y);
ctx.closePath();
ctx.stroke();
}
lastX = x;
lastY = y;
}
<!DOCTYPE html>
<html>
<head>
<title>Portrait</title>
</head>
<body>
<canvas id="myCanvas"></canvas><br/>
<input type="file" onchange="fileUpload(this.files)" id="file-input" capture="camera"><br/><br/>
<button onclick="rotate()">Rotate</button>
<script>
var file, canvas, ctx, image, fileURL;
function fileUpload(files){
file = files[0]
fileURL = URL.createObjectURL(file)
canvas = document.getElementById('myCanvas')
canvas.style.backgroundColor = "blue"
ctx = canvas.getContext('2d')
image = new Image()
image.onload = function() {
canvas.width = 500
canvas.height = (500*this.height)/this.width
ctx.drawImage(image,0,0,canvas.width,canvas.height)
ctx.save();
}
image.src = fileURL
}
function rotate(){
ctx.clearRect(0,0,canvas.width,canvas.height)
ctx.translate(canvas.width/2, canvas.height/2)
ctx.rotate(90*Math.PI/180)
ctx.translate(-canvas.width/2, -canvas.height/2)
ctx.drawImage(image,0,0,canvas.width,canvas.height)
}
</script>
</body>
</html>
You need to save the canvas state before rotating and translating, and then restore the state when the transformation is done.
var file, canvas, ctx, image, fileURL, rotation = 90;
function fileUpload(files) {
file = files[0]
fileURL = URL.createObjectURL(file)
canvas = document.getElementById('myCanvas')
canvas.style.backgroundColor = "blue"
ctx = canvas.getContext('2d')
image = new Image()
image.onload = function() {
canvas.width = 500
canvas.height = (500 * this.height) / this.width
ctx.drawImage(image, 0, 0, canvas.width, canvas.height)
}
image.src = fileURL
}
function rotate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save(); //save canvas state
ctx.translate(canvas.width / 2, canvas.height / 2);
ctx.rotate(rotation * Math.PI / 180);
ctx.translate(-canvas.width / 2, -canvas.height / 2);
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
rotation += 90;
ctx.restore(); //restore canvas state
}
canvas {border: 1px solid red}
<canvas id="myCanvas"></canvas>
<br/>
<input type="file" onchange="fileUpload(this.files)" id="file-input" capture="camera">
<br/>
<br/>
<button onclick="rotate()">Rotate</button>
Simple rotation
Quickest way to rotate the image by steps of 90 deg
ctx.setTransform(
0,1, // direction of x axis
-1,0 // direction of y axis
canvas.width,0 // location in pixels of the origin (0,0)
);
Then draw the image
ctx.drawImage(image,0,0);
Rather than use ctx.restore() that can be slow in many situations you can eset only the transform to the default with.
ctx.setTransform(1,0,0,1,0,0);
Rotate 90, 180, -90deg
Thus to rotate 90 deg
ctx.setTransform(0,1,-1,0,canvas.width,0);
ctx.drawImage(image,0,0);
ctx.setTransform(1,0,0,1,0,0);
Thus to rotate 180 deg
ctx.setTransform(-1,0,0,-1,canvas.width,canvas.height);
ctx.drawImage(image,0,0);
ctx.setTransform(1,0,0,1,0,0);
Thus to rotate -90 deg
ctx.setTransform(0,-1,1,0,0,canvas.height);
ctx.drawImage(image,0,0);
ctx.setTransform(1,0,0,1,0,0);
i have set red text marker , but i want to show obviously,
how to change marker color per second (for example like red and blue change per second )?
Is this possible?
function createMarkerIcon(text, opt) {
var defaultOptions =
{
fontStyle: "normal", //normal, bold, italic
fontName: "Arival",
fontSize: 12,
bgColor: "#999999",
fgColor: "white",
padding: 4,
arrowHeight: 6
};
options = $.extend(defaultOptions, opt);
var canvas = document.createElement("canvas"),
context = canvas.getContext("2d");
var font = options.fontStyle + " " + options.fontSize + "px " +
options.fontName;
context.font = font;
var metrics = context.measureText(text);
var w = metrics.width + options.padding * 2;
var h = options.fontSize + options.padding * 2 +options.arrowHeight;
canvas.width = w;
canvas.height = h;
context.beginPath();
context.rect(0, 0, w, h - options.arrowHeight);
context.fillStyle = options.bgColor;
context.fill();
context.beginPath();
var x = w / 2, y = h, arwSz = options.arrowHeight;
context.moveTo(x, y);
context.lineTo(x - arwSz, y - arwSz);
context.lineTo(x + arwSz, y - arwSz);
context.lineTo(x, y);
context.fill();
context.textAlign = "center";
context.fillStyle = options.fgColor;
context.font = font;
context.fillText(text,
w / 2,
(h - options.arrowHeight) / 2 + options.padding);
return canvas.toDataURL();
}
marker = new google.maps.Marker({
position: lat,
map: map,
content: redloc[j][1],
title: addressDetails[5],
icon: createMarkerIcon(addressDetails[3], {
bgColor:"#FF0000" })
//icon: "http://labs.google.com/ridefinder/images/mm_20_green.png"
});
Any help will be greatly appreciated!?
andrew
Marker objects have setIcon() method which can be used to change the icon of the marker. If you want to change icon every x seconds, then you must call setIcon() in setInterval() function:
var color = "red";
setInterval(function() {
if(color === "blue") {
// set color red
marker.setIcon(createMarkerIcon("some text", {
bgColor:"#FF0000" }));
// If you have multiple markers, uncomment below and comment above
/*for(var i = 0; i < markerArray.length; i++) {
markerArray[i].setIcon("http://labs.google.com/ridefinder/images/mm_20_red.png");
}*/
color = "red";
} else {
// set color blue
marker.setIcon(createMarkerIcon("some text again", {
bgColor:"#0900FF" }));
// If you have multiple markers, uncomment below and comment above
/*for(var i = 0; i < markerArray.length; i++) {
markerArray[i].setIcon("http://labs.google.com/ridefinder/images/mm_20_red.png");
}*/
color = "blue";
}
}, 1000 ); // every 1 second
You should add this after you define marker (or if you have multiple markers, add after you push created markers to marker array). Note that I used your createMarkerIcon() as parameter for setIcon().
DEMO -- UPDATED FOR MULTIPLE MARKERS
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.