http://jsbin.com/oMUtePo/1/edit
I've been having a pain trying to get canvas to fill the whole page.
I tried using...
canvas.width = document.body.clientWidth;
canvas.height = document.body.clientHeight;
It filled the width, but not the height, and the drawing board was drawing 1px lines, which is not what I want.
When using 100% for width and height in CSS the width is scaled, and the height is cut, when drawing it looks as if a raster image was scaled significantly larger in ms paint and there's a large offset on onmousedown drawing which is obviously not what I want.
Any help would be greatly appreciated.
Full Code:
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<title>HTML5 Canvas Drawing Board</title>
<style>
* {
margin: 0;
padding: 0;
}
body, html {
height: 100%;
}
#myCanvas {
cursor: crosshair;
position: absolute;
width: 100%;
height: 100%;
}
</style>
<script type="text/JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js?ver=1.4.2"></script>
<script type="text/javascript">
window.onload = function() {
var myCanvas = document.getElementById("myCanvas");
var curColor = $('#selectColor option:selected').val();
var ctx = myCanvas.getContext("2d");
ctx.fillStyle="#000";
ctx.fillRect(0,0,500,500);
if(myCanvas){
var isDown = false;
var canvasX, canvasY;
ctx.lineWidth = 5;
$(myCanvas)
.mousedown(function(e){
isDown = true;
ctx.beginPath();
canvasX = e.pageX - myCanvas.offsetLeft;
canvasY = e.pageY - myCanvas.offsetTop;
ctx.moveTo(canvasX, canvasY);
})
.mousemove(function(e){
if(isDown !== false) {
canvasX = e.pageX - myCanvas.offsetLeft;
canvasY = e.pageY - myCanvas.offsetTop;
ctx.lineTo(canvasX, canvasY);
ctx.strokeStyle = "white";
ctx.stroke();
}
})
.mouseup(function(e){
isDown = false;
ctx.closePath();
});
}
};
</script>
</head>
<body>
<canvas id="myCanvas">
Sorry, your browser does not support HTML5 canvas technology.
</canvas>
</body>
</html>
You have to set the absolute size in pixels on the canvas element and not with CSS as you do in the demo, so first remove the following lines from the CSS rule:
#myCanvas {
cursor: crosshair;
position: absolute;
/*width: 100%; Remove these */
/*height: 100%;*/
}
Then add this to your code - you need to use clientWidth/Height of the window object.
myCanvas.width = window.innerWidth;
myCanvas.height = window.innerHeight;
var ctx = myCanvas.getContext("2d");
ctx.fillStyle="#000";
ctx.fillRect(0,0, myCanvas.width, myCanvas.height);
Your modified JSBIN.
Related
I am trying to make a long drawing canvas, but users can exit drawing mode and go to Hand scroll mode just like you normally scroll website on your phone.
I was thinking to add a scrollbar on the side of the canvas. But it would be better if we can scroll the canvas normally like we reading a website on phone.
html,css code:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="user-scalable=no,initial-scale=1.0,maximum-scale=1.0" />
<style>
.container {
margin: 10px;
overflow: scroll;
}
#main {border: 1px solid #0000ff; overflow: scroll;}
</style>
<script src="draw.js"></script>
</head>
<body>
<div class="container">
<button id="clear">clear button that will clear teh canvas</button><br>
<canvas id="main" width="250" height="1000"></canvas>
</div>
</body>
</html>
javascript code for touch drawing:
window.onload = function() {
document.ontouchmove = function(e){ e.preventDefault(); }
var canvas = document.querySelector('#main');
// const width = canvas.width = window.innerWidth;
// const height = canvas.height = window.innerHeight;
var canvastop = canvas.offsetTop;
var context = canvas.getContext("2d");
var lastx;
var lasty;
context.strokeStyle = "#000000";
context.lineCap = 'round';
context.lineJoin = 'round';
context.lineWidth = 5;
function clear() {
context.fillStyle = "#ffffff";
context.rect(0, 0, 300, 300);
context.fill();
}
function dot(x,y) {
context.beginPath();
context.fillStyle = "#000000";
context.arc(x,y,1,0,Math.PI*2,true);
context.fill();
context.stroke();
context.closePath();
}
function line(fromx,fromy, tox,toy) {
context.beginPath();
context.moveTo(fromx, fromy);
context.lineTo(tox, toy);
context.stroke();
context.closePath();
}
canvas.ontouchstart = function(event){
event.preventDefault();
lastx = event.touches[0].clientX;
lasty = event.touches[0].clientY - canvastop;
dot(lastx,lasty);
}
canvas.ontouchmove = function(event){
event.preventDefault();
var newx = event.touches[0].clientX;
var newy = event.touches[0].clientY - canvastop;
line(lastx,lasty, newx,newy);
lastx = newx;
lasty = newy;
}
var clearButton = document.getElementById('clear')
clearButton.onclick = clear
clear()
}
I don't really understand what you'd like to do. However no need to add 'scroll' to everything.
Try this:
.container {
margin: 10px;
}
#main {
border: 1px solid #0000ff;
width: 250px;
height:600px;
overflow-y: auto
}
And then:
<canvas id="main"></canvas>
In this way your canvas will get a vertical scroll only if its contents is more than 600px, and at the same time you'll be able to scroll the page in a normal way.
I've set up a canvas where I am drawing a line on top of an image (second canvas underneath it). The canvas is fitted into a container. My problem is that when I draw a line (two clicks needed), it is not drawn in the right place.
The goal is to be able that the line will be drawn exactly where I click, even after the canvas is resized to fit the container's size.
My code:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="/Scripts/jquery-1.10.2.min.js"></script>
</head>
<body>
<style>
.container {
position: relative;
width: 50%;
}
canvas {
max-width: 100%;
height: auto;
}
.container > canvas {
position: absolute;
top: 100px;
left: 100px;
}
.container .buttons {
position: absolute;
top: 0;
left: 0;
}
#canvas-bg {
z-index: 0;
}
#canvas-draw {
z-index: 1;
}
</style>
<div class="container">
<canvas id="canvas-draw" width="300" height="150" style="border: 1px solid #d3d3d3;">Your browser does not support the HTML5 canvas tag.</canvas>
<canvas id="canvas-bg" width="300" height="150" style="border: 1px solid #d3d3d3;">Your browser does not support the HTML5 canvas tag.</canvas>
</div>
<script>
var needFirstPoint = true;
function drawNextLine(ctx, x, y) {
if (needFirstPoint) {
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(x, y);
needFirstPoint = false;
}
else {
ctx.lineTo(x, y);
ctx.stroke();
}
}
var canvasDrawing = null;
var canvasImage = null;
var ctxDrawing = null;
var ctxImage = null;
$(document).ready(function () {
canvasDrawing = $('#canvas-draw').get(0);
canvasImage = $("#canvas-bg").get(0);
if (!canvasDrawing.getContext) { return; }
ctxDrawing = canvasDrawing.getContext('2d');
ctxImage = canvasImage.getContext('2d');
function isCanvasBlank(canvas) {
var blank = document.createElement('canvas');
blank.width = canvas.width;
blank.height = canvas.height;
return canvas.toDataURL() == blank.toDataURL();
}
$('#canvas-draw').on('click', function (e) {
if (needFirstPoint == false && isCanvasBlank(canvasDrawing) == false) {
ctxDrawing.clearRect(0, 0, canvasDrawing.width, canvasDrawing.height);
needFirstPoint = true;
return false;
}
var offset = $(this).offset();
var x = e.pageX - offset.left;
var y = e.pageY - offset.top;
drawNextLine(ctxDrawing, x, y);
});
////////////
var imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
function handleImage(e) {
var reader = new FileReader();
reader.onload = function (event) {
var img = new Image();
img.onload = function () {
canvasImage.width = img.width;
canvasImage.height = img.height;
ctxImage.drawImage(img, 0, 0);
// refresh drawing canvas
$('#canvas-draw').width(img.width);
$("#canvas-draw").height(img.height);
canvasDrawing = $('#canvas-draw').get(0);
ctxDrawing = canvasDrawing.getContext('2d');
canvasDrawing.width = img.width;
canvasDrawing.height = img.height;
ctxDrawing.clearRect(0, 0, canvasDrawing.width, canvasDrawing.height);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
});
</script>
<div class="buttons">
Clear canvas
<input type="file" id="imageLoader" name="imageLoader" />
</div>
To accurately poll the pointer position on the Canvas you have to account for it's offset relative to the top-left corner of the screen - as .clientX (.pageX) and .clientY (.pageY) events return the pointer position relative to the browser window not the Canvas itself.
In plain JavaScript something like the following is often used...
/* click event handler */
function canvasClicked(e) {
var cnvBox = document.getElementById('canvas').getBoundingClientRect();
/* canvas-relative values */
var X = e.clientX - cnvBox.left,
Y = e.clientY - cnvBox.top;
}
... and the JQuery way goes something like this...
$("#canvas").click(function(e){
var cnvOffset = $(this).offset();
/* canvas-relative values */
var X = e.pageX - cnvOffset.left,
Y = e.pageY - cnvOffset.top;
});
Hoped that helped :)
I'm having trouble understanding why my code won't draw a square border on the canvas. I just started learning this stuff, and I'm afriad I'm missing something obvious...
<!DOCTYPE html>
<head>
<style type="text/css">
canvas {
background-image: url(uploads/1504975677.jpg);
width: 500px;
height: 334px;
}
</style>
<script type="text/javscript">
var x = 100;
var y = 100;
var width = 50;
var height = 50;
var canvas = document.getElementById('image');
var context = canvas.getContext('2d');
context.strokeStyle = 'white';
context.strokeRect(x, y, width, height);
</script>
<title>Test Website</title>
</head>
<body>
<canvas id="image"></canvas>
</body>
</html>
To clarify, I'm not trying to create a border for the canvas, I just want a box that is not filled in. All I get with this code is the background image and nothing drawn on top of it.
Below should be the format put your script before closing the body tag, Also change the color :-p
<!DOCTYPE html>
<head>
<style type="text/css">
canvas {
background-image: url(uploads/1504975677.jpg);
width: 500px;
height: 334px;
}
</style>
<title>Test Website</title>
</head>
<body>
<canvas id="image"></canvas>
<script type="text/javscript">
var x = 100; var y = 100; var width = 50; var height = 50; var canvas = document.getElementById('image'); var context = canvas.getContext('2d'); context.strokeStyle = 'black'; context.strokeRect(x, y, width, height);
</script>
</body>
</html>
var x = 100; var y = 100; var width = 50; var height = 50; var canvas = document.getElementById('image'); var context = canvas.getContext('2d'); context.strokeStyle = 'black'; context.strokeRect(x, y, width, height);
canvas {
width: 500px;
height: 334px;
}
<canvas id="image"></canvas>
I have a problem with centring the image inside of the canvas. Canvas has to be full sized. The whole thing should create a web preloader. Styling image inside of css does not work in this case.
<style> canvas{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #000000;
z-index: 99; }
</style> <body>
<canvas id="c"><img id="logo" width="800" height="150" src="imgsource" alt="logo"></canvas> <div> web content </div>
<script>
jQuery(window).on('load', function() {
jQuery('#c').delay(7000).fadeOut('slow');
jQuery('body').delay(7000).css({'overflow':'visible'});
})
window.onload = function() {
var c = document.getElementById("c");
var ctx = c.getContext("2d");
var img = document.getElementById("logo");
ctx.drawImage(img, 50, 0);
} </script>
The following only demonstrates the centering of an image inside a canvas with drawImg. Note that the image to the left is from the html <img> element while the other is from the drawImg call.
Outside of stackoverflow you'd have to wait for the image to load before drawing it, but as you also already use .on('load', ...) i assume you are aware of that.
To avoid having two images, create the image element in javascript and don't add it to the document but only use it for rendering.
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
let img = document.getElementById("i");
//just to make the area the canvas occupies visible
ctx.fillStyle = 'grey';
ctx.fillRect(0, 0, canvas.width, canvas.height);
//draw the image centered
ctx.drawImage(
img,
canvas.width / 2 - img.width / 2,
canvas.height / 2 - img.height / 2
);
<html>
<body>
<img id="i" src="http://i.imgur.com/kdJicdy.png"/>
<canvas id="canvas" width="320" height="240">Your browser doesn't support canvas</canvas>
</body>
</html>
var canvas = document.getElementById('canvas');
var image = new Image();
image.src = 'http://placehold.it/300x550';
image.onload = function () {
var canvasContext = canvas.getContext('2d');
var wrh = image.width / image.height;
var newWidth = canvas.width;
var newHeight = newWidth / wrh;
if (newHeight > canvas.height) {
newHeight = canvas.height;
newWidth = newHeight * wrh;
}
var xOffset = newWidth < canvas.width ? ((canvas.width - newWidth) / 2) : 0;
var yOffset = newHeight < canvas.height ? ((canvas.height - newHeight) / 2) : 0;
canvasContext.drawImage(image, xOffset, yOffset, newWidth, newHeight);
};
<canvas id="canvas" width="500" height="500" style="border: 1px solid black" />
Have a simple drawing application. The problem is in the coordinates (redraw function): they must be mouse, but are near 2x mouse. What's the problem in the code?
<html>
<head>
<style type="text/css" media="screen">
body{
background-color: green;
}
#workspace{
width: 700px;
height:420px;
margin: 40px auto 20px auto;
border: black dashed 1px;
}
#canvas{
background: white;
width: 100%;
height: 100%;
}
</style>
<script type="text/javascript" src="jquery-1.7.1.js"></script>
<script type="text/javascript">
$(document).ready(
function() {
var context = document.getElementById('canvas').getContext("2d");
var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;
$('#canvas').mousedown(function(e){
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
paint = true;
addClick(mouseX,mouseY, false);
redraw();
});
$('#canvas').mousemove(function(e){
if(paint){
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
redraw();
}
});
$('#canvas').mouseup(function(e){
paint = false;
});
$('#canvas').mouseleave(function(e){
paint = false;
});
function addClick(x, y, dragging)
{
clickX.push(x);
clickY.push(y);
clickDrag.push(dragging);
}
function redraw(){
canvas.width = canvas.width; // Clears the canvas
context.strokeStyle = "#df4b26";
context.lineJoin = "round";
context.lineWidth = 5;
for(var i=1; i < clickX.length; i++)
{
context.beginPath();
if(clickDrag[i] && i){
context.moveTo(clickX[i-1], clickY[i-1]);
}else{
context.moveTo(clickX[i], clickY[i]);
}
context.lineTo(clickX[i], clickY[i]);
context.closePath();
context.stroke();
}
console.log(clickX[clickX.length-1]+" "+clickY[clickX.length-1]);
}
});
</script>
</head>
<body>
<div id="workspace">
<canvas id="canvas"/>
</div>
</body>
</html>
You should not set a canvas' width/height through CSS. It makes the canvas stretch instead of making the resolution higher. This means that although the coordinates are correct, they will visually end up somewhere else.
For example, an x coordinate of 100 will be stretched to visually be an x coordinate of 200 (or something else; at least it will be bigger than 100 since it's been stretched).
Instead, use:
<canvas id="canvas" width="700" height="420" />
and remove the width: 100% in CSS.
http://jsfiddle.net/euXJC/1/