Create an animatable radial mask for layered images? - javascript

Here's what I'm trying to do:
I have two circular SVG images stacked on top of each other. The top image is grayscale. The bottom image is full-color.
What I'd like to do is, via a 1-100 percentage, remove the top image like the hands sweeping the face of a clock based on number. Let's say I'm at 25%. From 12 o'clock to 3 o'clock the grayscale image would be gone like a pie wedge) revealing the identical full-color image below. (see image for more clarity).
example of radial mask concept
Is this possible to do with HTML5/CSS? JQuery? Some way else I'm not considering?

Here is a fiddle of what i came up with http://jsfiddle.net/3a5eubcv/ .Basically your background image would be the red circle and then you have 2 masks floating over it (divs with semitransparent background). Sorry for not adding the javascript for it as well, but for you 25% = transform:rotate(90deg);.When you reach 50%, the right mask should stop and the left one should continue. 75% = .circle-mask-right{transform:rotate(180deg); .circle-mask-left{transform:rotate(90deg);} .I'm sure the code can be simplified, but hopefully this could get you going.

Related

Grid lines behind div without using absolute positioning

I'm trying to build a time selector that:
Sits inside a scrollable div (overflow-y:scroll)
Has an interactive click-and-drag area
Has a grid of 25 single-pixel lines behind the interactive area
Stretches vertically to fit any selected height
(This example image incorrectly shows the grid lines not perfectly aligned with the time markers to the left, so just pretend they do)
Accompanying codepen: http://codepen.io/t3db0t/pen/VKROka (non-interactive)
Previously I had this all working with absolute positioning, but that wreaked havoc with scrolling (as in, you couldn't use the mouse wheel to scroll the div, which is a requirement). So I have everything working without absolute positioning except for the grid lines.
I could do a repeating pattern or image, but then it would not stretch vertically correctly. The number of lines will always be the same. Any ideas?
You can use this using a repeating linear gradient. The trick is to use percentages that divide into the number of lines that you want. if you want a total of 25 sections then your last gradient stop should be 4% (4% x 25 = 100%).
you can position your line anywhere within the gradient by placing color stops on top of eachother.
The line will not be one pixel but a percentage of the whole width. There are some cross browser rendering issues that can cause the width of the line to vary. However under the right circumstances this can be a great solution.
Keep in mind that this divides the contianer into 25 sections ... not 26 sections divided by 25 lines. if you want that your gradient would have to be 3.85% (100 / 26)
My code example places the line at the begining of the repeated gradient, the link below places it in the middle
http://www.virtuosoft.eu/tools/css-gradient-generator/?t=linear&d=angle&r=on&a=0&sp=00000000_0_%25__00000000_1.7_%25__000000_1.7_%25__000000_2.3_%25__00000000_2.3_%25__00000000_4_%25
.gradient {
background-image: -webkit-repeating-linear-gradient(90deg,black 0%,black 0.5%,transparent 0.5%,transparent 4%);
/* IE10+ */
background-image: repeating-linear-gradient(0deg,black 0%,black 0.5%,transparent 0.5%,transparent 4%);
background-image: -ms-repeating-linear-gradient(90deg,black 0%,black 0.5%,transparent 0.5%,transparent 4%);
}
I fixed this problem. The parent was not positioned correctly, and it was causing the child to somehow intercept the scrolling in an undesirable way, so I am now using the absolute-positioned, layered divs to show the grid lines. Harun's answer is intriguing, but I wasn't able to get it to work exactly as required.

Cutting out background from image/canvas using a predefined pattern

I'm not requiring a full answer to this question, just an idea on how to approach it.
Let's say that a user on my site wants to cut out the background from this image:
Normally this would be a job for some magic outline tool, but this site already carries something that would provide a perfect cutout pattern, namely this:
As you can see this car will fit perfectly over the top one.
If the user could somehow fit the bottom picture over the top one and cut out everything outside that, it would be a perfect background removal.
How do I go about building something like this? Or are there already software out that does something similar?
The bottom picture could be anything, for examle a completely black model for easier recognition, but I'd think that it would be smarter if it used the outline of the transparent .png image and cut out everything outside it.
(The picture itself doesn't need to be used either if there is some way to extract the important bits of it needed for the cutout, of course).
Here's how to do your knockout with html5 canvas
If you have an exact image that defines the desired cut and you also know the position where the cut is to be made, then you can use compositing to do you cut-out. With destination-in compositing, new drawings will keep existing pixels only where new & old pixels are non-transparent.
Here's a few notes, example code and a Demo:
Notes:
Your car on your car-only image is not exactly the size of the car on the car+background image -- the car-only is a bit wider. This causes the cut-out to have some extra pixels. But if you had exact sizing the cutout would be perfect.
Your car on your car-only image has semi-transparent shadowing. This causes the cutout to have some extra semi-transparent pixels where the shadow was on the car-only image.
Example & demo using a different exactly sized cutout with no shadow:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var bk=new Image();
bk.onload=start;
bk.src='https://dl.dropboxusercontent.com/u/139992952/multple/model-t-car.png';
var cut=new Image();
cut.crossOrigin='anonymous';
cut.onload=start;
cut.src="https://dl.dropboxusercontent.com/u/139992952/multple/model-t-cutout.png";
var imgcount=2;
function start(){
if(--imgcount>0){return;}
canvas.width=bk.width;
canvas.height=bk.height;
ctx.drawImage(bk,0,0);
ctx.globalCompositeOperation='destination-in';
ctx.drawImage(cut,125,40);
// always clean up -- reset the default compositing mode
ctx.globalCompositeOperation='source-over';
}
body{ background-color: ivory; }
canvas{border:1px solid red; margin:0 auto; }
<h4>Original with background</h4>
<img src='https://dl.dropboxusercontent.com/u/139992952/multple/model-t-car.png'>
<h4>Exactly sized cutout</h4>
<img src='https://dl.dropboxusercontent.com/u/139992952/multple/model-t-cutout.png'>
<br>
<h4>With background removed</h4>
<canvas id="canvas" width=300 height=300></canvas>
There's no easy plug-and-play way. I can think of 2 methods:
(1) SVGs. Plot the different points on the outline of the car yourself (very time-consuming), or import the car into Illustrator (or similar), export it as an SVG, and use the points it calculated for you with clip-path.
(2) PNG (or GIF).
Create a rectangle of solid color in Illustrator/Photoshop.
Paste the car image on top of it as a new layer.
Select the outline of the car.
Delete the selection from the rectangle of color. This will leave a rectangle with a transparent car-shaped hole in it.
Save the rectangle as a PNG or GIF or other format supporting transparent backgrounds.
Use CSS to overlay that PNG on various images of cars.
This is useful if, for instance, you have 5 photos of cars in different colors, all with the same dimensions and taken from the same angle, and want to display the 5 cars with the same background. No need to copy the same background 5 times in Photoshop; just re-use the PNG 5 times in CSS.
Now if you want to change the "background" (which is actually an overlay and not really a background) you need only change it in one place.
Keep in mind: The image you provided is not a perfect outline because it has a shadow.

Isometric engine drawing issue

I'm trying to write a game engine in js (canvas). So far so good.
But i got one problem my world is diamond shaped and i render the tiles from top to bottom.
The problem is when i have a tile that's bigger than 1 tile (so 2x2 as example) this will happen:
The house is defined on tile (2,1).
The left rock is placed on (1,0)
The tile (1,0) is rendered first and the next tile is (2,1) because it's on the same row and on the right.
How can you solve this?
You should be able to avoid the problem by breaking your graphics down into smaller pieces - one piece per tile on the grid. A good way to think of it is like this: If you could view the grid from directly above, each sprite should not overflow the edges of the cell they're allocated to.
For example, this cell below should probably only contain the front section of the house shown by the smaller cube:
At some point you may need to also micromanage multiple sprites in the same cell, but that's the same concept in a smaller space.
For this specific example there's a simpler solution.
Right now the house occupies these spaces: 2x0, 3x0, 2x1, 3x1
And you're drawing the house from position 2x1
If you instead drew the house from position 2x0 (and still occupy the same original 4 tiles) all the tiles would draw in correct order.
As long as you're drawing tiles top (back) to bottom (front) in screen rows, you can use oversized tiles that are 2x2, 3x3, 4x4, or any square size easily without slicing. Just draw these larger tiles along their middle row position. I often use the left corner as the grid anchor for these large tiles. It makes sense in my head this way because as soon as you draw the leftmost (or right) corner of a big isometric square, you separate everything already drawn behind it from what comes in front of it.
Rectangular oversized tiles (e.g. 2x1, 2x3, 2x4, 3x4, 4x5) usually require a more complex draw order algorithm than just screen rows top to bottom. I opt to slice these into square tiles.
Side note, that medieval house tile does already have original parts split into vertical slices if you want to go that route (my originals are on OpenGameArt).
I think the best solution here is clearly to divide your graphics using a pre-defined metric (width of a tile for instance).
The tile-based system is widely used for 2D-game, including isometric games.
Example: http://www.spriters-resource.com/pc_computer/fallouttactics/
My solutions (Also thanks to Marty Wallace!)
I can cut the sprite in 3 pieces shown on the image below
The first part gets drawed on coord (2, 0)
The second part gets drawed on coord (2, 1)
The third part gets drawed on coord (3, 1)
So we slice it vertically on the bottom tiles (the drawed tiles are like a V shape)
This should work for every tile size like 4x4
We can forgot about the tile (3, 0)
Blue: The actual png
Red: the cut lines
The lines are a bit off, but it's about the idea
And i need some sleep (that last 2 is 3 ofcourse)
This also gives us a simple calculation:
sizeX - 1 = The number of sides on the right of the middle section (the big one)
sizeY - 1 = The number of sides on the left side of the middle section
And every slice is half the tile width, and the middle slice is the full tile width.
The right slices contain only the most right part of the tile, and the left the most left side.
We can easily use tiles like 3x1 or 1x4 etc

How do the createRadialGradient() and addColorStop() methods work?

Can anybody explain me, preferably with illustrative pictures, how do these methods work? I've looked at different examples and tutorials but can't seem to grasp the idea. I understand, that the createRadialGradient() creates two circles, but how do those two circles relate to each other and the addColorStop() method ?
Yes, I know this is necro'd... but it seems a valid question that was never snawered, so I leave this here in case someone else needs it.
================================================================================
Well, a gradient is a smooth shift from one color to another.
In any gradient, you pick a point where the colors begin, a point where the color ends, and the colors you want, and the color smoothly transitions between them.
The color stops are there to determine what colors will be a part of the gradient, and where in the gradient those colors will appear.
In a linear gradient, the color transitions from one color to the next in a straight line so that bands of color form along the line, perpendicular to the axis.
In a radial gradient, the color wraps itself around a central circle (or point, which is simply a very small circle) and transitions from that center to the edge of the gradient.
This means that the color bands that make up the gradient form into larger and larger circles as they transition from center to edge.
HEREis an example of a simple radial gradient transitioning from white in the center to black at the outside edge.
This is the origin of the syntax for createRadialGradient.
This first circle will be where the color begins, we will arbitrarily state that it starts in the center... lets say that is x:100,y:100
The second circle will be where the color ends, since we picked the center to start it, the color finishes at the outside edge of the circle (although these could just as easily be reversed).
For simplicity's sake, the center point (in this case) will remain the same: x:100,y:100
The real difference between these circles will be the radius. Since the center should be small, we will give it a radius of 1, while the larger outside radius of the circle, we will make 100.
This gives us the required parameters:
x = 100;
y = 100;
radiusStart = 1;
radiusEnd = 100;
var grad = ctx.createRadialGradient(x,y,radiusStart,x,y,radiusEnd);
However, if we try to display this code as is, we won't see anything... this is because we need the color stops.
Color stops are declared with two parameters... the position and the color of the stop.
The position is a number between 0 and 1, and represents the percentage of the distance from start to end.
If we want the color to start at white, then we would use:
grad.addColorStop(0,'#FFFFFF');
This means that we the color stop starts at 0% of the way down the line (meaning right where the gradient begins), and gives the color to paint there as white.
Similarly, the second gradient should be black, and should be placed at the very end of the gradient:
grad.addColorStop(1,'#000000');
Notice that these do not reference context directly... we referenced context to create the gradient, but we are adding stops directly to the gradient that we created.
When we are finished creating the gradient, then we can use this gradient as a fillStyle (or even a strokeStyle) for as long as the gradient that we created remains in scope.
Full code:
x = 100;
y = 100;
radiusStart = 1;
radiusEnd = 100;
var grad = ctx.createRadialGradient(x,y,radiusStart,x,y,radiusEnd);
grad.addColorStop(0,'#FFFFFF');
grad.addColorStop(1,'#000000');
ctx.beginPath();
ctx.arc(x,y,radiusEnd,0,Math.PI*2,false);
ctx.fillStyle = grad;
ctx.fill();
While you are playing with this, don't forget to experiment a bit.
Try adding more than two color stops... this means that instead of transitioning from black to white (boring), you can transition from blue to green to yellow to orange to red to purple.
Just remember to set the positions appropriately... if you have 6 colors, for example (as above), and you want them evenly spaced, then you would set the positions at .2 intervals:
grad.addColorStop(0,'#0000FF');
grad.addColorStop(.2,'#00FF00');
grad.addColorStop(.4,'#FFFF00');
grad.addColorStop(.6,'#FF8800');
grad.addColorStop(.8,'#FF0000');
grad.addColorStop(1,'#AA00AA');
Any color stops you try to place in the same position will overwrite one another.
Another cool effect is to set two different centers for the circles when creating the gradient... this lends a different effect to the gradient, and can be a worthy addition to your arsenal.
HERE are two images from the W3C specification (which itself is HERE). Both of these are radial gradient with different center points for the first and second circles.
A better example is HERE, although the code itself is written in svg for html backgrounds, the examples still show some great ways to use radial gradients with differing centers. He covers the theory of radial gradients as well as shows some very nice examples.
Finally, a tip... while it is quite possible to write gradients by hand, its kind of a pain in the butt. It is usually far easier to grab Photoshop, Illustrator, GIMP, or Inkscape, and build the gradient in one of those... then you can adjust the gradient directly until you like it. Then simply copy the color stop information over to your canvas code.
Hope some of that helps someone.

HTML5 canvas color

I have two blocks in HTML5 canvas.
Blue Block ie fixed in the canvas
Yellow Block that can be dragged with mouse.
When someone moves the yellow block over blue block, I want to change the color of overlapping or intersection regions to green. (please see attached image to have clear idea)
Since blue + yellow = green, is there any way to achieve this by changing the opacity level of blocks or I have to search for the overlapping area of the two blocks and display green block in that area or is there any other way?
I would like to know what is the best approach to achieve this?
Have a look at canvas globalCompositeOperation. The lighter composite type seems to fit what you're after.
You could use 3 elements:
Yellow bottom: Opacity 1
Yellow top: Opacity 0.x, same dimensions as the bottom one
Blue: Full opacity between the yellow divs
Example on jsFiddle
This is far from done, but maybe a step in the right direction.
EDIT: I noticed too late that you requested it on canvas, but the principe should be the same there.

Categories

Resources