I have read several questions/answers about this topic, but I can't seem to find my solution. So sorry if you guys find this question duplicated.
Here is my situation;
Let's say I have a menu for user to click on it and it will display the image of that selected item on canvas, also user can resize/drag/drop that image as they want. Right now I can make it works only one time with this code
addAction(selectedAction: any) {
var canvas = new fabric.Canvas('c');
var imgObj = new Image();
imgObj.src = selectedAction.image;
imgObj.onload = function() {
var imgInstance = new fabric.Image(imgObj, {
left: 200,
top: 200,
});
canvas.add(imgInstance);
}
The problem is when user click another item in the menu, the previous item that was on the canvas disappear, instead the current item display on the canvas. But if I click on that image, it will disappear and the previous image display on the canvas.
I want them BOTH stay on the canvas at the same time. Please advice.
Real quick answer: http://jsfiddle.net/8yf15nqp/1/.
var canvas = ...// setup canvas
function addImage (url) {
fabric.Image.fromURL(url, function (img) {
// deal with image
canvas.add(img);
});
}
Setup a function to handle adding and then call it when you want to add a new image. I'd assume you'll want to pass the url to the function and do other stuff, but this is a pretty stripped down example.
Related
I started to play with canvas coding and I'm stuck on a (most likely) very easy issue. I have a code which on click lads some image, and I would like to put the image on canvas when it's loaded. When I go to diagnostic tools in Chrome, the pictures get loaded and there is no errors in the console, yet the images do get drawn on the canvas.
any ideas why?
sAlphaF = new Image();
sAlphaF.src = '/img/sAlpha_'+tbaID+'_f.png';
sAlphaF.onload = function(){
var ctxs=gc.getContext("2d");
ctxs.drawImage(sAlphaF,0,0, gc.width, gc.length);
};
tAlphaF = new Image();
tAlphaF.src = '/img/tAlpha_'+tbaID+'_f.png';
tAlphaF.onload = function(){
var ctxt=bc.getContext("2d");
ctxt.drawImage(tAlphaF,0,0, bc.width, bc.length);
};
Change your bc.length property to bc.height ;)
I am trying to to write undo/Redo functionality on canvas . i am using fabric-js to draw Objects . undo ?Redo is working fine but the problem is after calling undo/redo function if i click on canvas Elements goes Invisible. i tried canvas.renderAll() still i am getting problem.
Steps for Undo::
Before Element Drawn i am saving canvas.toDataURl() in an variable Array.
2.When Undo Button is clicked i am using clear method of fabric to clear canvas and then getting variable Array to Draw on canvas using Previous `toDataUrl() .
Code ::
function undoDrawOnCanvas() {
console.log('inside undodrawn');
// If we have some restore points
if (restorePoints.length > 0) {
// Create a new Image object
var oImg = new Image();
// When the image object is fully loaded in the memory...
oImg.onload = function() {
//Saving point for Redo
c_redo=document.getElementById("design_text").toDataURL("image/png");
canvas.clear();
// Get the canvas context
var canvasContext = document.getElementById("design_text").getContext("2d");
// and draw the image (restore point) on the canvas. That would overwrite anything
// already drawn on the canvas, which will basically restore it to a previous point.
canvasContext.drawImage(oImg, 0, 0);
}
// The source of the image, is the last restoration point
oImg.src = restorePoints.pop();
}
}
11I'm using sketch.js from here: http://intridea.github.io/sketch.js/ and jquery 2.0.0
On my page, I have a list of images presented like so:
<img src="http://url.to/image"><br><span class="background">click for background</span>
and a canvas, set up like so:
<canvas id="simple_sketch" style="border: 2px solid black;"></canvas>
relevant JavaScript:
var winwidth = 800;
var winheight = 600;
$('#simple_sketch').attr('width', winwidth).attr('height', winheight);
$('#simple_sketch').sketch();
$('.background').on('click', function(event) {
event.preventDefault();
var imgurl = $(this).parent().attr('href');
console.log('imgurl: ' + imgurl);
var n = imgurl.split('/');
var size = n.length;
var file = '../webkort/' + n[size - 1];
var sigCanvas = document.getElementById('simple_sketch');
var context = sigCanvas.getContext('2d');
var imageObj = new Image();
imageObj.src = imgurl;
imageObj.onload = function() {
context.drawImage(this, 0, 0,sigCanvas.width,sigCanvas.height);
};
alert('background changed');
});
Backgrounds are changed just as I want them to, but whenever I click on the canvas, the backgound image is cleared. As per a suggestion on this thread: html5 canvas background image disappear on mousemove I commented out this.el.width = this.canvas.width(); on line 116 of sketch.js, but to no avail.
Any help appreciated!
EDIT: jsfiddle: http://jsfiddle.net/RXFX4/1/
EDIT: Couldn't figure out how to do this with sketch.js, so instead went with jqScribble (link posted in comments) which has the ability to do this as a built-in function instead.
Find this line on the library - sketch.js and delete/comment it out.
this.el.width = this.canvas.width();
Good luck
Assign the url on the image source after the onload event. If the image is already loaded, the event is probably firing before you are hooking it. Which means that your drawImage is never being called.
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(this, 0, 0,sigCanvas.width,sigCanvas.height);
};
imageObj.src = imgurl;
EDIT: I'm going to take a shot in the dark here, since I'm not familiar with sketchjs
I'm thinking that your problem is that you are completely re-render the canvas when you click your 'change background' link. Notice that if you draw, then click the change background, you lose your drawing.
However, notice that once you click again, the background disappears, and you get your original drawing back again. This tells me that sketchjs is keeping track of what has been drawn on it's own in-memory canvas, and then it drops it onto the target. The problem, then, is that when this in-memory canvas is drawn, it completely replaces the contents of the target canvas with it's own.
I notice in some of the sketchjs examples, if you want a background they actually assign the canvas a background style. In your example, you are drawing the background directly onto the canvas. The prior probably works because sketchjs knows to incorporate the background style when it draws. However, it does not know that when you drew your fresh background image, it should be using that.
Can you just change the background style on the canvas element, instead of drawing directly on the canvas?
I'm trying to build a web app using KineticJS, I basically have a function which runs on load which adds an image to a canvas (stage in KineticJS). Each time the function runs though, it is adding the image again underneath the existing one, where as I need it to replace the one that is currently on the stage. I know it's something to do with me creating a new image object each time the function is loaded, but I'm confused as to why it's positioning is different (underneath). I have simulated the same event here: http://jsfiddle.net/UCvbe/ - If you click the button several times, the image duplicates below. The final function will be ran when a user selects a knocker, therefore the final function must accept a parameter eg 'silver' so that it knows to draw the silver knocker etc.
Any help will be greatly appreciated!
Your code looks like this:
$('#testBtn').click(function() {
var stageKnocker = new Kinetic.Stage({
container: "canvas-overlay",
width: 402,
height: 470
});
var layerKnocker = new Kinetic.Layer();
var imageObj = new Image();
imageObj.onload = function(){
var image = new Kinetic.Image({
x: 193,
y: 110,
image: imageObj,
width: 25,
height: 50,
draggable: true
});
layerKnocker.add(image);
stageKnocker.add(layerKnocker);
};
imageObj.src = "http://shop.windowrepairshop.co.uk/WebRoot/Store3/Shops/es115683_shop/49E6/ECF2/0C60/3750/10B1/50ED/8970/710D/V6GP_0020_gold_0020_plate_0020_vic_0020_urn_0020_LArge.jpg";
})
The first problem is that you are creating a new Stage each time a user clicks the button. Don't do that--you only want one stage.
You're also creating a new layer each time a user clicks the button. Don't do that. You only need & want a single layer.
Finally, you are creating a new Kinetic.Image each time a user clicks the button and adding it to the layer. That's fine! Keep doing that. But you also want to remove the old Kinetic.Image. If you don't, you will just keep adding images, not replacing them.
So before adding the Kinetic.Image to the layer, you want to remove any existing images from the layer: layerKnocker.removeChildren() will remove everything in the layer.
When you're done, you will have a single stage, a single layer, and at any point in time a single image.
I've switched over to kineticJS and I'm trying to have a background image repeat itself. Here is the code I am using:
var background_image = new Image();
background_image.onload = function() {
var image = new Kinetic.Image({
image: background_image,
width: this.width,
height: this.height
});
mainLayer.add(image);
stage.add(mainLayer); // now mainLayer is available
};
Now what I'd like to do is essentially what this tutorial does:
http://www.html5canvastutorials.com/tutorials/html5-canvas-patterns-tutorial/ :
That tutorial makes use of the canvas/context objects to repeat the image. I couldn't find an image repeat in the docs, so I was wondering if maybe I could access the main context element of my stage (or layer?) and then use that similar to the tutorial.
Try using a Rect with an image fill. Image fills are repeated by default. Here's an example:
http://www.html5canvastutorials.com/kineticjs/html5-canvas-set-fill-with-kineticjs/
You can also change the pattern repeat type, use offsets, and scale the pattern image
Cheers!