I want to add my image to a canvas, and position and scale it.
I know how to position it, but every time I scale it, it disappears from my canvas.
My current code looks similar to this:
function init() {
var canvas = new createjs.Stage("canvas");
var image = new createjs.Bitmap("assets/image.png");
image.scale(600, 600);
canvas.addChild(image);
canvas.update(image);
}
My image does not appear on the canvas unless I remove image.scale(600, 600).
According to the documentation, the scale property is the scale factor. For example, a scale of 2 means that the image is two times as large. You're making the image 600 times as large. So a 64x64px image would become a 38400x38400px image. You'll need to calculate the factor from the image's dimensions:
const imageBounds = image.getBounds()
image.scaleX = 600 / imageBounds.width;
image.scaleY = 600 / imageBounds.height;
Notice also that scale is a property, you can also directly assign to it:
image.scale = 1.6;
Related
Computer with hdpi screen are more and more common and I own one.
I'm building a webpage with a P5.js canvas inside it filling a div.
I have absolutely no problem till this point, but as I have an hdpi screen the number of pixels to render is tremendous and it's very hard to render smoothly.
what I would like to do: render a low-resolution canvas an stretching it to fill all the space. But I have no ideƩ how to achieve this or even if it's possible.
function setup() {
var canvasDiv = document.getElementById('myCanvas');
var divWidth = canvasDiv.getBoundingClientRect().width;
var divHeight = canvasDiv.getBoundingClientRect().height;
var sketchCanvas = createCanvas(divWidth,divHeight);
sketchCanvas.parent("myCanvas");
background(0)
}
function windowResized() {
var canvasDiv = document.getElementById('myCanvas');
var divWidth = canvasDiv.getBoundingClientRect().width;
var divHeight = canvasDiv.getBoundingClientRect().height;
resizeCanvas(divWidth, divHeight);
background(0)
}
function draw(){
}
Step one: Create an off-screen buffer using the createGraphics() function. More info can be found in the reference. Give it whatever low-res size you want.
Step two: Draw your scene to that off-screen buffer. Use its width and height to draw stuff to scale.
Step three: Draw the off-screen buffer to the screen, using the image() function, which takes parameters for the size to draw. Use the size of the canvas as the arguments. Again, more info can be found in the reference.
You'll still be drawing the same amount of pixels, but that's how you'd draw to a small buffer and resize it to match the canvas size.
If you're still having trouble, please post a MCVE in a new question post, and we'll go from there. Good luck.
I have a canvas into which I draw content. The width of the content is constant, but the height changes. This is kind of a list - a map legend. The problem is I don't know how many items will I get beforehand, neither their size.
If I set height to eg. 800 it's fine for longer lists, but for lists that have just a few of elements, it's way too high and a lot of whitespace remains at the bottom, plus an unnecessary scroll (it's placed in div with overflow: auto, so I can scroll when a longer legend appears).
But I know the last pixel Y-position after I draw every element. Is it possible to somehow trim the remaining space or force adjust canvas size?
Edit: code
<div class="legend">
some stuff here
<div id="canvas">
<canvas id="cv"></canvas>
</div>
</div>
#canvas {
width: 100%;
max-height: 100%;
}
And I set #canvas height using:
document.getElementById('canvas').style.height = finalSize
after knowing the total height.
If you're already holding the canvas in a div for overflow, you could just adjust the div height based on list length. It'd be easier (and cheaper on resources) to obscure the part you don't need, rather than draw the canvas all over again. Depending on your use case, the canvas might even be totally unnecessary (it could be more efficient to just prerender a few key aspects, i.e. use images), but I can't say any more on that without additional details.
It is not possible to resize a canvas not clearing all its content.
As a workaround I can suggest to create 2nd canvas to keep the content of main one while you resize it.
const mainCanvas = ...;
const mainCtx = mainCanvas.getContext('2d');
const hiddenCanvas = document.createElement('canvas');
const hiddenCtx = hiddenCanvas.getContext('2d');
function render() {
// render the list and keep last Y position
// copy content of main canvas to the 2nd one
hiddenCanvas.width = mainCanvas.width;
hiddenCanvas.height = mainCanvas.height;
hiddenCtx.drawImage(mainCanvas, 0, 0);
// resize main canvas and restore its content
mainCanvas.height = lastYPosition;
mainCtx.drawImage(hiddenCanvas, 0, 0);
}
Edit:
As pointed out in comments: you can even render the list directly to the 2nd canvas.
const mainCanvas = ...;
const mainCtx = mainCanvas.getContext('2d');
const hiddenCanvas = document.createElement('canvas');
const hiddenCtx = hiddenCanvas.getContext('2d');
function render() {
// render the list on hidden canvas
// and keep last Y position
// resize and copy
mainCanvas.width = hiddenCanvas.width;
mainCanvas.height = lastYPosition;
mainCtx.drawImage(hiddenCanvas, 0, 0);
}
I'm drawing a image to a canvas, and when doing so the image gets downscaled to the canvas(which makes it lose quality) even though the image is the same size as the canvas, thats because the img does a good job scaling down the actual img that in reality has a bigger naturalheight and naturalwidth. I know there is possible ways to make this quality better, however i have no need of actually showing this canvas to the user/no need of downscaling. Therefore am i wondering if there is any way to drawImage that is bigger than the screen and hold it somewhere? Heard someone mention a box object or a camera object somewhere but couldn't really get use of that information only.
Question, is it possible to draw a canvas bigger than the screen? in that case how?
This is the code im working with atm
var image = document.getElementById('insertedImg');
var height = $("#insertedImg").height();
var width = $("#insertedImg").width();
var c=document.getElementById("canvass");
var ctx=c.getContext("2d");
c.height=height;
c.width=width;
ctx.drawImage(image,0,0,width,height);
Use an offscreen canvas, you just need to create a new canvas and set its height and width accordingly. Then you can append it to an element or export the image as a base64 string or whatever you need.
//canvas is not visible unless appended to a DOM element
var canvas = document.createElement('canvas');
canvas.width = $("#insertedImg").height();
canvas.height = $("#insertedImg").width();
var ctx = canvas.getContext('2d');
//do the drawing, etc.
ctx.drawImage(...);
//export the image
var img = canvas.toDataURL("image/png");
What I'd like to do is create a 15 by 15 pixel sized canvas with jQuery and I am looking for an elegant way to do it.
I currently create a canvas with jQuery like this:
var canvasNode = $('<canvas />', {
style:'display:block',
width:15,
});
// canvasNode[0].width=15;
canvasNode[0].height=15;
An oddity is that the width:15 in that has no effect while the currently commented out line below does what I'd like to do. I also tried style:'display:block;width:15px;' but while that displays the canvas at 15px width the canvas itself stays at its large default size so its just being scaled so that's not what I seek.
In case you are really worried about performance, this is the fastest way (untested, but I'm sure it is):
var canvas = document.createElement("canvas");
canvas.width = 15;
canvas.height = 15;
That is, no jQuery at all.
Note that sending in an object with a width property will set the css width to 15px (basically just scaling the canvas), the canvas will still be created with the default number of pixels in width if no width attribute is specified, which is usually 300 pixels.
Just set the width and height attributes:
$('<canvas />', {
style:'display:block'
}).attr('width', 15).attr('height', 15);
How do I merge a smaller image on top of a larger background image on one canvas. The smaller image will move around. So I will need to keep reference of the original background pixel data, so that the each frame the canvas can be redrawn, with the overlay in its new position.
BgImage: 1280 x 400, overlayImage: 320 x 400, overlayOffsetX: mouseX
I think it is common to draw whole scene each time you want to change something, so:
context.drawImage(bgImage, 0, 0);
context.drawImage(overlayImage, overlayOffsetX, 0);
UPDATE
You could manually compose image data of two images with making copy of background image data
or
do something easier, probably faster. You could create new canvas element (without attaching to the document) which would store image data in easy to manage form. putImageData is good if you want to place rectangular image into the canvas. But if you want to put image with transparency, additional canvas will help. See if example below is satisfying you.
// preparation of canvas containing data of overlayImage
var OVERLAY_IMAGE_WIDTH = 320;
var OVERLAY_IMAGE_Height = 400;
var overlayImageCanvas = document.createElement('canvas');
overlayImageCanvas.width = OVERLAY_IMAGE_WIDTH;
overlayImageCanvas.height = OVERLAY_IMAGE_HEIGHT;
overlayImageCanvas.getContext('2d').putImageData(overlayImage, 0, 0);
// drawing scene, execute this block every time overlayOffsetX has changed
context.putImageData(bgImage, 0, 0);
context.drawImage(overlayImageCanvas, overlayOffsetX, 0);