Blur canvas that is full width of window without transparent edge? - javascript

I'm having some issues with an effect I'm trying to achieve using canvas and the CSS blur filter.
Essentially I need a canvas that is 100% of the height and width of the window, which can be erased to show elements sitting beneath. I am using the blur so the shapes/drawing looks blurred (this is needed).
My issue is that despite oversizing the canvas, there is still a transparent edge around the corners, which shows the elements beneath (i.e. the body with a blue background). I have tried multiple negative margin/overflow hacks, but can't seem to get around it?
I need this canvas to be the full width of the screen, blurred, and not crop in at all, but maybe this is just how CSS filters render, only what is visible?
(function() {
// make canvas larger than window
var largeWidth = window.innerWidth * 3;
var largeHeight = window.innerHeight * 3;
function createCanvas(parent, width, height) {
var canvas = {};
canvas.node = document.createElement('canvas');
canvas.context = canvas.node.getContext('2d');
canvas.node.width = largeWidth;
canvas.node.height = largeHeight;
parent.appendChild(canvas.node);
return canvas;
}
function init(container, width, height, fillColor) {
var canvas = createCanvas(container, 3000, 3000);
var ctx = canvas.context;
ctx.fillCircle = function(x, y, radius, fillColor) {
this.fillStyle = fillColor;
this.beginPath();
this.moveTo(x, y);
this.arc(x, y, radius, 0, Math.PI * 2, false);
this.fill();
};
ctx.clearTo = function(fillColor) {
ctx.fillStyle = fillColor;
ctx.fillRect(0, 0, width, height);
};
ctx.clearTo(fillColor || "#ddd");
canvas.node.onmousemove = function(e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
var radius = 100; // or whatever
var fillColor = '#ff0000';
ctx.globalCompositeOperation = 'destination-out';
ctx.fillCircle(x, y, radius, fillColor);
};
canvas.node.onmousedown = function(e) {
canvas.isDrawing = true;
};
}
var container = document.getElementById('canvas');
init(container, largeWidth, largeHeight, '#fff');
})();
/* CSS: */
body {
background: blue;
}
#canvas {
z-index: 1;
top: 0;
left: 0;
position: fixed;
filter: blur(10px);
-webkit-filter: blur(10px);
}
<div id = "canvas"></div>
Please see my fiddle
Thanks

Solution 1 - AKA "Ready Today"
Don't blur your canvas but blur what you put inside it; ex:
// After filling circle
context.shadowColor = color;
context.shadowBlur = 16;
context.stroke();
Here is a fiddle
Solution 2 - AKA "Tomorrow .. maybe"
Webkit is working on such feature. But I'm not sure it will work as you intend with canvas, maybe it will considere the whole canvas as "blur mask" so it will blur underneath event if content inside canvas is erased. Here is the feature :
backdrop-filter: blur(10px);
Here is some doc
ps :
I'm not sure it's necessary to wrap canvas as you did .. juste create one and edit its properties directly !
Ouch ! if you make element size 3 times bigger but don't set offset it will only be able overflow on right and bottom sides

You can remove the filter from the canvas and use a gradient brush to achieve the same.
(function() {
// make canvas larger than window
var largeWidth = window.innerWidth * 3;
var largeHeight = window.innerHeight * 3;
function createCanvas(parent, width, height) {
var canvas = {};
canvas.node = document.createElement('canvas');
canvas.context = canvas.node.getContext('2d');
canvas.node.width = largeWidth;
canvas.node.height = largeHeight;
parent.appendChild(canvas.node);
return canvas;
}
function init(container, width, height, fillColor) {
var canvas = createCanvas(container, 3000, 3000);
var ctx = canvas.context;
ctx.fillCircle = function(x, y, radius, fillColor) {
this.fillStyle = fillColor;
this.beginPath();
this.moveTo(x, y);
this.arc(x, y, radius, 0, Math.PI * 2, false);
this.fill();
};
ctx.clearTo = function(fillColor) {
ctx.fillStyle = fillColor;
ctx.fillRect(0, 0, width, height);
};
ctx.clearTo(fillColor || "#ddd");
canvas.node.onmousemove = function(e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
var radius = 100; // or whatever
var fillColor = '#ff0000';
var radgrad = ctx.createRadialGradient(x,y,0,x,y,radius);
radgrad.addColorStop(0, 'rgba(255,0,0,1)');
radgrad.addColorStop(0.6, 'rgba(228,0,0,.6)');
radgrad.addColorStop(1, 'rgba(228,0,0,0)');
ctx.globalCompositeOperation = 'destination-out';
ctx.fillCircle(x, y, radius, radgrad);
};
canvas.node.onmousedown = function(e) {
canvas.isDrawing = true;
};
}
var container = document.getElementById('canvas');
init(container, largeWidth, largeHeight, '#fff');
})();
/* CSS: */
body {
background: blue;
}
#canvas {
z-index: 1;
top: 0;
left: 0;
position: fixed;
}
<div id = "canvas"></div>

