How can I fullscreen my canvas & make it fill the screen? - javascript

I have a HTML5 canvas that when it goes into fullscreen, it does not fill the entire screen.
If I change only the canvas.style.width/height then it works but the display looks bad and also the mouse coordinates are misplaced.
js
var canvas = document.getElementById("canvas");
var mouseX = 0;
var mouseY = 0;
canvas.style.left = 0;
canvas.style.top = 0;
onmousemove = function(event) {
mouseX = (event.pageX - parseFloat(canvas.style.left, 10)) + document.body.scrollLeft;
mouseY = (event.pageY - parseFloat(canvas.style.top, 10)) + document.body.scrollTop;
}
document.body.addEventListener("keydown", function (event) {
switch (event.keyCode) {
case 70:
if (canvas.requestFullScreen) {
canvas.requestFullScreen();
}
else if (canvas.webkitRequestFullScreen) {
canvas.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
}
else if (canvas.mozRequestFullScreen) {
canvas.mozRequestFullScreen();
}
break;
}
});
function on_fullscreen_change() {
if(document.mozFullScreen || document.webkitIsFullScreen) {
canvas.style.position = "absolute";
canvas.style.left = 0;
canvas.style.top = 0;
canvas.style.width = screen.width+"px";
canvas.style.height = screen.height+"px";
canvas.width = parseFloat(canvas.style.width, 10);
canvas.height = parseFloat(canvas.style.height, 10);
}
else {
canvas.style.left = 0;
canvas.style.top = 0;
canvas.style.width = "1280px";
canvas.style.height = "720px";
canvas.width = parseFloat(canvas.style.width, 10);
canvas.height = parseFloat(canvas.style.height, 10);
}
}
document.addEventListener('mozfullscreenchange', on_fullscreen_change);
document.addEventListener('webkitfullscreenchange', on_fullscreen_change);
window.setInterval(function(){
var context = canvas.getContext('2d');
context.fillStyle = '#0e6eae';
context.fillRect(mouseX, mouseY, 150, 100);
}, 10);
function getMouseX(){
return mouseX;
}
function getMouseY(){
return mouseY;
}
css
:-webkit-full-screen { width: 100%; height: 100%; background: #000; }
EDIT: You can download test files at http://liveweave.com/g5WLW5

Try adding:
canvas.width = screen.width;
canvas.height = screen.height;
canvas.width and canvas.style.width are two different things. The first resizes the context of the canvas, while the second scales the representation of it.

Related

Issue when dragging text on canvas if slightly scrolled down

When I scroll slightly down on my canvas, it does not allow me to drag my text at all. Examples (These are GIFs) -
https://gyazo.com/e60d2efd924ced758c2c6441391804db
GIF explained: So you saw the drag was working when I was on top of the page but when I scrolled slightly down. It completely stopped working. I added a few console.logs around, and what I know is the click event listener for the canvas is working but it isn't detected the text when I slightly scroll down on the page.
I based my drag code from: http://jsfiddle.net/m1erickson/9xAGa/ | What you can see is if you change the canvas size width: 667 and height: 800, and when you scroll slightly down, you will have the same issue I am having.
HTML Code:
<div id="middle_container">
<div class="center_container">
<canvas id="canvas" width="667px" height="800px"></canvas>
</div>
</div>
JavaScript Code:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var $canvas = $("#canvas");
var BB=canvas.getBoundingClientRect();
var offsetX = BB.left;
var offsetY = BB.top;
var mx;
var my;
var texts = [];
var images = [];
var dragF = -1;
var mode = "none";
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for(const { text, x, y, width, height } of texts) {
ctx.fillText(text, x, y);
}
}
function addNewText(string_text) {
var y = texts.length * 20 + 20;
var text = {
text: string_text,
x: 20,
y: y
};
ctx.font = "32px verdana";
ctx.textBaseline = "top";
text.width = ctx.measureText(text.text).width;
text.height = 32;
texts.push(text);
draw();
}
function hitDrag(x,y,textIndex) {
var r=texts[textIndex];
return (x>r.x && x<r.x+r.width && y>r.y && y<r.y+r.height);
}
function myDrag(a,e) {
if (a == "down") {
e.preventDefault();
e.stopPropagation();
mx=parseInt(e.clientX-offsetX);
my=parseInt(e.clientY-offsetY);
for(var i=0;i<texts.length;i++){
if(hitDrag(mx,my,i)){
console.log("found");
dragF = i;
}
}
}
}
addNewText("Hello World")
$("#canvas").mousedown(function(e) {
myDrag("down", e);
});
The problem is this line of code:
var BB=canvas.getBoundingClientRect();
which is only populated once at the start of your script. The .getBoundingClientRect() method returns the position of a HTML element relative to the viewport.
Well if you scroll the window, the viewport moves - as the canvas element - but the BB object still holds the position of your canvas at startup.
The fix is rather simple - you need to use the actual position of the canvas element by calling .getBoundingClientRect() again on mouse down and on mouse move.
I've prepared a little sample based on your code and the fiddle you've linked:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var $canvas = $("#canvas");
var BB = canvas.getBoundingClientRect();
var offsetX = BB.left;
var offsetY = BB.top;
var mx;
var my;
var texts = [];
var images = [];
var dragF = -1;
var mode = "none";
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (const {
text,
x,
y,
width,
height
} of texts) {
ctx.fillText(text, x, y);
}
}
function addNewText(string_text) {
var y = texts.length * 20 + 20;
var text = {
text: string_text,
x: 20,
y: y
};
ctx.font = "32px verdana";
ctx.textBaseline = "top";
text.width = ctx.measureText(text.text).width;
text.height = 32;
texts.push(text);
draw();
}
function myDrag(a, e) {
if (a == "down") {
e.preventDefault();
e.stopPropagation();
let rect = canvas.getBoundingClientRect();
mx = parseInt(e.clientX - rect.left);
my = parseInt(e.clientY - rect.top);
for (var i = 0; i < texts.length; i++) {
if (hitDrag(mx, my, i)) {
// console.log("found");
dragF = i;
}
}
}
}
function hitDrag(x, y, textIndex) {
var r = texts[textIndex];
return (x > r.x && x < r.x + r.width && y > r.y && y < r.y + r.height);
}
function handleMouseMove(e) {
if (dragF < 0) {
return;
}
e.preventDefault();
let rect = canvas.getBoundingClientRect();
mouseX = parseInt(e.clientX - rect.left);
mouseY = parseInt(e.clientY - rect.top);
var dx = mouseX - mx;
var dy = mouseY - my;
mx = mouseX;
my = mouseY;
var text = texts[dragF];
text.x += dx;
text.y += dy;
draw();
}
function handleMouseUp(e) {
e.preventDefault();
dragF = -1;
}
addNewText("Hello World")
$("#canvas").mousedown(function(e) {
myDrag("down", e);
});
$("#canvas").mousemove(function(e) {
handleMouseMove(e);
});
$("#canvas").mouseup(function(e) {
handleMouseUp(e);
});
body {
background-color: ivory;
}
#canvas {
border: 1px solid red;
}
#theText {
width: 10em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="middle_container">
<div class="center_container">
<canvas id="canvas" width="667px" height="800px"></canvas>
</div>
</div>
<br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br>

