Loading a clipped image into a new variable - javascript

I'm currently working on a top-down MMORPG, in JavaScript. As you can imagine, this requires a lot of sprite sheets, and herein lies the problem.
I can simply place the clipped version of a sprite sheet onto the canvas using the canvas.drawImage method. However, this must require more performance than simply loading the clipped version of the image into a new image object which I'd then place onto the canvas using the canvas.drawImage method, as I'd only have to clip it once.
Is this at all possible, and if so, how?

It's a sprite. Any "clipping" is a convenient illusion. Loading a clipped version adds more HTTP traffic which will certainly take more time than drawing canvas image, regardless of the image source, especially when you have the image on the client already.

Related

Layering The Canvas Without Multiple Canvases

There I am creating a stamp maker in HTML,Jquery and javascript. In the editor of my application image is adding to HTML canvas (simple) and also the text, I just create new line element and then append it to the canvas.But the problem is that I want my image to be in back of text. I googled it alot and also search stackoverflow I got the solution of creating multiple canvases but in last I have to download the canvas to file for user. There is the problem. And I want to export whole canvas along with text one and second image together.If I create seperate canvas for the text and another for image and give image one low zindex it would be fine but there will be one canvas to be exported as image.
Link to multiple layers in canvas html5 - canvas element - Multiple layers
I am hopping that we would come up with an idea of how to download both canvases as an image or find a method to take image to back of the canvas.
Any answer would be appreciated.
If you store the text, second image and first image in variables, you could just draw them on the canvas in the order you prefer. This means that, whenever there's some change in the image or text, you should clean the canvas and redraw everything.
Also, you may be interested in Compositing, since it allows you to decide where a new object is drawn in relation to the existing drawing (on top, behind, etc.)

Store and load fabricjs canvas on server

I am creating an app which uses fabricjs canvas drawing comics. Canvas contains some objects such as rectangles, svg object, and jpeg images. After editing is done, the canvas need to be stored in the server (nodejs) and should be reloaded later from server by the creator or other viewers.
I thought I can serialize canvas to svg string and store svg string on the server and upload images which exist in the canvas one by one to the server as well. Later on, load the svg string replace the images url with the downloaded picture and reload the canvas.
Here are my questions:
1- Is this the right way to achieve my goal?
2- I am doing all of this because my canvas will have different size depending on user device (monitor, smartphone,...) therefore, I chose to use svg for scalability. However, I'm not sure how to scale the original svg string to the new canvas.
Thanks,
Don't save to SVG. SVG is for export. Call myCanvas.toObject()
Not sure how you're going to take advantage of SVG's scalability, if you are just using SVG as a persistence format for canvas. But if you're going to render in SVG, then that makes sense.
You may be overthinking the image solution. How are users going to put an image on the canvas in the first place? The way I do it is to have them upload the image to my server. Then I let them choose images from an image browser. The image they choose already has a URL, so there's nothing left to do when storing/restoring.

How to increase the canvas bit depth to create a higher quality picture in javaScript? and how to increate the canvas size when outputting

I'm new to HTML5 and JavaScript, and I'm trying to use the canvas element to create a high(ish) quality output image.
The current purpose is to allow users to all their own images (jpeg, png, svg). this works like a charm. however when I render the image it's always a 32-bit png. how can I create a higher quality picture using JavaScript(preferably) ?
when I output the file, it always seems to keep the same resolution as the canvas, how can I change this using JavaScript(preferably)
Thanks in Advance guys, I looked around for a while but I couldn't find the answer to this :(
If you want to create a larger image with getImageData or toDataURL then you have to:
Create an in-memory canvas that is larger than your normal canvas
Redraw your entire scene onto your in-memory canvas. You will probably want to call ctx.scale(theScale, theScale) on your in-memory context in order to scale your images, but this heavily depends on how they were created in the first place (images? Canvas paths?)
Call getImageData or toDataURL on the in-memory canvas and not your
normal canvas
By in-memory canvas I mean:
var inMem = document.createElement('canvas');
// The larger size
inMem.width = blah;
inMem.height = blah;
Well firstly, when you draw the image to the canvas it's not a png quite yet, it's a simple raw bitmap where the canvas API works on as you call it's methods, then it's converted to a png in order for the browser to display it, and that's what you get when you use toDataURL. When using toDataURL you're able to choose which image format you want the output to be, I think jpeg and bmp are supported along with png. (Don't think of it as a png converted to another format, cause it's not)
And I don't know what exactly do you mean by higher quality by adding more bits to a pixel, you see 32 bits are enough for all RGBA channels to have a true color 8 bits depth giving you way more colors than the human eye can see at once. I know depending on the lighting and angle in which the user is exposed to your picture his perception of the colors may vary but not the quality of it which I'd say only depends on the resolution it has. Anyway the canvas was not designed to work with those deeper colors and honestly that much color information isn't even necessary on any kind of scene you could render on the canvas, that's only relevant for high definition movies and games made by big studios, also, even if you could use deep colors on the canvas it would really depend on the support of the user's videocard and screen which I think the majority of people doesn't have.
If you wish to add information not directly concerned to the color of each pixel but maybe on potencial transformations they could have you better create your own type capable of carrying the imageData acceptable by the canvas API, keeping it's 32-bit format, and the additional information on a corresponding array.
And yes, the output image has the same resolution as the canvas do but there are a couple of ways provided for you to resize your final composition. Just do as Simon Sarris said, create an offscreen canvas which resolution is the final resolution you want your image to be, then, you can either:
Resize the raster image by calling drawImage while providing the toDataURL generated image making use of the resizing parameters
Redraw your scene there, as Simon said, which will reduce quality loss if your composition contains shapes created through the canvas API and not only image files put together
In case you know the final resolution you want it to be beforehand then just set the width and height of the canvas to it, but the CSS width and height can be set differently in order for your canvas to fit in your webpage as you wish.