you should change your css as below
(function() {
var largeWidth = ( window.innerWidth * 3)+30;
var largeHeight = (window.innerHeight * 3)+30;
function createCanvas(parent, width, height) {
var canvas = {};
canvas.node = document.createElement('canvas');
canvas.context = canvas.node.getContext('2d');
canvas.node.width = largeWidth;
canvas.node.height = largeHeight;
parent.appendChild(canvas.node);
var overlay = document.getElementById("overlay");
overlay.style.width=(largeWidth -30) +"px";
overlay.style.height =( largeHeight-30)+"px";
return canvas;
}
function init(container, width, height, fillColor) {
var canvas = createCanvas(container, 3000, 3000);
var ctx = canvas.context;
ctx.fillCircle = function(x, y, radius, fillColor) {
this.fillStyle = fillColor;
this.beginPath();
this.moveTo(x, y);
this.arc(x, y, radius, 0, Math.PI * 2, false);
this.fill();
};
ctx.clearTo = function(fillColor) {
ctx.fillStyle = fillColor;
ctx.fillRect(0, 0, width, height);
};
ctx.clearTo(fillColor || "#ddd");
canvas.node.onmousemove = function(e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
var radius = 100; // or whatever
var fillColor = '#ff0000';
ctx.globalCompositeOperation = 'destination-out';
ctx.fillCircle(x, y, radius, fillColor);
};
canvas.node.onmousedown = function(e) {
canvas.isDrawing = true;
};
}
var container = document.getElementById('canvas');
init(container, largeWidth, largeHeight, '#fff');
})();
body {
background: blue;
}
#canvas {
margin: -15px;
filter: blur(10px);
-webkit-filter: blur(10px);
position: relative;
}
#overlay {
overflow:hidden;
position: fixed;
top: 0px;
left: 0px;
z-index: 1;
filter: unset;
-webkit-filter: unset;
}
<div id="overlay">
<div id="canvas">
</div>
</div>

Related

Why my small app does not draw on smartphones?

I have this code, that is meant to allow drawing on android smartphones tablets. I use touch events. With desktop events, it works, on desktop browsers, it work. In the code, I commented out the code for desktop and I left only the code for android smartphones and tablets. Any ideas please?
Here is the HTML:
<div id="canvas">Click to draw<br/></div>
Here is the JavaScript:
(function() {
// Creates a new canvas element and appends it as a child
// to the parent element, and returns the reference to
// the newly created canvas element
function createCanvas(parent, width, height) {
var canvas = {};
canvas.node = document.createElement('canvas');
canvas.context = canvas.node.getContext('2d');
canvas.node.width = width || 100;
canvas.node.height = height || 100;
parent.appendChild(canvas.node);
return canvas;
}
function init(container, width, height, fillColor) {
var canvas = createCanvas(container, width, height);
var ctx = canvas.context;
// define a custom fillCircle method
ctx.fillCircle = function(x, y, radius, fillColor) {
this.fillStyle = fillColor;
this.beginPath();
this.moveTo(x, y);
this.arc(x, y, radius, 0, Math.PI * 2, false);
this.fill();
};
ctx.clearTo = function(fillColor) {
ctx.fillStyle = fillColor;
ctx.fillRect(0, 0, width, height);
};
ctx.clearTo(fillColor || "#ddd");
// bind mouse events
/*canvas.node.onmousemove = function(e) {
if (!canvas.isDrawing) {
return;
}
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
var radius = 5; // or whatever
var fillColor = '#ff0000';
ctx.fillCircle(x, y, radius, fillColor);
};
canvas.node.onmousedown = function(e) {
canvas.isDrawing = true;
};
canvas.node.onmouseup = function(e) {
canvas.isDrawing = false;
};
*/
// bind touch events
canvas.node.ontouchmove = function(e) {
if (!canvas.isDrawing) {
return;
}
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
var radius = 5; // or whatever
var fillColor = '#ff0000';
ctx.fillCircle(x, y, radius, fillColor);
};
canvas.node.ontouchstart = function(e) {
canvas.isDrawing = true;
};
canvas.node.ontouchend = function(e) {
canvas.isDrawing = false;
};
}
var container = document.getElementById('canvas');
init(container, 200, 200, '#ddd');
})();
Link to the code: https://codepen.io/sp2012/pen/gOmGZGV
It should be because of your x and y extraction
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
Check this documentation for canvas touch events
I think you should access e.touches array to extract pageX and pageY info.
Here is a link where I made some changes to make it work for mobile. But it's just a hack :) . Also go through this link which has similar question.

