fabric js canvas doesn't render images - javascript

I put an image and a textbox on a FabricJS canvas, but only the textbox is rendered. I also tried to export the whole canvas as an image, but still, only the textbox showed up. If I print out all objects on canvas in the console, the image instance is there, but why it's not rendered? Here is the JS Fiddle,
Here is the full HTML file
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.3.1/fabric.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
</head>
<style>
#c {
border: 2px solid black;
}
#render {
border: 2px solid red;
}
</style>
<body>
<h2>This is the test image</h2>
<img id='testImg' src="https://picsum.photos/seed/123/50/50" crossorigin="anonymous">
<h2>Fabric canvas</h2>
<canvas id='c'></canvas>
<h2>Save canvas as an image</h2>
<div id='render'></div>
<script>
var canvas = new fabric.Canvas('c');
canvas.setHeight(200);
canvas.setWidth(200);
//add image
var imgEle = $("#testImg")[0];
var newImg = new fabric.Image(imgEle, {
left: 0,
top:0
});
canvas.add(newImg);
canvas.renderAll();
//add new textbox
var newTextBox = new fabric.Textbox("Hello text box", {
left: 0,
top: 100,
width: 200
});
canvas.add(newTextBox);
canvas.renderAll();
//two objects are stored in canvas
console.log(JSON.stringify(canvas));
//show the canvas image, only one object shows
var canvasUrl = canvas.toDataURL('png');
var canvasImg = $("<img id=canvasImg>");
canvasImg.attr('src', canvasUrl);
canvasImg.appendTo("#render");
</script>
</body>
</html>

In your code you are not waiting for the image to load, so what happens is that the new fabric.Image executes before the image has fully loaded, that is why you only see the text.
We need an onload on the image.
See the code below:
var canvas = new fabric.Canvas('c');
canvas.setHeight(120);
canvas.setWidth(200);
$("#testImg")[0].onload = function () {
var newImg = new fabric.Image(this, { left: 10, top: 10 });
canvas.add(newImg);
canvas.renderAll();
}
var newTextBox = new fabric.Textbox("Hello", { left: 0, top: 70, width: 90 });
canvas.add(newTextBox);
canvas.renderAll();
#c {
border: 2px solid black;
}
#render {
border: 2px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.6.2/fabric.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
This is the test image
<img id='testImg' src="https://picsum.photos/seed/123/50/50" crossorigin="anonymous">
<canvas id='c'></canvas>

Related

Dynamically retrieve image dimensions using html/js

I am currently trying to create a web app to be able to upload images on a canvas using fabric.js. I am able to upload the images but have been unable to retrieve the dimensions of the image when I resize the image inside the canvas. Is there a way, that can be solved? Also, how do I handle it when multiple images are uploaded in realtime?
<!DOCTYPE html>
<html>
<head>
<title>Test Project</title>
</head>
<body>
<style>
canvas{
border: 1px solid black;
position: absolute;
top: 0px;
left: 0px;
}
</style>
<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"><br />
<canvas id="canvas" width="1000" height="1000"></canvas>
<script>
var canvas = new fabric.Canvas('canvas');
document.getElementById('file').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: 0}).scale(0.2);
console.log(oImg.height)
console.log(oImg.width)
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({format: 'png', quality: 1});
oImg.setControlsVisibility({ mtr: false })
});
};
reader.readAsDataURL(file);
});
</script>
</body>
</html>
In Fabric.js, an image's scaled width/height values can be obtained with the getScaledWidth() and getScaledHeight() methods.
<!DOCTYPE html>
<html>
<head>
<title>Test Project</title>
</head>
<body>
<style>
canvas{
border: 1px solid black;
position: absolute;
top: 0px;
left: 0px;
}
</style>
<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"><br />
<canvas id="canvas" width="1000" height="1000"></canvas>
<script>
var canvas = new fabric.Canvas('canvas');
document.getElementById('file').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: 0}).scale(0.2);
console.log(oImg.getScaledWidth())
console.log(oImg.getScaledHeight())
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({format: 'png', quality: 1});
oImg.setControlsVisibility({ mtr: false })
});
};
reader.readAsDataURL(file);
});
</script>
</body>
</html>

how can I change the thickness of the pen on the canvas below using an input range?

