Is it possible to have a full screen canvas element in the background of a webpage and "normal" markup elements like a table in front of it?
like the following snippet (if it wouldn't be used as alternative content):
<canvas id="imageView" width="100%" height="100%">
<table>...</table>
</canvas>
You could try setting a CSS style on the canvas where it has a position: fixed (or absolute as appropriate), and then any content that follows it (as opposed to container content as you've given in your example) should sit on top of it.
<html>
<style>
body {
margin:0;
padding:0;
}
canvas{
position:absolute;
left:0;
top:0;
z-index:-1;
}
div{
position:absolute;
z-index:0;
left:12px;
top:10px;
}
</style>
<body>
<canvas id="myCanvas" width="600" height="600" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<div>hello is floating div</div>
<script type="text/javascript">
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var grd = ctx.createLinearGradient(0, 0, 600, 600);
grd.addColorStop(0, "#FF0000");
grd.addColorStop(1, "#00FF00");
ctx.fillStyle = grd;
ctx.fillRect(0, 0, 600, 600);
</script>
</body>
</html>
I tried it for you with the following code. The div gets placed on top of the canvas element just as Matthew describes it. So should work for you:
<!DOCTYPE HTML>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Canvas demo</title>
<style type="text/css">
#canvasSection{ position:fixed;}
</style>
<script type="text/javascript">
function draw()
{
//paint the text
var canvas = document.getElementById('canvasSection');
var context = canvas.getContext('2d');
context.fillStyle = '#00f';
context.font = 'italic 30px sans-serif';
context.textBaseline = 'top';
context.font = 'bold 30px sans-serif';
context.strokeText('Your Text!!', 0, 0);
//paint the square
var canvasSquare = document.getElementById('canvasSquare');
var ctxSquare = canvas.getContext('2d');
ctxSquare.fillStyle='#FF0000';
ctxSquare.fillRect(0, 100,50,100);
}
</script>
</head>
<body onLoad="draw()">
<canvas id="canvasSection">Error, canvas is not supported</canvas>
<div>TestText</div>
</body>
</html>
You can use toDataURL() to have it in pure JS separated from HTML
var c = document.createElement('canvas'),
ctx = c.getContext('2d'),
size = c.width = c.height = 50;
for( var x = 0; x < size; x++ ){
for( var y = 0; y < size; y++ ){
ctx.fillStyle = 'hsl(0, 0%, ' + ( 100 - ( Math.random() * 15 ) ) + '%)';
ctx.fillRect(x, y, 1, 1);
}
}
document.body.style.background = 'url(' + c.toDataURL() + ')';
HTML on <b>canvas background</b>
Based on this CodePen
Related
Even I tried to find an answer I didn't found the exactly information (until now).
I have the following code:
<!DOCTYPE html personal exercise>
<html lang="en">
<head>
<title>An DOM example project</title>
<meta http-equiv="refresh" content="0.005">
<style>
div {position:absolute; margin-left:100px};
</style>
</head>
<body id="theBody" onload="show_pattern()">
<script>
function show_pattern() {
var top_position=25, left_position=25;
var width=500, height=500;
var color_list=["red", "orange", "yellow", "green", "blue", "indigo", "violet"];
var the_body=document.getElementById("theBody");
while(width>50) {
var this_div=document.createElement("div");
var random_color=Math.random()*7;
random_color=Math.floor(random_color);
this_div.style.top=top_position + "px";
this_div.style.left=left_position + "px";
this_div.style.width=width + "px";
this_div.style.height=height + "px";
this_div.style.background=color_list[random_color];
the_body.appendChild(this_div);
top_position += 10; left_position += 10;
width -= 20; height -= 20;}}
</script>
</body>
</html>
I want to display on same page two colored squares using same function (show_pattern()) and div style.
Thank you for your support!
You need to append a for loop and create within it wrapping divs for colored squares
function show_pattern() {
var color_list=["red", "orange", "yellow", "green", "blue", "indigo", "violet"];
var the_body=document.getElementById("theBody");
for(i=0; i<2; i++){
var width=500, height=500, top_position=25, left_position=25;
var wrap_div=document.createElement("div");
wrap_div.className="wrap";
wrap_div.style.left=500*i + "px";
the_body.appendChild(wrap_div);
while(width>50) {
var this_div=document.createElement("div");
var random_color=Math.random()*7;
random_color=Math.floor(random_color);
this_div.style.top=top_position + "px";
this_div.style.left=left_position + "px";
this_div.style.width=width + "px";
this_div.style.height=height + "px";
this_div.style.background=color_list[random_color];
wrap_div.appendChild(this_div);
top_position += 10; left_position += 10;
width -= 20;
height -= 20;
}
}
}
body {
height: 100vh;
}
.wrap div {
position: absolute;
}
.wrap {
display: inline-block;
position: relative;
}
<body id="theBody" onload="show_pattern()">
</body>
I want to restrict the area that an image can be drawn on a canvas. I am using Fabric.js.
I tried the following link, but it didn't work for me. Set object drag limit in Fabric.js.
I want any part of the image that would be drawn outside the red rectangle (pictured below) to just not be drawn.
var canvas = new fabric.Canvas('canvas');
$("#canvascolor > input").click(function() {
canvas.setBackgroundImage(this.src, canvas.renderAll.bind(canvas), {
crossOrigin: 'anonymous'
});
});
// trigger the first one at startup
$("#canvascolor > input:first-of-type()")[0].click();
document.getElementById('file').addEventListener("change", function(e) {
var file = e.target.files[0];
var reader = new FileReader();
console.log("reader " + reader);
reader.onload = function(f) {
var data = f.target.result;
fabric.Image.fromURL(data, function(img) {
var oImg = img.set({
left: 140,
top: 100,
width: 250,
height: 200,
angle: 0
}).scale(0.9);
oImg.lockMovementX = true;
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({
format: 'png',
quality: 0.8
});
});
};
reader.readAsDataURL(file);
});
document.querySelector('#txt').onclick = function(e) {
e.preventDefault();
canvas.deactivateAll().renderAll();
document.querySelector('#preview').src = canvas.toDataURL();
};
canvas {
border: 1px solid black;
}
#canvascolor input {
height: 50px;
width: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file">
<canvas id="canvas" width="520" height="520"></canvas>
<section id="canvascolor">
<input class="canvasborder" type="image" src="https://dl.dropboxusercontent.com/s/9leyl96qd3tytn8/tshirt-front.jpg">
<input class="canvasborder" type="image" src="https://dl.dropboxusercontent.com/s/tk0fs5v4muo6898/tshirt-back.jpg">
</section>
<button href='' id='txt' target="_blank">submit</button><br/>
<img id="preview" />
I extended your script to answer you.
For your use case it looks like you could use some clipping function and uniform centered scaling.
Anyway the main question about restricting area for drawing is this:
var canvas = new fabric.Canvas('canvas');
$("#canvascolor > input").click(function() {
canvas.setBackgroundImage(this.src, canvas.renderAll.bind(canvas), {
crossOrigin: 'anonymous'
});
});
// trigger the first one at startup
$("#canvascolor > input:first-of-type()")[0].click();
function clipTShirt(ctx) {
ctx.save();
ctx.setTransform(1, 0, 0, 1, 0, 0);
var x = 140, y = 100 ,w = 225, h = 300;
ctx.moveTo(x, y);
ctx.lineTo(x + w, y);
ctx.lineTo(x + w, y + h);
ctx.lineTo(x, y + h);
ctx.lineTo(x, y);
ctx.restore();
}
document.getElementById('file').addEventListener("change", function(e) {
var file = e.target.files[0];
var reader = new FileReader();
console.log("reader " + reader);
reader.onload = function(f) {
var data = f.target.result;
fabric.Image.fromURL(data, function(img) {
var oImg = img.set({
left: 140,
top: 100,
width: 250,
height: 200,
angle: 0,
lockUniScaling: true,
centeredScaling: true,
clipTo: clipTShirt
}).scale(0.9);
oImg.lockMovementX = true;
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({
format: 'png',
quality: 0.8
});
});
};
reader.readAsDataURL(file);
});
document.querySelector('#txt').onclick = function(e) {
e.preventDefault();
canvas.deactivateAll().renderAll();
document.querySelector('#preview').src = canvas.toDataURL();
};
canvas {
border: 1px solid black;
}
#canvascolor input {
height: 50px;
width: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file">
<canvas id="canvas" width="520" height="520"></canvas>
<section id="canvascolor">
<input class="canvasborder" type="image" src="https://dl.dropboxusercontent.com/s/9leyl96qd3tytn8/tshirt-front.jpg">
<input class="canvasborder" type="image" src="https://dl.dropboxusercontent.com/s/tk0fs5v4muo6898/tshirt-back.jpg">
</section>
<button href='' id='txt' target="_blank">submit</button><br/>
<img id="preview" />
<html>
<head>
<style type="text/css">
canvas{
border:1px solid #ccc;
}
.canvas-container{
float: left;
left: 20px;
}
</style>
</head>
<body>
<canvas id='canvas' width='500' height='600' ></canvas>
<canvas id='C2' width='500' height='600'></canvas>
<script type="text/javascript" src="fabric.js"></script>
<script>
(function() {
var canvas = this.__canvas = new fabric.Canvas('canvas');
fabric.Object.prototype.transparentCorners = false;
var radius = 300;
fabric.Image.fromURL('./images/Chrysanthemum.jpg', function(img) {
img.scale(0.4).set({
left: 10,
top: 100,
angle: 0,
clipTo: function (ctx) {
ctx.rect(-250, -250, 400, 400);
}
});
canvas.add(img).setActiveObject(img);
console.log(canvas.getActiveObject());
});
})();
</script>
</body>
----------
</html>
//the code above;
Now the active object size is the same as the image which has not been cropped;
But if there is any way to make the cropped image to be selected.Means the smaller size which will be selected in a smaller size.
thx!
Clip is not meant for that effect:
If you desire some cropping better go with pattern trick if your cropping differs from what the attribute preserverveAspectRatio allows you.
(basically crop in center, crop left crop right, both for x and y axis).
As you see instead of image i create a rect with desired dimensions, then i use the img loaded to create a pattern that will fill the rect.
You can then use offsetX and offsetY on pattern to modify the part of image visible.
offsets are accessible trought:
rect.fill.offsetX
rect.fill.offsetY
(function() {
var canvas = this.__canvas = new fabric.Canvas('canvas');
fabric.Object.prototype.transparentCorners = false;
var radius = 300;
fabric.Image.fromURL('http://fabricjs.com/assets/pug.jpg', function(img) {
var rect = new fabric.Rect({width: 400, height: 400});
var pattern = new fabric.Pattern({source: img.getElement(), offsetX: -20, offsetY: -50});
rect.scale(0.4).set({
left: 10,
top: 100,
angle: 0,
fill: pattern,
});
canvas.add(rect).setActiveObject(rect);
});
})();
canvas{
border:1px solid #ccc;
}
.canvas-container{
float: left;
left: 20px;
}
<canvas id='canvas' width='500' height='600' ></canvas>
<canvas id='C2' width='500' height='600'></canvas>
<script type="text/javascript" src="http://fabricjs.com/lib/fabric.js"></script>
Canvas stroke() seems to be broken in chrome version 44
see test: https://jsfiddle.net/n9ds4q8m/ click on test button
works fine in FF/IE even Edge. Grid does not show in Chrome but used to?
var canvas = document.getElementById("drawing");
// if the canvas element exists
if (canvas != null) {
var ctx = canvas.getContext("2d");
ctx.setLineDash([null]);
ctx.lineWidth = 0.5;
ctx.strokeStyle = "#eeeeee";
// horizontal grid lines
for (var i = 0; i <= canvas.height; i = i + 10) {
ctx.beginPath();
ctx.moveTo(0, i);
ctx.lineTo(canvas.width, i);
if (i % parseInt(50) == 0) {
ctx.lineWidth = 2;
} else {
ctx.lineWidth = 0.5;
}
ctx.closePath();
ctx.stroke();
}
// vertical grid lines
for (var j = 0; j <= canvas.width; j = j + 10) {
ctx.beginPath();
ctx.moveTo(j, 0);
ctx.lineTo(j, canvas.height);
if (j % parseInt(50) == 0) {
ctx.lineWidth = 2;
} else {
ctx.lineWidth = 0.5;
}
ctx.closePath();
ctx.stroke();
}
}
}
HTML: <body>
<form id="form1" runat="server">
<div><input type="button" onclick="draw()" value="test" />
<canvas id="drawing" width="800" height="550" style="position: relative; cursor: crosshair; border: 1px solid #000; z-index: 10; -ms-touch-action: none; touch-action: none;"></canvas>
</div>
</form>
</body>
I'm glad you noticed this. I sort of noticed this a few days ago, but didn't set out to really investigate it until today. I have narrowed down the problem. It doesn't like the
ctx.setLineDash([null]);
part. In my code, I was using
ctx.setLineDash([0,0]); and it doesn't like that either.
After some more investigating, it seems that [0,0] doesn't make any sense, even though Firefox allows it that way. Also, [null] isn't spec compliant. So the best way to make solid lines is
ctx.setLineDash([]);
How can I use jQuery to follow the cursor with a DIV?
You can't follow the cursor with a DIV, but you can draw a DIV when moving the cursor!
$(document).on('mousemove', function(e){
$('#your_div_id').css({
left: e.pageX,
top: e.pageY
});
});
That div must be off the float, so position: absolute should be set.
You don't need jQuery for this. Here's a simple working example:
<!DOCTYPE html>
<html>
<head>
<title>box-shadow-experiment</title>
<style type="text/css">
#box-shadow-div{
position: fixed;
width: 1px;
height: 1px;
border-radius: 100%;
background-color:black;
box-shadow: 0 0 10px 10px black;
top: 49%;
left: 48.85%;
}
</style>
<script type="text/javascript">
window.onload = function(){
var bsDiv = document.getElementById("box-shadow-div");
var x, y;
// On mousemove use event.clientX and event.clientY to set the location of the div to the location of the cursor:
window.addEventListener('mousemove', function(event){
x = event.clientX;
y = event.clientY;
if ( typeof x !== 'undefined' ){
bsDiv.style.left = x + "px";
bsDiv.style.top = y + "px";
}
}, false);
}
</script>
</head>
<body>
<div id="box-shadow-div"></div>
</body>
</html>
I chose position: fixed; so scrolling wouldn't be an issue.
This works for me. Has a nice delayed action going on.
var $mouseX = 0, $mouseY = 0;
var $xp = 0, $yp =0;
$(document).mousemove(function(e){
$mouseX = e.pageX;
$mouseY = e.pageY;
});
var $loop = setInterval(function(){
// change 12 to alter damping higher is slower
$xp += (($mouseX - $xp)/12);
$yp += (($mouseY - $yp)/12);
$("#moving_div").css({left:$xp +'px', top:$yp +'px'});
}, 30);
Nice and simples