I have a project I'm currently working on that I cannot seem to Google a solution for. I have an HTML canvas that I'm using ctx.drawImage() to stack a couple images, the issue I'm having is I cannot figure out a way to draw an image specifically this, using a pattern like this. Is there anyway this can be done easy, or would I need to attempt to generate the image server-side then push it to the client to draw?
The order of images I'm attempting to draw is as follows:
Background ColorA rounded maskThe first linked image (this is the one that I want to draw with a pattern)
I'm trying to keep the first two layers visible, and just covering the non-transparent part of the third with the pattern file. All layers have the parts that need to be transparent set as transparent.
Updated to meet additional conditions added to question since this answer was first posted:
You don't state if the rounded mask has filled or transparent center but the following assumes filled center:
Draw letter image
Change comp. mode to "source-atop" (see old answer below on how-to)
Draw pattern. You now have the pattern in the shape of the letter.
Change comp. mode to "destination-over"
Draw mask, this will end up "behind" existing content
Fill canvas with background color using same comp. mode.
Old answer
Sure, draw the first image, provided it has an alpha channel, to the canvas.
Then change composite mode to source-atop (source-in can also be used but it will remove existing content which doesn't end up under the new pixels):
ctx.globalCompositeOperation = "source-atop";
Then draw the second image on top. To change back to the normal mode:
ctx.globalCompositeOperation = "source-over";
Related
Is this possible in canvas to do something like this on screen?
Basically I want to:
Upload any image to canvas [DONE]
Put any type of mask on it (here on screen this circle) [DONE]
Move,rotate and scale image [DONE]
Be able to see rest of the image around the mask(it should be darkened) like on this screen
I try various ways to render it with
ctx.globalCompositeOperation
but I only get image inside the mask and rest of the image is covered by background of canvas (although i can move or rotate image)
Edit:
When I rotate it it should look like on the second picture
And then i want to clip this rectangle and save to file (which also is DONE)
The question has already cut out the image required so one way of getting what is needed is to draw the whole image on a canvas, draw a mask over it and then place the already obtained image over that.
However, it is possible to do it the other way round.
Draw the image on a canvas, scaling, skewing, stretching, rotating it as required.
Then draw the semi transparent overlay on it e.g.
ctx.beginPath();
ctx.rect(0,0,width,height);
ctx.fillStyle = “rgba(0,0,0,0.4);
ctx.fill();
cutting out the required mask. Without knowing exactly what shape is required it’s not possible to give the exact code for this but see for example https://stackoverflow.com/questions/36711841/apply-bitmap-mask-to-image-on-html5-canvas which describes how to remove part of a mask.
I'm working on a pototype HMTL5 canvas animation that will export to quicktime.
I'm having a dynamically generated background with dynamically masked elements on top of it.
I can get the background to be made, and have it export to the server as a frame by frame animation (png sequence) and then compile the animation using FFMPEG into a quicktime. The concept is working.
However, whenever I try to put the dynamically masked elements on top of the background, the background gets affected by the mask too.
Currently the draw opperation I have goes
Draw Background element 1
Draw Background element 2
Draw Foreground Element Mask
Switch to Source-in Mode
Draw Foreground element fill
Revert to Source-Over Mode
I'm obviously using the source mode wrong, but I'm not sure it is possible to do what I want (have a mask affect the element right under it, but not ones below that).
The easiest solution I can think of would be to just layer 2 canvas objects on top of eachother...however I'm not sure how I could combine the 2 canvases into a single image for the quicktime export.
Thanks for the help
The context.drawImage method will accept another canvas as the image source.
So if you want to "flatten" all your canvases into a single canvas:
yourMainContext.drawImage(yourOverlayCanvasElement,0,0);
If I change the cursor of a page into a 'flashlight' (say, a circle), and I want to reveal an image only when passing the light (the circle) over it, what would be the best way to go about this? Using css clip? But then it can only do rectangles, so I'd have to use canvas? Perhaps there's an easy way to intersect the two images?
You can do this with a canvas easily.
Here's an example:
http://jsfiddle.net/gfZ5C/
On every mouse move, we clear the canvas, redraw the image, make a clipping region that is a circle cut out of a rectangle, and draw black on the entire canvas (which will draw only on the clipping region)
Make sense?
There are a lot of ways to achieve this effect and similar effects. You can also make much fancier light sources with a bit of canvas sorcery. See for instance my answer here: Canvas - Fill a rectangle in all areas that are fully transparent
I'm trying to draw a tiled background using Javascript on an HTML5 canvas, but it's not working because shapes that intersect the edges of the canvas don't wrap around to the other side. (Just to be clear: these are static shapes--no motion in time is involved.) How can I get objects interrupted by one side of the canvas to wrap around to the other side?
Basically I'm looking for the "wraparound" effect that many video games use--most famously Asteroids; I just want that effect for a static purpose here. This page seems to be an example that shows it is possible. Note how an asteroid, say, on the right edge of the screen (whether moving or not) continues over to the left edge. Or for that matter, an object in the corner is split between all four corners. Again, no motion is necessarily involved.
Anyone have any clues how I might be able to draw, say, a square or a line that wraps around the edges? Is there perhaps some sort of option for canvas or Javascript? My google searches using obvious keywords have come up empty.
Edit
To give a little more context, I'm basing my work off the example here: Canvas as Background Image. (Also linked from here: Use <canvas> as a CSS background.) Repeating the image is no problem. The problem is getting the truncated parts of shapes to wrap around to the other side.
I'm not sure how you have the tiles set-up, however, if they are all part of a single 'wrapper' slide which has it's own x,x at say 0,0, then you could actually just draw it twice, or generate a new slide as needed. Hopefully this code will better illustrate the concept.
// Here, the 'tilegroup' is the same size of the canvas
function renderbg() {
tiles.draw(tiles.posx, tiles.posy);
if(tiles.posx < 0)
tiles.draw(canvas.width + tiles.posx, tiles.posy);
if(tiles.posx > 0)
tiles.draw(-canvas.width + tiles.posx, tiles.posy);
}
So basically, the idea here is to draw the groupings of tiles twice. Once in it's actual position, and again to fill in the gap. You still need to calculate when the entire group leaves the canvas completely, and then reset it, but hopefully this leads you in the correct direction!
You could always create your tillable image in canvas, generate a toDataUrl(), and then assign that data url as a background to something and let CSS do the tiling.. just a thought.
Edit: If you're having trouble drawing a tillable image, you could create a 3*widthx3*width canvas, draw on it as regular (assuming you grab data from the center square of data as the final result), and then see if you can't draw from subsets of the canvas to itself. Looks like you'd have to use:
var myImageData = context.getImageData(left, top, width, height);
context.putImageData(myImageData, dx, dy);
(with appropriate measurements)
https://developer.mozilla.org/En/HTML/Canvas/Pixel_manipulation_with_canvas/
Edit II: The idea was that you'd have a canvas big enough that has a center area of interest, and buffer areas around it big enough to account for any of the shapes you may draw, like so:
XXX
XCX
XXX
You could draw the shapes once to this big canvas and then just blindly draw each of the areas X around that center area to the center area (and then clear those areas out for the next drawing). So, if K is the number of shapes instead of 4*K draws, you have K + 8 draws (and then 8 clears). Obviously the practical applicability of this depends on the number of shapes and overlapping concerns, although I bet it could be tweaked. Depending upon the complexity of your shapes it may make sense to draw a shape 4 times as you originally thought, or to draw to some buffer or buffer area and then draw it's pixel data 4 times or something. I'll admit, this is some idea that just popped into my head so I might be missing something.
Edit III: And really, you could be smart about it. If you know how a set of objects are going to overlap, you should only have to draw from the buffer once. Say you got a bunch of shapes in a row that only draw to the north overlapping region. All you should need to do is draw those shapes, and then draw the north overlapping region to the south side. The hairy regions would be the corners, but I don't think they really get hairy unless the shapes are large.... sigh.. at this point I probably need to quiet down and see if there's any existing implementations of what I speak out there because I'm not sure my writing off-the-cuff is helping anybody.
I'm working on a Raphael JS project and need to display some transparent PNGs with only the parts that are non-transparent to be clickable. Is there a way to:
Upon mouse click, pull out the alpha of the current position.
or
Generate a path which can be be used to define the clickable region (i.e. http://raphaeljs.com/australia.html)
As raphael is for vector graphics, it is the wrong tool for your problem with png. I think canvas is what you looking for. Load your image in an canvas (the canvas doesent need to be pushed in the DOM). On click check the coords and get the pixel out of the canvas.
But maybe it will be easier to convert you png to vector graphics and use raphael instead.