How do I replace an image on a canvas onclick? - javascript

I'm using fabricjs to place an image on a canvas. I'd like to learn what I need to do to to replace the already drawn image with another one from a url onclick.
My limited understanding has me thinking I need to maybe set a var for each image but I'm not sure how to connect that with the fabricjs canvas. I've spent the last few hours trying different things without any luck.
I tried submitting a similar question but deleted it because I thought maybe it was too complicated an ask. Any help would be greatly appreciated. Here's my code now:
var canvas = new fabric.Canvas('c');
fabric.Image.fromURL('http://lorempixel.com/400/400/', function(img) {
var oImg = img.set({
selectable: false
})
canvas.add(oImg).renderAll();
});
canvas {
border: 1px solid #dddddd;
border-radius: 3px;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<canvas id="c" width="400" height="400"></canvas>

This is how you could achieve that :
var canvas = new fabric.Canvas('c');
var image, isImageLoaded;
fabric.Image.fromURL('//lorempixel.com/200/200/', function(img) {
isImageLoaded = true;
image = img.set({
selectable: false
})
canvas.add(image).renderAll();
});
function replaceImage(imgUrl) {
if (!isImageLoaded) return; //return if initial image not loaded
var imgElem = image._element; //reference to actual image element
imgElem.src = imgUrl; //set image source
imgElem.onload = () => canvas.renderAll(); //render on image load
}
canvas.on('mouse:down', function() {
replaceImage('//lorempixel.com/200/200/');
});
canvas {
border: 1px solid #dddddd;
border-radius: 3px;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<canvas id="c" width="200" height="200"></canvas>
PS: apology for not giving that much explanation.

You can do this much simpler. Don't see why you'd use an extra lib for something like this. I wrote something small in plain JS which hopefully helps you further.
document.getElementById("image").onclick = function(){
document.getElementById("image").src = "http://lorempixel.com/400/400/";
};
<img id="image" src="http://lorempixel.com/400/400/">

var canvas = new fabric.Canvas('c');
var oImg;
loadImage();
function loadImage(){
fabric.Image.fromURL('https://lorempixel.com/400/400/', function(img) {
oImg && canvas.remove(oImg); //If image element alread added to canvas remove it.
oImg = img.set({
selectable: false
})
canvas.add(oImg); //add new image to canvas
oImg.on('mousedown',onImgMouseDown); //add mouse down lisner to image
});
}
function onImgMouseDown(){
loadImage();
}
canvas {
border: 1px solid #dddddd;
border-radius: 3px;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<canvas id="c" width="400" height="400"></canvas>
Alternative you add mousedown listener to image , and check if element added ,then remove it from canvas. then add new one to canvas.

Related

How to trigger or receive events of objects in the group?

I use Fabric.js to develop a ppt editor in online. I have a problem, a group A has B and C, I can listen Events of A, but I need also listen events of it's A and B. How to do it?
you need to set subTargetCheck true for group object and then you can access subtargets from event which contains array of subTargets[]
var canvas = new fabric.Canvas('c');
var rect = new fabric.Rect({
width:100,height:100,left:10,top:10,fill:'red'
});
var circle = new fabric.Circle({
left:150,top:10,fill:'green',radius:50
});
var group = new fabric.Group([rect,circle],{
left:20,
top:20,
subTargetCheck: true
});
canvas.add(group);
group.on('mousedown',onMouseDown);
function onMouseDown(option){
option.subTargets[0] && console.log(option.subTargets[0].type)
}
canvas{
border: 1px solid #000;
}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="400" height="400"></canvas>

Create non-animated spritesheet in JS

I'm struggling to get an image of a deck of small cards into spritesheet form using javascript. I need to get them into an array so as to shuffle them. Here's what I've got so far. Only the canvas shows up light blue against a dark blue background.
<html>
<head>
<style>
canvas#game-canvas {
position: absolute;
top: 5%;
left: 5%;
background: lightblue;
height: 281px;
width: 500px;
}
body {
background: darkblue;
}
</style>
<script type="text/javascript" src="jquery1_10_2_min.js"></script>
<script>
var canvas = document.getElementById("game-canvas");
var ctx = canvas.getContext("2d");
function SpriteSheet(path, frameWidth, frameHeight) {
this.image = new Image();
this.frameHeight = frameHeight;
this.frameWidth = frameWidth;
// calculate the number of frames in a row after the image loads
var self = this;
this.image.onload = function() {
self.framesPerRow = Math.floor(this.image.width / frameWidth);
};
this.image.src = path;
}
var spritesheet = new SpriteSheet('small_playing_cards.png', 54, 65);
</script>
</head>
<body>
<canvas id="game-canvas"></canvas>
</body>
</html>
That's an duplicated answer, anyway you can do it by creating one new canvas and drawing it on the main.
PS: that's not my costume code, so I'll do somethings I'd not do, as create variables, etc.
1. Create canvas element asigned as value from one variable;
var Area=document.createElement("canvas")
2. Set the frame size to this canvas;
Area.width=FrameWidth,
Area.height=FrameHeight
3. Draw the spritesheet in this canvas in the x/y (negative) where the frame you want is located;
var AContext=Area.getContext("2d");
AContext.drawImage(SpriteSheet,0-FrameX,0-FrameY);
4. Draw this canvas as image in the main canvas, but with x/y preference;
MainCanvas.drawImage(Area,PreferenceX,PreferenceY)
It's like these steps you can draw one frame from an spritesheet image. I'm not sure if it's that you want, I can't understand your question as well.

How to add image to fabric canvas?

I want to add images/icons to my fabric canvas. The code given on the Fabric demo is not working.
fabric.Image.fromURL('my_image.png', function(oImg) {
canvas.add(oImg);
});
This just makes my entire canvas blank.
I want to add icons as clickable elements which respond to events.
I have done a jsfiddle that loads a jpg image on the canvas, by using the
fabric.Image.fromURL() function and the 'mouse:down' event. Inside the mouse:down i check if the user clicks on an object or just on the canvas.
here is a snippet of the javascript:
var canvas = new fabric.Canvas('c');
canvas.backgroundColor = 'yellow';
fabric.Image.fromURL('http://fabricjs.com/assets/pug_small.jpg', function(myImg) {
//i create an extra var for to change some image properties
var img1 = myImg.set({ left: 0, top: 0 ,width:150,height:150});
canvas.add(img1);
});
canvas.on('mouse:down',function(event){
if(canvas.getActiveObject()){
alert(event.target);
}
})
but my example also works ok ,if i dont use the extra variable:
fabric.Image.fromURL('http://fabricjs.com/assets/pug_small.jpg', function(myImg) {
canvas.add(myImg);
});
if you need more fabric events you can take a look here : http://fabricjs.com/events/
jsfiddle : https://jsfiddle.net/tornado1979/5nrmwtxu/
Hope helps , good luck.
This code is working properly but you need to use fabric.js file.
You also need to use fabric.js CDN file in your header.
Fabric.js CDN->
var canvas = new fabric.Canvas('drawarea');
var imgElement = document.getElementById('my-image');
var imgInstance = new fabric.Image(imgElement, {
left: 100,
top: 100,
angle: 0,
opacity: 0.75,
width:300,
height:300
});
canvas.add(imgInstance);
#my-image{display:none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<canvas width="800" height="800" id="drawarea" style="border: 1px solid red;float: right"> </canvas>
<img src="https://via.placeholder.com/300.png" id="my-image" width="500px" height="500px">

SVG images not downloading in as pdf in firefox [duplicate]

I have a canvas element with some doodling in it.
I am using the following to convert the canvas to a jpeg:
var data = canvas.toDataURL( "image/jpeg", 0.5 );
var img = new Image();
img.src = data;
$( "body" ).append( img );
However instead of my doodle, I get a solid black jpeg.
Can anyone tell me what I'm doing wrong?
Thanks!
Thats happening because the JPEG does not support a transparent background.. if you want that to be supported use png (the default extension) else you can set a non transparent fill color to the canvas using .fillStyle and .fillRect
Image created with a "image/jpeg" type have a default black background. Consider the snippet below in which the canvas is on the left and the captured image is on the right:
var canvas = $("#c").get(0), ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect(40,60,20,20);
var data = canvas.toDataURL("image/jpeg");
var img = new Image();
img.src = data;
$( "body" ).append( img );
var data = canvas.toDataURL("image/png");
var img = new Image();
img.src = data;
$( "body" ).append( img );
canvas { border: thin solid green; }
img { border: thin solid black; margin-right: 5px; }
body { background-color: #DFF; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="c" width="100"></canvas>
If you've only drawn black shapes on the canvas, you won't see them against a default black JPEG background.
If you instead use the type image/png, the background will be transparent by default.

I am having trouble processing my image using HTML5 Canvas and Javascript Filters from Pixastic, what am I doing wrong?

The Javascript "pixastic.custom (5) file was created from Pixastic using just the core code and "lighten" filter. The code works to redraw the image in the canvas in a Mozilla Broweser, however it is not filtering it. The HTML5 is coding the canvas, drawing the image on the canvas, and supposed to be redrawing the image through the Javascript Filter on to the canvas where it would then be lightened. Does any of this make sense?
Here is my code below:
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript" charset="utf-8" src="pixastic.custom (5).js"></script>
<style>
body {
margin: 0px;
padding: 0px;
}
#myCanvas {
border: 1px solid #9C9898;
}
</style>
<script>
window.onload = function() {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var imageObj = new Image();
imageObj.onload = function() {
var options ={};
Pixastic.process(imageObj, "lighten", options)
{amount : .5
};
options.resultCanvas;
context.drawImage(imageObj, 80, 60);
}
imageObj.src = "IMAG8703.jpg";
};
</script>
</head>
<body>
<canvas id="myCanvas" width="2000" height="4000"></canvas>
</body>
</html>
Thank you for looking over my code...I really have no idea why it isn't working. Everything is in the same directory and everything matches up. The code is combined from the PIXASTIC site with HTML5 Canvas framework everything should work smoothly...
The problem is at the 7th line from the script tag. Not sure what you are trying to do but there's gonna be an error.
This is legal.
Pixastic.process(imageObj, "lighten", {amount : .5});

Categories