Drawing an image to a <canvas> - javascript

I was trying to draw an image (png-file) to a to act as a background-image and I do not know why the js i have thus far is not working.
Here's what I have:
var canvas = document.getElementById('hplogo-z');
var cnvs = canvas.getContext('2d');
background = new Image();
background.onload = function(){
cnvs.drawImage(background, x, y);
}
background.src = 'bg.png';
Any ideas on what I am doing wrong?

I was unable to reproduce your problem, so the only things I can guess are that your path is wrong or there is something wrong with your image.
I would recommend you attempt to replace your current path with something from placehold.it, or use a different image in a different location in order to see if your image/path is indeed the problem.

Related

Adjusting Canvas size to image size with Pixi.js

I'm working on a really basic image editor (designed primarily to place text on an image), using PixiJS... though this may be more of a Canvas question, I'm not sure how to classify it as I'm green to Canvas and completely new to Pixi. Unfortunately I can't replicate the behavior in JSFiddle. As of now, I only have this running on localhost, but if anyone has suggestions on how to share this code, I'm open for any feedback.
The idea is that users would be able to select a image to edit (templates for various forms of signage), with the canvas rendering to the size of the image and adding said image as a child on loading the page. For now I'm using a 400 x 650px placeholder for testing purposes. The problem is that on an initial loading or hard refresh of the page, the canvas size defaults to Pixi's 800 x 600px. Soft refreshing the page will size the canvas to the image's dimensions, but I'd like to fix this issue... and I'm sure it's probably an easy fix, but I'm in uncharted waters here. Any help is appreciated. Thanks in advance.
I apologize if some of this code looks wonky, I'm fully aware this is a huge mess right now.
Javascript (this is actually in an AngularJS controller for the time being)
var img = new Image();
var signagetemplate = "placeholderSIGN.png";
img.src = signagetemplate;
var canwidth = img.width;
var canheight = img.height;
var renderer = PIXI.autoDetectRenderer(canwidth, canheight, {
transparent: true,
resolution: 1
});
document.getElementById('display').appendChild(renderer.view);
var stage = new PIXI.Container();
PIXI.loader
.add("signitem", signagetemplate)
.load(setup);
function setup() {
signitem = new PIXI.Sprite(
PIXI.loader.resources["signitem"].texture
);
stage.addChild(signitem);
renderer.render(stage);
}
Edit 9/21/17
I've tried using Pixi's built-in loader as suggested by Hachi in the comments to load the image, but it doesn't seem to load it at all. In the log, it's undefined. I don't understand this loader...
loader.add('signitem', signagetemplate);
loader.load((loader, resources) => {
console.log(resources.name, 'loaded.', 'progress:',resources.progressChunk, '%');
});
loader.load(setup);
I figured it out. All of the examples I found for working with the loader confused me a little bit, mainly just the syntax for entering basic JavaScript. Whether or not this is the cleanest way of going about the problem, I'm not sure, but this seems to work, at least locally. My feelings will not be hurt if someone comes along with a better solution.
var container = new PIXI.Container();
var signagetemplate = //Image to be loaded
var loader = PIXI.loader;
var canwidth;
var canheight;
var renderer = PIXI.autoDetectRenderer({
transparent: true,
resolution: 1
});
loader.add("signtemp", signagetemplate)
loader.on('complete', function(loader, resources, IMAGE) {
var signitem = new PIXI.Sprite(loader.resources.signtemp.texture);
canwidth = signitem.width;
canheight = signitem.height;
container.addChild(signitem);
})
loader.load(setup);
function setup() {
renderer.resize(canwidth, canheight);
renderer.render(container);
}
document.getElementById('display').appendChild(renderer.view);

canvas toDataURL() returns transparent image

I am attempting to use a chrome extension to take a screenshot of the current page, and then draw some shapes on it. After I have done that to the image, I turn the whole thing into a canvas that way it is all together, like the divs I have drawn on it are now baked into the 'image', and they are one in the same. After doing this, I want to turn the canvas back into a png image I can use to push to a service I have, but when I go to use the canvas.toDataURL() in order to do so, the image source that it creates is completely transparent. If I do it as a jpeg, it is completely black.
I read something about the canvas being 'dirtied' because I have drawn an image to it, and that this won't work in Chrome, but that doesn't make sense to me as I have gotten it to work before, but I am unable to use my previous method. Below is the code snippet that isn't working. I am just making a canvas element, and then I am drawing an image before that.
var passes = rectangles.length;
var run = 0;
var context = hiDefCanvas.getContext('2d');
while (run < passes) {
var rect = rectangles[run];
// Set the stroke and fill color
context.strokeStyle = 'rgba(0,255,130,0.7)';
context.fillStyle = 'rgba(0,0,255,0.1)';
context.rect(rect.left, rect.top, rect.width, rect.height);
context.setLineDash([2,1]);
context.lineWidth = 2;
run++;
} // end of the while loop
screencapImage.className = 'hide';
context.fill();
context.stroke();
console.log(hiDefCanvas.toDataURL());
And the image data that it returns is: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAACWAAAAVGCAYAAAAaGIAxAAAgAElEQ…ECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAQBVKBUe32pNYAAAAAElFTkSuQmCC which is a blank, transparent image.
Is there something special I need to do with Chrome? Is there something that I am missing? Thanks, I appreciate the time and help.
Had the same problem, and found the solution here:
https://bugzilla.mozilla.org/show_bug.cgi?id=749824
"I can confirm, that it works if you set preserveDrawingBuffer.
var glContextAttributes = { preserveDrawingBuffer: true };
var gl = canvas.getContext("experimental-webgl", glContextAttributes);"
After getting the context with preserveDrawingBuffer, toDataURL just works as expected, no completely transparent or black image.
Having a similar problem I found a solution, thanks to the following post
https://github.com/iddan/react-native-canvas/issues/29.
These methods return a promise, so you would need to wait for it to resolve before the variable can be populated.
My solution was to set asyn function and await for the result:
const canvas = <HTMLCanvasElement>document.getElementById("myCanvas")[0];
let ctx = canvas.getContext('2d');
let img = new Image();
img.onload = async (e) => { ctx.drawImage(img, 0, 0); ctx.font = "165px Arial";ctx.fillStyle = "white"; b64Code = await (<any>canvas).toDataURL(); }