How can I change the thickness of the pen on canvas with JQuery?
I have used a canvas and I want to put the range below the canvas and it should be hidden when the page is loaded and after clicking on a button it should be appeared.
body {
background: #384047;
font-family: sans-serif;
}
canvas {
background: #fff;
display: block;
margin: 50px auto 10px;
border-radius: 5px;
box-shadow: 0 4px 0 0 #222;
cursor: url(http://s8.picofile.com/file/8333405442/download.png), pointer;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="001.css">
</head>
<body>
<canvas width="600" height="400" ></canvas>
</body>
</html>
Here's an example, I'll quickly explain:
You cannot change the width and height of the cursor property in CSS, only the x and y coordinates - read the MDN Reference. So to render a custom cursor, simply make a new Image object, set cursor: none; and render the custom cursor on the canvas like you would any other canvas element. The slider value scales the width and height of the cursor. If you have any questions, feel free to ask.
var canvas = document.getElementById("c"); //define DOM content
var ctx = canvas.getContext("2d");
var slider = document.getElementById("range");
var btn = document.getElementById("btn");
var clicked = false;
var cursor = new Image(); //load img
cursor.src = "cursor.png"; //change this to your img
cursor.w = cursor.h = 50;
btn.addEventListener("click", e => { //When btn is clicked
slider.style.display = "block"; //display range
});
c.addEventListener("mousemove", e => {
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.drawImage(cursor, e.pageX - cursor.w/2, e.pageY - cursor.h/2, cursor.w, cursor.h);
});
slider.addEventListener("click", e => {
check();
});
function check() {
if (slider.value !== cursor.w) { //if unique value
cursor.w = cursor.h = slider.value; //width and height scale based on slider
}
}
canvas {
cursor: none;
}
#range {
display: none;
}
<canvas id="c" width="600" height="400" ></canvas>
<input id="btn" type="button" value="activate" />
<input id="range" type="range" />

DrawImage on Canvas HTML5 Error

So when I try to draw image on canvas like this (it works fine):
<html>
<head>
<title>HTML5 canvas</title>
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
$(document).ready(start);
var image1;
function start() {
var ctx = $('#canvas').get(0).getContext('2d');
image1 = new Image;
image1.src = "/arenag/arenagimg/BeastBear.jpg";
image1.onload = function () {
ctx.drawImage(image1.src,200, 200, 100, 100);
};
}
</script>
<style type="text/css">
#framework {
border: 2px solid #000;
width: 100%;
text-align: center;
}
#canvas {
background-color: #00FFE2;
margin-right: auto;
margin-left: auto;
}
</style>
</head>
<body>
<div id="framework">
<canvas id="canvas" width="1024" height="768"></canvas>
</div>
</body>
</html>
Then i add a folder called imagefactory.js and create a class ImageFactory,and create function in that class called drawImage:
var ImageFactory = function (ctx) {
this.ctx = ctx;
this.drawImage = function (image_arg, image_x, image_y, image_w, image_h) {
var _this = this;
var image = new Image;
image.src = image_arg;
image.onload = function () {
_this.ctx.drawImage(image.src, image_x, image_y, image_w, image_h);
};
};
};
Then I simply try to call that function in my main file:
<html>
<head>
<title>HTML5 canvas</title>
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
$(document).ready(start);
var image;
function start() {
image = '/arenag/arenagimg/BeastBear.jpg';
var ctx = $('#canvas').get(0).getContext('2d');
var imageFactory=new ImageFactory(ctx);
imageFactory.drawImage(image,200, 200, 100, 100);
}
</script>
<style type="text/css">
#framework {
border: 2px solid #000;
width: 100%;
text-align: center;
}
#canvas {
background-color: #00FFE2;
margin-right: auto;
margin-left: auto;
}
</style>
</head>
<body>
<div id="framework">
<canvas id="canvas" width="1024" height="768"></canvas>
</div>
</body>
</html>
I get this error(on 36 line in my main (HTML) file where the canvas is) :
Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(HTMLImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap)'
And also this bug which is connected to the other one(i mean when there is no this bug then there is no the first bug too):
[object%20HTMLImageElement]:1 GET http://phpcasovi.dev/arenag/klase/[object%20HTMLImageElement] 404 (Not Found)
And i wanted to just give you a help to solve this : When i change var image = new Image;to var image = {};in JS file.Then there is no bug but becuase var image is not equal to new Image well then there is no images at all.So i think bug is at that line where i say var image = new Image; but i dont know why there is a bug (why should it be)??
First argument for context.drawImage should be Image-Object not image.src
From docs, ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);, image, An element to draw into the context. The specification permits any canvas image source (CanvasImageSource), such as an HTMLImageElement, an HTMLVideoElement, an HTMLCanvasElement or an ImageBitmap.
var ImageFactory = function(ctx) {
this.ctx = ctx;
this.drawImage = function(image_arg, image_x, image_y, image_w, image_h) {
var _this = this;
var image = new Image();
image.src = image_arg;
image.onload = function() {
_this.ctx.drawImage(image, image_x, image_y, image_w, image_h);
};
};
};
$(document).ready(start);
function start() {
var image = 'https://www.google.com/images/branding/googlelogo/1x/googlelogo_white_background_color_272x92dp.png';
var ctx = $('#canvas').get(0).getContext('2d');
var imageFactory = new ImageFactory(ctx);
imageFactory.drawImage(image, 200, 200, 100, 100);
}
#framework {
border: 2px solid #000;
width: 100%;
text-align: center;
}
#canvas {
background-color: #00FFE2;
margin-right: auto;
margin-left: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="framework">
<canvas id="canvas" width="1024" height="768"></canvas>
</div>
Fiddle Demo

JQuery / Javascript - Mouse Location completely off