Combine Vector advantages with Bitmap in an HTML canvas element - how?

What I am trying to do is create a game that has an extreme amount of zoom-ability on a canvas element. I would like to make use of the advantage that vector graphics have insofar as being able to be programmatically created at runtime, with the high performance of bitmap images.
What I would like to do is programmatically create the first-frame image of a game "sprite"... this would be a vector image. After the first frame though, I do not want to keep wasting CPU cycles on drawing the image though.. i would like to cache it as a bitmap/high performance image for that zoom level.
Following this, if the user zooms in by >20%, I then redraw the image with a higher level of detail vector image. As above, this vector image would then be cached and optimized.
As you can see here, this would be a pretty basic space ship.. I would first render it programmatically as a vector and then.. raster it I guess? Goal is to avoid wasting CPU.
If the user zooms in...
A new vector image of the same shape would be drawn, albeit with a much higher level of detail. This is basically a Level Of Detail system. In this case as well, after the initial programmatic draw, I would "raster" the image for maximum performance.
Does anyone have ideas on what tools I would need to make this a reality inside of a HTML canvas? (The rest of the game will be running inside of the canvas element..)
Thank you very much for your thoughts.
**Edit: I wanted to add... perhaps the route of rendering an image via SVG (programmatically), then pushing that png file into the canvas using drawimage(), might provide some success? Something similar? Hmm...
Check out that article , but it seems there is no standard method to do what you want and it may fail in IE.
http://svgopen.org/2010/papers/62-From_SVG_to_Canvas_and_Back/#svg_to_canvas
You should perhaps go with an all SVG game , or provide a maximum zooming rate to your game and use big images as sprite assets. it would not have been a problem using flash,but i guess you wont go with flash anyway.
Maybe there is a framework that can translate SVG into a "canvas drawing sequence" but i would not bet on high performances in that case.
I managed to answer my own question.
The way to do this is to first create an SVG file, and then convert it to a PNG file on the client using "canvg". The PNG can be created at different levels of details based on what you want, and in this way you could create a dynamic LOD system.
Flash does something similar automatically by cashing a bitmap image of the SVG file... it's called "pre-rendering". If the SVG isn't scaled or the alpha isn't changed, flash will just use the bitmap instead (much faster then continuously re-rendering the SVG file, in complex cases). Size (and thus detail) of the PNG output can be modified however you like, and so pre-rendering could be done based on events as well.
From this information, I have decided to implement the LOD system such that SVG is used whilst the user is actively zooming (scaling the target "sprite"), and then as the zoom slows down, compute a PNG pre-render. Also, at extremely high levels of zoom, I simply use the SVG, as it is much easier for the CPU to compute SVG's at high resolution, then bitmap images that cover most of the screen. (just take a look at some of the HTML5 icon tests that put lots of icons on the screen... the bigger the icons are, the slower it runs).
Thanks very much to everyone's comments here and I hope that my question/answer has helped someone.

HTML5 canvas: Toggle between color/grayscale image

I've got an HTML5 canvas element in which a user can dynamically move, resize, and rotate a color photo.
I'd like the user to be able to toggle between grayscale and color.
I can think of two approaches, but neither is ideal:
1) Re-render the color image as grayscale (using a pixel-by-pixel loop) on every resize and rotate event (which could be several times a second)
2) Create a grayscale version server-side, and apply any canvas transformations to both images, but show only one of them at a time, depending on the toggle selection.
Can anyone think of a better solution than these two -- or, if no better solution exists, take a guess about which of the two would be the better choice?
Update: I implemented the method suggested below by Phrogz.
Create a second canvas (you don't even have to append it to the document) and use drawImage() to copy the color image onto it, and then (once) use getImageData()/putImageData() to make it greyscale.
Use this canvas as the source for future calls to drawImage() when you need the greyscale version, otherwise use the original image.
You are transforming the context, e.g. context.translate() / context.rotate() / context.scale(), to draw the image easily, right? There is no reason to keep rotating or resizing the source image as the user is transforming it.
You can also draw both images to two canvases (or a big one). That canvas probably doesn't even have to be added to the page, it can just be the element.
Then you draw the proper image from that canvas to the main canvas using the build-in methods. This will both be fast and not require server-side code.
You could even do the conversion to grayscale in a webworker, but that depends on if your clients do support it.

Categories

Resources