Adjust canvas background in Javascript

I'm trying to drawn a rect on canvas, but I want that canvas has lightly transparent background, but that drawn rect has no background.
What I will is something as follows:
I have code as follows:
var canvas = document.getElementById('canvas');
var img = document.getElementById('photo');
var ctx = canvas.getContext('2d');
var rect = {};
var drag = false;
var update = true; // when true updates canvas
var original_source = img.src;
img.src = original_source;
function init() {
img.addEventListener('load', function(){
canvas.width = img.width;
canvas.height = img.height;
canvas.addEventListener('mousedown', mouseDown, false);
canvas.addEventListener('mouseup', mouseUp, false);
canvas.addEventListener('mousemove', mouseMove, false);
});
// start the rendering loop
requestAnimationFrame(updateCanvas);
}
// main render loop only updates if update is true
function updateCanvas(){
if(update){
drawCanvas();
update = false;
}
requestAnimationFrame(updateCanvas);
}
// draws a rectangle with rotation
function drawRect(){
ctx.setTransform(1,0,0,1,rect.startX + rect.w / 2, rect.startY + rect.h / 2);
ctx.rotate(rect.rotate);
ctx.beginPath();
ctx.rect(-rect.w/2, -rect.h/2, rect.w, rect.h);
/* ctx.fill(); */
ctx.stroke();
}
// clears canvas sets filters and draws rectangles
function drawCanvas(){
// restore the default transform as rectangle rendering does not restore the transform.
ctx.setTransform(1,0,0,1,0,0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawRect()
}
// create new rect add to array
function mouseDown(e) {
rect = {
startX : e.offsetX,
startY : e.offsetY,
w : 1,
h : 1,
rotate : 0,
};
drag = true;
}
function mouseUp() { drag = false; buttons_shown = true; update = true; }
function mouseMove(e) {
if (drag) {
rect.w = (e.pageX - this.offsetLeft) - rect.startX;
rect.h = (e.pageY - this.offsetTop) - rect.startY;
update = true;
}
}
init();
.hide{
display: none !important;
}
canvas{
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
display:inline-block;
background:rgba(0,0,0,0.3);
}
<div style="position: relative; overflow: hidden;display:inline-block;">
<img id="photo" src="http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg"/>
<canvas id="canvas"></canvas>
</div>
<div id="buttons" class="hide"></div>
In my example I set the background of the canvas to what I will but I cannot remove that background for the drawn rect, it has the same color as the canvas.
Here is the fiddle.
Any idea how to solve it?
This could be achieved in several ways (compositing, clip-path...) but the easiest for such a simple path is probably to use the "evenodd" fill-rule parameter of fill() method which will allow us to draw this rectangle with a hole.
The process is simply to draw a first rect the size of the canvas, then, in the same path declaration, draw your own smaller rectangle. The fill-rule will then exclude this smaller inner rectangle from the bigger one.
function drawRect() {
ctx.beginPath(); // a single path
// the big rectangle, covering the whole canvas
ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height);
// your smaller, inner rectangle
ctx.setTransform(1, 0, 0, 1, rect.startX + rect.w / 2, rect.startY + rect.h / 2);
ctx.rotate(rect.rotate);
ctx.rect(-rect.w / 2, -rect.h / 2, rect.w, rect.h);
// set the fill-rule to evenodd
ctx.fill('evenodd');
// stroke
// start a new Path declaration
ctx.beginPath
// redraw only the small rect
ctx.rect(-rect.w / 2, -rect.h / 2, rect.w, rect.h);
ctx.stroke();
}
var canvas = document.getElementById('canvas');
var img = document.getElementById('photo');
var ctx = canvas.getContext('2d');
var rect = {};
var drag = false;
var update = true; // when true updates canvas
var original_source = img.src;
img.src = original_source;
function init() {
img.addEventListener('load', function() {
canvas.width = img.width;
canvas.height = img.height;
canvas.addEventListener('mousedown', mouseDown, false);
canvas.addEventListener('mouseup', mouseUp, false);
canvas.addEventListener('mousemove', mouseMove, false);
// set our context's styles here
ctx.fillStyle = 'rgba(0,0,0,.5)';
ctx.strokeStyle = 'white';
ctx.lineWidth = 2;
});
// start the rendering loop
requestAnimationFrame(updateCanvas);
}
// main render loop only updates if update is true
function updateCanvas() {
if (update) {
drawCanvas();
update = false;
}
requestAnimationFrame(updateCanvas);
}
// draws a rectangle with rotation
// clears canvas sets filters and draws rectangles
function drawCanvas() {
// restore the default transform as rectangle rendering does not restore the transform.
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawRect()
}
// create new rect add to array
function mouseDown(e) {
rect = {
startX: e.offsetX,
startY: e.offsetY,
w: 1,
h: 1,
rotate: 0,
};
drag = true;
}
function mouseUp() {
drag = false;
buttons_shown = true;
update = true;
}
function mouseMove(e) {
if (drag) {
rect.w = (e.pageX - this.offsetLeft) - rect.startX;
rect.h = (e.pageY - this.offsetTop) - rect.startY;
update = true;
}
}
init();
.hide {
display: none !important;
}
canvas {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
display: inline-block;
background: rgba(0, 0, 0, 0.3);
}
<div style="position: relative; overflow: hidden;display:inline-block;">
<img id="photo" src="http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg" />
<canvas id="canvas"></canvas>
</div>
<div id="buttons" class="hide"></div>
Try filling your rect before calling ctx.stroke(), like this:
ctx.fillStyle = "rgba(255, 255, 255, 0.3)";
ctx.fill();
This will produce similar effect to what you have shown in your question. Now the inside of rectangle has both css and fillStyle effect, so it's not ideal - for even better effect you would have to fill outside of rect with desired style instead of setting background in css.
first, draw a full canvas with semi-transparent background, like
ctx.fillStyle = 'rgba(32, 32, 32, 0.7)';
ctx.fillRect(0, 0, width, height);
Then just clear your rectangular form this canvas
ctx.clearRect(x, y, mini_width, mini_height);