I'm trying to make a 'draw' app, which allows the user to draw something by dragging their mouse over a canvas.
I want to draw a 'pixel' where the user drags their mouse, however: The location of the mouse and the location where the 'pixels' get drawn are not the same.
I've searched all over the internet but I don't know what the difference is with my version and with theirs.
Image:
HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Drawer</title>
<script src="jquery-2.2.1.min.js"></script>
<script src="scripting/draw.js"></script>
</head>
<body>
<canvas id="drawGround" style="width: 500px; height: 500px; margin: 0 auto; border: 1px solid black;"></canvas>
</body>
</html>
Code:
$(document).ready(function() {
var drawSize = 3;
var canDrawCanvas = false;
const canvasID = "#drawGround";
document.onmouseup = function() {
canDrawCanvas = false;
};
$(canvasID).mousedown(function() {
canDrawCanvas = true;
});
$(canvasID).mousemove(function(event) {
if (canDrawCanvas) handleDrawing(event);
});
function handleDrawing(mouseEvent) {
var canvas = document.getElementById(canvasID.substring(1));
var context = canvas.getContext('2d');
context.fillRect(mouseEvent.pageX, mouseEvent.pageY, drawSize, drawSize);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="drawGround" style="width: 500px; height: 500px; margin: 0 auto; border: 1px solid black;"></canvas>
Instead of scaling the canvas object with the "style" attribute, you should use the "width" and "height"-attributes in the canvas-element.
<canvas id="drawGround" width="500px" height="500px" style="margin: 0 auto; border: 1px solid black;"></canvas>
Then use the offsetX and offsetY parameters instead of pageX and pageY to get the tip position of the mouse:
function handleDrawing(mouseEvent) {
var canvas = document.getElementById(canvasID.substring(1));
var context = canvas.getContext('2d');
context.fillRect(mouseEvent.offsetX, mouseEvent.offsetY, drawSize, drawSize);
}

I cannot draw the image in chrome correctly

Here simple code1 which work fine Demo jsFiddle ,I want the same result in code2
Here the code2 Demo jsfiddle which have two problems.
The scale is not correct to 1400x700 pix
I can only successes to draw from inside function loadImage()
function loadImage(){
oG.width = 1400;
oG.height = 700;
oG.drawImage(scrollImg,0,0);
}
I want to draw from scrollObject.draw()
var scrollObject = {
draw : function() {
oG.drawImage(scrollImg,0,0);
}
};
How can I do that ?
Many thanks.
code1;
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
#mycanvas{
border: 1px solid #9C9898;
}
</style>
</head>
<body >
<canvas id="mycanvas" width="1400" height="700" ></canvas>
<script type="text/javascript">
// get the canvas element using the DOM http://jsfiddle.net/centerwow/Z2UzF/show/
var context = document.getElementById('mycanvas').getContext("2d");
context.width = 1400 ;
context.height = 700 ;
var img = new Image();
img.src = "http://s9.postimage.org/433ecr79b/grid.png";
img.onload = function () {
context.clearRect(0,0,1400,700);
context.drawImage(img, 0, 0);
}
</script>
</body>
</html>
code2:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title> image not display correct</title>
<style type='text/css'>
body {
background-color:black;
}
.Container {
position: relative;
margin-left:auto;
margin-right:auto;
top:10px;
background-image:url('http://s8.postimage.org/jnu65wk2d/Box_Grass200x100.jpg');
background-repeat:repeat;
width:1000px;
height:500px;
z-index:0;
overflow:hidden;
}
#layer1{
position:absolute;
padding:0;
margin: 0px;
z-index:2;
top:-100px;
left:-200px;
width:1400px;
height:700px;
}
</style>
</head>
<body >
<div class="Container">
<canvas id="layer1">LAYER1</canvas>
</div>
<script type='text/javascript'>//http://jsfiddle.net/centerwow/Z2UzF/1/show/
function loadImage(){
oG.width = 1400;
oG.height = 700;
oG.drawImage(scrollImg,0,0);
}
//layer 1 image then will be object objectGame = oG
var oG = document.getElementById('layer1').getContext("2d");
scrollImg = new Image();
scrollImg.src = "http://s9.postimage.org/433ecr79b/grid.png"; //image size 1400x700px
scrollImg.onload = loadImage;
var scrollObject = {
// Basic attributes
draw : function() {
oG.drawImage(scrollImg,0,0);
}
};
// Now moving it
function move() {
//handle with object background
//clearRect(x, y, width, height)
oG.clearRect(0,0,1400,700);
scrollObject.draw();
}
move();
</script>
</body>
</html>
You can only draw on loadImage(), because when you trigger move() the image have not been loaded yet. You can use a assetmanager to download your assets like images, sounds etc. Here is a great guide to build one - http://www.html5rocks.com/en/tutorials/games/assetmanager/
And for the scale, you can pass a width and height argument to the drawImage function.
context.drawImage(image, x, y, width, height);
You are also setting the height and width of the 2d-context, that you cannot do. Set the width and height in the <canvas> attributes. I once had problems with height/width when I used css, so I would not recommend setting the width/height there.

Categories

Resources