Bitmap in Easeljs does not work with event listeners?

I'm trying to create a draggable background image in my canvas. Currently I have something like this:
var stage = new createjs.Stage("canvas");
createjs.Ticker.addEventListener("tick", tick);
var dragContainer = new createjs.Container();
stage.addChild(dragContainer);
dragContainer.on("pressmove", function (event) {
event.currentTarget.x = event.stageX;
event.currentTarget.y = event.stageY;
stage.update();
});
// Add a thing
var shape = new createjs.Shape();
shape.graphics.beginFill("#000");
shape.graphics.drawRect(0, 0, 50, 50);
dragContainer.addChild(shape);
// Update the stage
function tick(event) {
stage.update();
}
This works perfectly fine, everything is draggable, etc. The problem is, when I replace the shape drawn with graphics with a bitmap (which is the functionality I want), it doesn't work.
//Add a thing, this doesn't work
var shape = new createjs.Bitmap("http://www.graphic-design-employment.com/images/create-a-simple-shape.jpg")
dragContainer.addChild(shape);
Here's a jsfiddle: http://jsfiddle.net/frozensoviet/5heLu2L1/. Any ideas what I'm doing wrong?
You are likely seeing cross-origin errors. Your console should be showing you the error. This happens because EaselJS must access the stage pixels to determine when the content is intersected by the mouse.
I modified your fiddle to load an image from a server that supports CORS. There is an htaccess file in the folder, which has the line:
Header set Access-Control-Allow-Origin "*"
Then, it is just a matter of flagging the content as crossOrigin. Note that the crossOrigin flag must be set BEFORE you load the source.
var img = new Image();
img.crossOrigin = "Anonymous";
img.src = "http://playpen.createjs.com/CORS/duck.png";
var shape = new createjs.Bitmap(img);
EaselJS doesn't have built-in support for CORS, so you have to specify it on your images before you load and pass them in. PreloadJS does have CORS support.
If you can't support CORS on the server, there is another workaround. Specify a hitArea on the image that is the same size, and it will draw that instead of the image when doing hit-detection. Here is an updated Fiddle: http://jsfiddle.net/lannymcnie/5heLu2L1/2/
var shape = new createjs.Bitmap("http://playpen.createjs.com/CORS/duck.png");
shape.image.onload = function() {
var hitArea = new createjs.Shape();
hitArea.graphics.f("#000").dr(0,0,shape.image.width,shape.image.height);
shape.hitArea = hitArea;
}
Hope that helps!

Template for canvas html5/jquery/javascript

I am a beginner at HTML5, Jquery/JavaScript.
I am attempting to create a canvas (sort of like windows paint application) and I am looking at other users sample functions/code to see whats it going on and attempt to re-create it.
$(function(){
var paint = new Paint($('#surface').get(0));
// Setup line template
var templateLine = new Paint($('#toolbar #line').get(0), {'readonly': true});
templateLine.shape = new Line([10, 10], [50, 50]);
templateLine.place(templateLine.shape);
I am unsure what is going on here. I know this new Paint is not an internal built-in function. What is it?
Secondly whats the difference between this and
$( document).ready(function(){
var canvas = $("#canvas").get(0);
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
// Choose a color
ctx.fillStyle = "black";
ctx.strokeStyle = color;
ctx.fillRect(0, 0, 50, 50);
} else {
// Browser doesn't support CANVAS
}
});
Help!!!
Well, first off, the code you're looking at in the beginning of your question was probably using some canvas library or API, but that is not the vanilla HTML5 Canvas API, making it completely different from what you've written below, even if they have the same output (although it doesn't look like they do).
Secondly, color is not defined, so unless that's defined in your code somewhere else, your code's not going to work. Otherwise, your code will draw a black rectangle in the corner of the canvas with the stroke color of whatever color is.

Graphics BitMapFill TypeError

I'm working with the easeljs javascript to make a sort of game.
I'm using this example: http://www.createjs.com/#!/EaselJS/demos/game
As you can see there are spacerocks. This are graphics objects:
this.graphics.beginStroke("#FFFFFF");
I would like to fill the background with an image like this:
var bitmap = new createjs.Bitmap("http://nielsvroman.be/twitter/root/easeljs/image.png");
this.graphics.beginBitmapFill(bitmap, "no-repeat");
But I always get this error:
Uncaught TypeError: Type error
Does anybody know what I'm doing wrong?
Use a reference to an HTML Image, and not a Bitmap instance.
var image = new Image();
image.srce = "http://nielsvroman.be/twitter/root/easeljs/image.png";
this.graphics.beginBitmapFill(image, "no-repeat");
Note that you have to ensure the image is loaded, otherwise it may not show up on the first stage update. You can either tick the stage, or listen for image onload, and refresh the stage then.
image.onload = function() {
stage.update();
}

Categories