How to make eraser circle a gradient in canvas

I am working on a canvas java to erase a toplayer to show the rest of the image...
I would like to create a (pulsing) gradient like here http://rifke.co.uk/ though until now I only have a hard circle.
Could anyone help me out with making this (pulsating) gradient circle?
My code is shown here below.
(function() {
// Creates a new canvas element and appends it as a child
// to the parent element, and returns the reference to
// the newly created canvas element
function createCanvas(parent, width, height) {
var canvas = {};
canvas.node = document.createElement('canvas');
canvas.context = canvas.node.getContext('2d');
canvas.node.width = width || 100;
canvas.node.height = height || 100;
parent.appendChild(canvas.node);
return canvas;
}
function init(container, width, height, fillColor) {
var canvas = createCanvas(container, width, height);
var ctx = canvas.context;
// define a custom fillCircle method
ctx.fillCircle = function(x, y, radius, fillColor) {
this.fillStyle = fillColor;
this.beginPath();
this.moveTo(x, y);
this.arc(x, y, radius, 0, Math.PI * 2, false);
this.fill();
};
ctx.clearTo = function(fillColor) {
ctx.fillStyle = fillColor;
ctx.fillRect(0, 0, width, height);
};
ctx.clearTo(fillColor || "#ddd");
// bind mouse events
canvas.node.onmousemove = function(e) {
if (!canvas.isDrawing) {
return;
}
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
var radius = 55; // or whatever
var fillColor = '#ff0000';
ctx.globalCompositeOperation = 'destination-out';
ctx.fillCircle(x, y, radius, fillColor);
};
canvas.node.onmouseenter = function(e) {
canvas.isDrawing = true;
};
}
var container = document.getElementById('canvas');
init(container, 3020, 3000, '#f8fa58');
})();
body { margin: 0px;
background:black;}
#canvas {
z-index: -1;
width: 100vw;
height: 100vh;
overflow:hidden;
background: url(http://newscenario.net/bodyholes/files/works/Edward_Shenk.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
<div id="canvas"></div>
Try the following:
(function() {
// Creates a new canvas element and appends it as a child
// to the parent element, and returns the reference to
// the newly created canvas element
function createCanvas(parent, width, height) {
var canvas = {};
canvas.node = document.createElement('canvas');
canvas.context = canvas.node.getContext('2d');
canvas.node.width = width || 100;
canvas.node.height = height || 100;
parent.appendChild(canvas.node);
return canvas;
}
function init(container, width, height, fillColor) {
var canvas = createCanvas(container, width, height);
var ctx = canvas.context;
// define a custom fillCircle method
ctx.fillCircle = function(x, y, radius, fillColor) {
/*this.fillStyle = fillColor;
this.beginPath();
this.moveTo(x, y);
this.arc(x, y, radius, 0, Math.PI * 2, false);
this.fill();*/
var radgrad = ctx.createRadialGradient(x,y,0,x,y,radius);
radgrad.addColorStop(0, 'rgba(255,0,0,1)');
radgrad.addColorStop(0.5, 'rgba(228,0,0,.9)');
radgrad.addColorStop(1, 'rgba(228,0,0,0)');
// draw shape
ctx.fillStyle = radgrad;
ctx.fillRect(x-radius,y-radius,x+radius,y+radius);
};
ctx.clearTo = function(fillColor) {
ctx.fillStyle = fillColor;
ctx.fillRect(0, 0, width, height);
};
ctx.clearTo(fillColor || "#ddd");
// bind mouse events
canvas.node.onmousemove = function(e) {
if (!canvas.isDrawing) {
return;
}
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
var radius = 55; // or whatever
var fillColor = '#ff0000';
ctx.globalCompositeOperation = 'destination-out';
ctx.fillCircle(x, y, radius, fillColor);
};
canvas.node.onmouseenter = function(e) {
canvas.isDrawing = true;
};
}
var container = document.getElementById('canvas');
init(container, 3020, 3000, '#f8fa58');
})();
body { margin: 0px;
background:black;}
#canvas {
z-index: -1;
width: 100vw;
height: 100vh;
overflow:hidden;
background: url(http://i.imgur.com/UhAODHB.gif) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
<div id="canvas"></div>

Replacing color with photo in html drawing tool

In this drawing tool for html I want to replace the color (#ddd) with a photo.
Instead of the current version I want to replace the grey rectangle with a photo. Any idea on how to do that? And it won't let me reposition the rectangle, any idea why?
(function() {
function createCanvas(parent, width, height) {
var canvas = {};
canvas.node = document.createElement('canvas');
canvas.context = canvas.node.getContext('2d');
canvas.node.width = width || 100;
canvas.node.height = height || 100;
parent.appendChild(canvas.node);
return canvas;
}
function init(container, width, height, fillColor) {
var canvas = createCanvas(container, width, height);
var ctx = canvas.context;
// define a custom fillCircle method
ctx.fillCircle = function(x, y, radius, fillColor) {
this.fillStyle = fillColor;
this.beginPath();
this.moveTo(x, y);
this.arc(x, y, radius, 0, Math.PI * 2, false);
this.fill();
};
ctx.clearTo = function(fillColor) {
ctx.fillStyle = fillColor;
ctx.fillRect(0, 0, width, height);
};
ctx.clearTo(fillColor || "#ddd");
// bind mouse events
canvas.node.onmousemove = function(e) {
if (!canvas.isDrawing) {
return;
}
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
var radius = 25; // or whatever
var fillColor = '#ff0000';
ctx.globalCompositeOperation = 'destination-out';
ctx.fillCircle(x, y, radius, fillColor);
};
canvas.node.onmousedown = function(e) {
canvas.isDrawing = true;
};
canvas.node.onmouseup = function(e) {
canvas.isDrawing = false;
};
}
var container = document.getElementById('canvas');
init(container, 400, 400, '#ddd');
})();
You can achieve this by layering a solid canvas on top of another canvas. Erasing parts of the top canvas should reveal the canvas below.
The following reuses 99% of the code from two separate posts.
Loading the image onto the canvas.
Erasing the top canvas (layer).
// Borrowed from here: https://stackoverflow.com/a/4776378
var canvasWrapper = document.getElementsByClassName('layer-wrapper')[0];
var imageLayer = canvasWrapper.querySelector('.layer-image');
var drawLayer = canvasWrapper.querySelector('.layer-draw');
var img = new Image;
img.onload = function() {
imageLayer.width = drawLayer.width = img.width;
imageLayer.height = drawLayer.height = img.height;
var imageCtx = imageLayer.getContext('2d');
imageCtx.drawImage(img, 0, 0);
var drawCtx = drawLayer.getContext('2d');
drawCtx.fillStyle = '#7F7F7F';
drawCtx.fillRect(0, 0, img.width, img.height);
};
img.src = 'https://pbs.twimg.com/profile_images/462372073982025728/jTHaxsxd.jpeg';
// Borrowed from here: https://stackoverflow.com/a/25916334
var RADIUS = 32;
var canvas = canvasWrapper.querySelector('.layer-wrapper .layer-draw');
var ctx = canvas.getContext('2d');
var lastX;
var lastY;
var strokeColor = 'red';
var strokeWidth = 5;
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, RADIUS, 0, Math.PI * 2, false);
ctx.fill();
}
lastX = mouseX;
lastY = mouseY;
}
}
$(canvas).mousedown(function(e) {
handleMouseDown(e);
}).mousemove(function(e) {
handleMouseMove(e);
}).mouseup(function(e) {
handleMouseUp(e);
}).mouseout(function(e) {
handleMouseOut(e);
});
var mode = 'eraser';
//$('#pen') .click(function() { mode = 'pen'; });
//$('#eraser').click(function() { mode = 'eraser'; });
.layer-wrapper {
position: relative;
width: 400px;
height: 300px;
}
.layer-wrapper canvas.layer {
position: absolute;
top: 0;
left: 0;
}
.layer-image {
z-index: 1;
}
.layer-draw {
z-index: 100;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="layer-wrapper">
<canvas class="layer layer-image"></canvas>
<canvas class="layer layer-draw"></canvas>
</div>

Canvas HTML5 JavaScript code not working, with canvas.toDataURL()

I've failed to get this code working:
(function() {
// Creates a new canvas element and appends it as a child
// to the parent element, and returns the reference to
// the newly created canvas element
function createCanvas(parent, width, height) {
var canvas = {};
canvas.node = document.createElement('canvas');
canvas.context = canvas.node.getContext('2d');
canvas.node.width = width || 100;
canvas.node.height = height || 100;
parent.appendChild(canvas.node);
return canvas;
}
function init(container, width, height, fillColor) {
var canvas = createCanvas(container, width, height);
var ctx = canvas.context;
// define a custom fillCircle method
ctx.fillCircle = function(x, y, radius, fillColor) {
this.fillStyle = fillColor;
this.beginPath();
this.moveTo(x, y);
this.arc(x, y, radius, 0, Math.PI * 2, false);
this.fill();
};
ctx.clearTo = function(fillColor) {
ctx.fillStyle = fillColor;
ctx.fillRect(0, 0, width, height);
};
ctx.clearTo(fillColor || "#ddd");
// bind mouse events
canvas.node.onmousemove = function(e) {
if (!canvas.isDrawing) {
return;
}
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
var radius = 10; // or whatever
var fillColor = '#ff0000';
ctx.fillCircle(x, y, radius, fillColor);
};
canvas.node.onmousedown = function(e) {
canvas.isDrawing = true;
};
canvas.node.onmouseup = function(e) {
canvas.isDrawing = false;
};
}
var container = document.getElementById('canvas');
init(container, 200, 200, '#ddd');
})();
function hi(){
var canvas = document.getElementsByTagName('canvas');
var imageData = canvas.toDataURL();
document.getElementById("his").innerHTML=imageData;
}
It's a little JavaScript code, which creates a little canvas in the div with the id of canvas.
And, I'm trying to make the image save, and write to a div with the id of his the saved image. NOW that's where the code stops working... I'd greatly appreciate your help, thanks! :)
document.getElementsByTagName('canvas') returns a NodeList, not a single element. So use
function hi(){
var canvas = document.getElementsByTagName('canvas')[0];
imageData = canvas ? canvas.toDataURL() : "could not find a <canvas> element";
document.getElementById("his").textContent = imageData;
}
Image data URLs belong in image src attributes. Images don't have innerHTML.

Categories

Resources