Is it possible to drag an image within canvas as well as draw on the same canvas?

Here I'm trying to draw on a html5 canvas as well as upload some images and drag them within the canvas. The problem is I can do one or the other but not both.
What I've realised is that the canvas must be Cleared before dragging takes place but by doing that I'm clearing the drawing and if I don't clear the canvas it draws but dragging an image leaves trail behind. Can anyone point me to right direction please.
function init() {
canvas = document.getElementById('can');
ctx = canvas.getContext("2d");
w = canvas.width;
h = canvas.height;
img = document.getElementById("drag");
canvas.addEventListener("mousemove", function (e) { findxy('move', e) }, false);
canvas.addEventListener("mousedown", function (e) { findxy('down', e) }, false);
canvas.addEventListener("mouseup", function (e) { findxy('up', e) }, false);
canvas.addEventListener("mouseout", function (e) { findxy('out', e) }, false);
imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', handleImage, false);
var contexts = [];
contexts.push(canvas.getContext('2d'));
function clearAll() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
canvas.onclick = function (e) { handleClick(e, 1); };
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();
}
}
canvas.onmousemove = function (e) { handleMousemove(e, 1); }
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 = [];
states.push(addState(0, 0, img));
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);
}
}//end of init()
var imgArray = [];
function handleImage(e) {
var reader = new FileReader();
reader.onload = function (event) {
imgArray.push(img);
for(i = 0; i < imgArray.length; i++){
img.src = imgArray[i];
img.setAtX = i * 50;
img.setAtY = i * 0;
img.onload = function() {
ctx.drawImage(this, this.setAtX, this.setAtY);
};
img.src = event.target.result;
}
};
reader.readAsDataURL(e.target.files[0]);
}
function findxy(res, e) {
if (res === 'down') {
prevX = currX;
prevY = currY;
currX = e.clientX - canvas.offsetLeft;
currY = e.clientY - canvas.offsetTop;
flag = true;
dot_flag = true;
if (dot_flag) {
ctx.beginPath();
ctx.fillStyle = x;
ctx.fillRect(currX, currY, 2, 2);
ctx.closePath();
dot_flag = false;
}
}
if (res === 'up' || res === "out") {
flag = false;
}
if (res === 'move') {
if (flag) {
prevX = currX;
prevY = currY;
currX = e.clientX - canvas.offsetLeft;
currY = e.clientY - canvas.offsetTop;
draw();
}
}
}
//Draw lines or text
function draw() {
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
ctx.fillStyle = x;
ctx.font = "Italic Bold 14pt Times, serif";
ctx.fillText(message, prevX, prevY);
}
Here is a mashup of the code i linked to and your own.
All parameters related to drawing the image and translating it around the canvas is covered.
var canvas = document.getElementById("canvas");
var ctx;
var x = 75;
var y = 50;
var WIDTH = 400;
var HEIGHT = 300;
var dragok = false;
var img = document.getElementById("img");
var lines = [{
x: x,
y: y
}];
function rect(x, y, w, h) {
ctx.beginPath();
ctx.rect(x, y, w, h);
ctx.closePath();
ctx.fill();
}
function clear() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
}
function init() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
return setInterval(draw, 1000/24);
}
function draw() {
clear();
ctx.drawImage(img, x - img.width / 2, y - img.height / 2);
ctx.beginPath();
ctx.moveTo(lines[0].x,lines[0].y);
for(var i = 1; i < lines.length; i++) {
var line = lines[i];
ctx.lineTo(lines[i].x,lines[i].y);
}
ctx.stroke();
ctx.closePath();
//rect(x - 15, y - 15, 30, 30);
}
function myMove(e) {
if (dragok) {
x = e.pageX - canvas.offsetLeft;
y = e.pageY - canvas.offsetTop;
lines = lines.slice(lines.length - 100)
lines.push({
x: x,
y: y
});
}
}
function myDown(e) {
if (e.pageX < x + img.width / 2 + canvas.offsetLeft && e.pageX > x - img.width / 2 +
canvas.offsetLeft && e.pageY < y + img.height / 2 + canvas.offsetTop &&
e.pageY > y - img.height / 2 + 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;
//Change image for the heck of it ^^
setInterval(function() {
img.src = 'https://placeholdit.imgix.net/~text?txtsize=60&txt=' +
Math.floor(Math.random() * 10) +
'&w=100&h=100';
}, 3000)
<canvas id="canvas" width="400" height="300">
This text is displayed if your browser does not support HTML5 Canvas.
</canvas>
<img id="img" src="https://placeholdit.imgix.net/~text?txtsize=60&txt=1&w=100&h=100">
Updated my answer to draw lines
My final code that's working , I had to add two canvases one for the drawing and one for the dragging images. Fabric frame work helped a lot. https://jsfiddle.net/tn07Bond/982s4bgv/2/
<div id="canvasesdiv">
<canvas id="images" width=600 height=400 style="position: absolute;
left: 0;
top: 0;
border: 1px solid blue;
z-index: 1;">
This text is displayed if your browser does not support HTML5 Canvas</canvas>
<canvas id="drawing" width=600 height=400 style="position: absolute;
left: 0;
top: 0;
border: 1px solid red;
z-index: 2;">
This text is displayed if your browser does not support HTML5 Canvas</canvas>
<input type="file" id="imageLoader" class="imageLoader" name="imageLoader"/>
<input type="image" src="images/PenForCanvas.png" alt="pen" title="Draw on canvas"
id="Drawing" style="cursor: pointer; margin: 5px 0 0 200px;">
<input type="image" src="images/drag.png" alt="drag" title="Drag this image" id="Images" style="cursor: pointer;">
</div>
<script>
var drawing, drawingCtx,images,imagesCtx, message = "", img, imageLoader, prevX = 10, currX = 10, prevY = 10, currY = 10,
dot_flag = false, flag = false, x = "black", y = 2, formElement, canvasLeft, canvasTop, imgData, data,
startOffsetX = 0, startOffsetY = 0;
(function () {
// Drawing canvas
drawing = document.getElementById("drawing");
drawingCtx = drawing.getContext("2d");
//Uploading and dragging images
images = new fabric.Canvas('images');
document.getElementById('imageLoader').addEventListener("change", function (e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function (f) {
var data = f.target.result;
fabric.Image.fromURL(data, function (img) {
var oImg = img.set({left: 0, top: 0, angle: 00,width:40, height:40}).scale(0.9);
images.add(oImg).renderAll();
var a = images.setActiveObject(oImg);
var dataURL = images.toDataURL({format: 'png', quality: 0.8});
});
};
reader.readAsDataURL(file);
});
w = drawing.width;
h = drawing.height;
//Mouse events
drawing.addEventListener("mousemove", function (e) { findxy('move', e) }, false);
drawing.addEventListener("mousedown", function (e) { findxy('down', e) }, false);
drawing.addEventListener("mouseup", function (e) { findxy('up', e) }, false);
drawing.addEventListener("mouseout", function (e) { findxy('out', e) }, false);
Drawing = document.getElementById("Drawing");
Drawing.addEventListener("click", bringDrawingToFront);
Images = document.getElementById("Images");
Images.addEventListener("click", bringImagesToFront);
imageLoader = document.getElementById('imageLoader');
imageLoader.addEventListener('change', bringImagesToFront);
//Drawing
function findxy(res, e) {
if (res === 'down') {
prevX = currX;
prevY = currY;
currX = e.clientX - drawing.offsetLeft;
currY = e.clientY - drawing.offsetTop;
flag = true;
dot_flag = true;
if (dot_flag) {
drawingCtx.beginPath();
drawingCtx.fillStyle = x;
drawingCtx.fillRect(currX, currY, 2, 2);
drawingCtx.closePath();
dot_flag = false;
}
}
if (res === 'up' || res === "out") {
flag = false;
}
if (res === 'move') {
if (flag) {
prevX = currX;
prevY = currY;
currX = e.clientX - drawing.offsetLeft;
currY = e.clientY - drawing.offsetTop;
draw();
}
}
}
function save() {
imgData = drawingCtx.getImageData(0, 0, drawing.width, drawing.height);
}
function restore() {
drawingCtx.putImageData(imgData, 0, 0);
}
function bringDrawingToFront() {
drawing.style.zIndex = 1;
document.getElementById("images").style.zIndex = 0;
}
function bringImagesToFront() {
drawing.style.zIndex = 0;
document.getElementById("images").style.zIndex = 1;
}
//Draw lines or text
function draw() {
drawingCtx.beginPath();
drawingCtx.moveTo(prevX, prevY);
drawingCtx.lineTo(currX, currY);
drawingCtx.strokeStyle = x;
drawingCtx.lineWidth = y;
drawingCtx.stroke();
drawingCtx.closePath();
drawingCtx.fillStyle = x;
drawingCtx.font = "Italic Bold 14pt Times, serif";
drawingCtx.fillText(message, prevX, prevY);
save();
}
})();
</script>

Canvas arc on Retina is too sharp at some points

I am trying to create animated arc that doesn't look blurry on HiDPI devices.
This is how my arc looks on iPhone 5s:
you can see that near 0, 90, 180 deg arc becomes too sharp. How can I prevent this?
This is my code:
// Canvas arc progress
const can = document.getElementById('canvas');
const ctx = can.getContext('2d');
const circ = Math.PI * 2;
const quart = Math.PI / 2;
const canvasSize = can.offsetWidth;
const halfCanvasSize = canvasSize / 2;
let start = 0,
finish = 70,
animRequestId = null;
// Get pixel ratio
const ratio = (function() {
const dpr = window.devicePixelRatio || 1,
bsr = ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1;
return dpr / bsr;
})();
// Set canvas h & w
can.width = can.height = canvasSize * ratio;
can.style.width = can.style.height = canvasSize + 'px';
ctx.scale(ratio, ratio)
ctx.beginPath();
ctx.strokeStyle = 'rgb(120,159,194)';
ctx.lineCap = 'square';
ctx.lineWidth = 8.0;
ctx.arc(halfCanvasSize, halfCanvasSize, halfCanvasSize - 4, 0, circ, false);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.strokeStyle = 'rgb(244,247,255)';
ctx.lineCap = 'round';
ctx.lineWidth = 8.0;
ctx.closePath();
let imd = ctx.getImageData(0, 0, canvasSize, canvasSize);
const draw = (current) => {
ctx.putImageData(imd, 0, 0);
ctx.beginPath();
ctx.arc(halfCanvasSize, halfCanvasSize, halfCanvasSize - 4, -(quart), ((circ) * current) - quart, false);
ctx.stroke();
};
(function animateArcProgress() {
animRequestId = requestAnimationFrame(animateArcProgress);
if (start <= finish) {
draw(start / 100);
start += 2;
} else {
cancelAnimationFrame(animRequestId);
}
})();
body {
margin: 0;
}
div {
display: flex;
align-items: center;
justify-content: center;
height: 300px;
widht: 300px;
background: #85b1d7;
}
canvas {
height: 250px;
width: 250px;
}
<div>
<canvas id='canvas'></canvas>
</div>
You can soften the edge by drawing 1/2 pixel inside as done in your code below.
I rendered the arc 3 times at 8, 7.5 and 7 pixel width width alpha colour values 0.25, 0.5 and 1 respectively.
You can make it as soft as you want.
BTW using putImageData is very slow, why not just render the background to another canvas and draw that via ctx.drawImage(offScreencanvas,0,0) that way you will use the GPU to render the background rather than the CPU via the graphics port bus.
I added a bit more code to show the different softening FX you can get and added a mouse zoom so you can see the pixels a little better.
const can = document.getElementById('canvas');
const can2 = document.createElement("canvas"); // off screen canvas
const can3 = document.createElement("canvas"); // off screen canvas
const ctx = can.getContext('2d');
const ctx2 = can2.getContext('2d');
const ctx3 = can3.getContext('2d');
const circ = Math.PI * 2;
const quart = Math.PI / 2;
const canvasSize = can.offsetWidth;
const halfCanvasSize = canvasSize / 2;
const mouse = {x : null, y : null};
can.addEventListener("mousemove",function(e){
var bounds = can.getBoundingClientRect();
mouse.x = e.clientX - bounds.left;
mouse.y = e.clientY - bounds.top;
});
let start = 0,
finish = 70,
animRequestId = null;
// Get pixel ratio
const ratio = (function() {
const dpr = window.devicePixelRatio || 1,
bsr = ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1;
return dpr / bsr;
})();
// Set canvas h & w
can2.height = can3.height = can2.width = can3.width = can.width = can.height = canvasSize * ratio;
can.style.width = can.style.height = canvasSize + 'px';
ctx.scale(ratio, ratio)
ctx2.scale(ratio, ratio)
ctx3.scale(ratio, ratio)
ctx2.beginPath();
ctx2.strokeStyle = 'rgb(120,159,194)';
ctx2.lineCap = 'square';
ctx2.lineWidth = 8.0;
ctx2.arc(halfCanvasSize, halfCanvasSize, halfCanvasSize - 4, 0, circ, false);
ctx2.stroke();
ctx2.closePath();
ctx2.beginPath();
ctx2.strokeStyle = 'rgb(244,247,255)';
ctx2.lineCap = 'round';
ctx2.lineWidth = 8.0;
ctx2.closePath();
const draw = (current) => {
ctx3.clearRect(0,0,canvas.width,canvas.height);
ctx3.drawImage(can2,0,0);
var rad = halfCanvasSize - 4;
const drawArc = () => {
ctx3.beginPath();
ctx3.arc(halfCanvasSize, halfCanvasSize, rad, -(quart), ((circ) * current) - quart, false);
ctx3.stroke();
}
// draw soft
ctx3.strokeStyle = 'rgb(244,247,255)';
ctx3.lineWidth = 8.5;
ctx3.globalAlpha = 0.25;
drawArc();;
ctx3.lineWidth = 7.0;
ctx3.globalAlpha = 0.5;
drawArc();;
ctx3.lineWidth = 6.5;
ctx3.globalAlpha = 1;
drawArc();
// draw normal
rad -= 12;
ctx3.lineWidth = 8.0;
ctx3.globalAlpha = 1;
drawArc();;
// draw ultra soft
rad -= 12;
ctx3.strokeStyle = 'rgb(244,247,255)';
ctx3.lineWidth = 9.0;
ctx3.globalAlpha = 0.1;
drawArc();
ctx3.lineWidth = 8.0;
ctx3.globalAlpha = 0.2;
drawArc();;
ctx3.lineWidth = 7.5;
ctx3.globalAlpha = 0.5;
drawArc();
ctx3.lineWidth = 6;
ctx3.globalAlpha = 1;
drawArc();
};
const zoomW = 30;
const zoomAmount = 5;
const drawZoom = () => {
ctx.drawImage(can3,0,0);
var width = zoomW * zoomAmount;
var cx = mouse.x - width / 2;
var cy = mouse.y - width / 2;
var c1x = mouse.x - zoomW / 2;
var c1y = mouse.y - zoomW / 2;
ctx.strokeStyle = 'rgb(244,247,255)';
ctx.lineWidth = 4;
ctx.strokeRect(cx,cy,width,width);
ctx.clearRect(cx,cy,width,width);
ctx.imageSmoothingEnabled = false;
ctx.mozImageSmoothingEnabled = false;
ctx.drawImage(can3,c1x,c1y,zoomW,zoomW,cx,cy,width,width);
ctx.imageSmoothingEnabled = true;
ctx.mozImageSmoothingEnabled = true;
}
function keepUpdating(){
ctx.clearRect(0,0,can.width,can.height);
drawZoom();
requestAnimationFrame(keepUpdating);
}
(function animateArcProgress() {
ctx.clearRect(0,0,can.width,can.height);
draw(start / 100);
drawZoom();
if (start <= finish) {
start += 0.5;
requestAnimationFrame(animateArcProgress);
} else {
requestAnimationFrame(keepUpdating);
}
})();
body {
margin: 0;
}
div {
display: flex;
align-items: center;
justify-content: center;
height: 300px;
widht: 300px;
background: #85b1d7;
}
canvas {
height: 250px;
width: 250px;
}
<div>
<canvas id='canvas'></canvas>
</div>

Is there a way to create TEXT watermark in pure javascript?

I would like to create and add textual watermark to a webpage. It should be created in pure javascript.
EDIT:
Explanation: Take current page as an example and I wish I could display semi-transparent text "STACKOVERFLOW" in the middle of this page.
Making a watermark with pure JS is long, but easier with jQuery:
$(document).ready(function(){
var Html = "<div id='myDiv'>My Watermark</div>";
$("body").append(Html);
$("#myDiv").css({
"color":"#bbb","font-size":"100px",
"position":"absolute","top":"0px","left":"0px",
"z-index":"-1","transform":"rotate(45deg)"
});
});
See this jsfiddle: http://jsfiddle.net/jondinham/agz5tytb/
With pure JavaScript, it's harder because the 'transform' css is not a standard in old browsers. Anyway, it can be done this way:
var div = document.createElement("div");
document.getElementsByTagName("body")[0].appendChild(div);
div.innerHTML = "My Watermark";
div.style.color = "#bbb";
div.style.fontSize = "100px";
div.style.position = "absolute";
div.style.top = "0px";
div.style.left = "0px";
div.style.zIndex = "-1";
div.style.transform = "rotate(45deg)"; //standard
div.style.msTransform = "rotate(45deg)"; //IE
div.style.mozTransform = "rotate(45deg)"; //Firefox
div.style.webkitTransform = "rotate(45deg)"; //Chrome
div.style.oTransform = "rotate(45deg)"; //Opera
See jsfiddle: http://jsfiddle.net/jondinham/7fqg9n6w/
https://codepen.io/emrahaydemir/pen/OJZYwYz
async function addWatermarkToImage(file) {
return new Promise(async (resolve, reject) => {
const image = await fileToDataURL(file);
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0);
const fontSize =
(canvas.width + canvas.height) / ctx.measureText(text).width;
ctx.font = fontSize + "px verdana";
const textSize = ctx.measureText(text);
ctx.globalAlpha = watermarkOpacity;
ctx.fillStyle = waterMarkColor;
ctx.textAlign = "center";
let startY = -canvas.height / 2;
let startX = -canvas.width / 2;
const xGap = canvas.width * 0.07;
const yGap = canvas.height * 0.07;
for (let index = 0; startX < canvas.width; index++) {
for (let yIndex = 0; startY < canvas.height; index++) {
ctx.strokeText(text, startX, startY);
startY += fontSize + yGap;
}
startY = 0;
startX += textSize.width + xGap;
}
resolve(canvas.toDataURL());
});
}

How can I get the line to draw where the cursor is positioned? HTML5 canvas using MrDoob's Harmony

QUESTION
How can I get the line to draw where the cursor is positioned?
DETAILS
I'm trying to draw a line freehand on html5 canvas using MrDoob's harmony script (https://github.com/mshuler/harmony). I've edited the canvas so that it has a specific width and height (before it covered the whole page). I then position it using the following CSS
canvas
{
position:absolute;
top:0px; left:0px;
}
When I draw on the canvas (using the mouse) the lines are drawn as per normal, but if I position the canvas like this
canvas
{
position:absolute;
top:100px; left:0px;
}
the line appears lower than the position of the cursor.
QUESTION: How can I get the line to draw where the cursor is positioned?
Here is my code.
CSS
canvas
{
position:absolute;
top:100px; left:0px;
}
#writepad
{
display:block;
width:700px;
height:500px;
}
JAVASCRIPT (Main.js)
SCREEN_HEIGHT = $('#writepad').innerHeight();// SCREEN_HEIGHT = window.innerHeight,
init();
function init()
{
var hash, palette, embed, localStorageImage;
document.body.style.backgroundRepeat = 'no-repeat';
document.body.style.backgroundPosition = 'center center';
container = document.createElement('div');
document.body.appendChild(container);
canvas = document.createElement("canvas");
canvas.width = SCREEN_WIDTH;
canvas.height = SCREEN_HEIGHT;
canvas.style.cursor = 'crosshair';
container.appendChild(canvas);
context = canvas.getContext("2d");
flattenCanvas = document.createElement("canvas");
flattenCanvas.width = SCREEN_WIDTH;
flattenCanvas.height = SCREEN_HEIGHT;
}
// WINDOW
function onWindowMouseMove( event )
{
mouseX = event.clientX;
//console.log("mouseX=",mouseX);
mouseY = event.clientY;
//console.log("mouseY=",mouseY);
}
function onWindowResize()
{
SCREEN_WIDTH = window.innerWidth;
SCREEN_HEIGHT = window.innerHeight;
menu.container.style.left = ((SCREEN_WIDTH - menu.container.offsetWidth) / 2) + 'px';
about.container.style.left = ((SCREEN_WIDTH - about.container.offsetWidth) / 2) + 'px';
about.container.style.top = ((SCREEN_HEIGHT - about.container.offsetHeight) / 2) + 'px';
}
function onWindowBlur( event )
{
shiftKeyIsDown = false;
altKeyIsDown = false;
}
// CANVAS
function onCanvasMouseDown( event )
{
var data, position;
clearTimeout(saveTimeOut);
cleanPopUps();
if (altKeyIsDown)
{
flatten();
data = flattenCanvas.getContext("2d").getImageData(0, 0, flattenCanvas.width, flattenCanvas.height).data;
position = (event.clientX + (event.clientY * canvas.width)) * 4;
console.log("position=",position);
foregroundColorSelector.setColor( [ data[position], data[position + 1], data[position + 2] ] );
return;
}
BRUSH_PRESSURE = wacom && wacom.isWacom ? wacom.pressure : 1;
brush.strokeStart( event.clientX, event.clientY );
window.addEventListener('mousemove', onCanvasMouseMove, false);
window.addEventListener('mouseup', onCanvasMouseUp, false);
}
function onCanvasMouseMove( event )
{
BRUSH_PRESSURE = wacom && wacom.isWacom ? wacom.pressure : 1;
brush.stroke( event.clientX, event.clientY );
}
function onCanvasMouseUp()
{
brush.strokeEnd();
window.removeEventListener('mousemove', onCanvasMouseMove, false);
window.removeEventListener('mouseup', onCanvasMouseUp, false);
}
function onCanvasTouchStart( event )
{
cleanPopUps();
if(event.touches.length == 1) {
event.preventDefault();
brush.strokeStart( event.touches[0].pageX, event.touches[0].pageY );
window.addEventListener('touchmove', onCanvasTouchMove, false);
window.addEventListener('touchend', onCanvasTouchEnd, false);
}
}
function onCanvasTouchMove( event )
{
if(event.touches.length == 1)
{
event.preventDefault();
brush.stroke( event.touches[0].pageX, event.touches[0].pageY );
}
}
function onCanvasTouchEnd( event )
{
if(event.touches.length == 0)
{
event.preventDefault();
brush.strokeEnd();
window.removeEventListener('touchmove', onCanvasTouchMove, false);
window.removeEventListener('touchend', onCanvasTouchEnd, false);
}
}
function flatten()
{
var context = flattenCanvas.getContext("2d");
context.fillStyle = 'rgb(' + BACKGROUND_COLOR[0] + ', ' + BACKGROUND_COLOR[1] + ', ' + BACKGROUND_COLOR[2] + ')';
context.fillRect(0, 0, canvas.width, canvas.height);
context.drawImage(canvas, 0, 0);
}
You want something like this???
<!doctype html>
<html>
<head>
<script type="text/javascript">
window.onload=function() {
var canvas=document.getElementById('mycanvas');
var ctx=canvas.getContext('2d');
canvas.addEventListener('mousemove',function onMouseover(e) {
var mx = e.clientX - 8;
var my = e.clientY - 8;
ctx.fillStyle = '#000';
ctx.font = 'bold 22px verdana';
ctx.fillText(".", mx, my,1000);
}, 0);
};
</script>
</head>
<body>
<canvas id="mycanvas" height="400" width="800" style="border:1px solid #000000;">
</body>
</html>
Use the offset property
y = event.pageY - canvas.offsetTop;
x = event.pageX - canvas.offsetLeft;

Categories

Resources