Paint all pixels (excluding transparant) in PNG with Javascript/CSS? - javascript

I need to create a silhouette of a PNG with Javascript/CSS. Is this possible?
I tried the following:
Stack the PNG with lowered opacity multiple times with absolute positioning and z-index.
This does not work.
Unfortunately I can't use PHP or something else then Javascript and CSS.
I got some ideas with overlays and such but I can't figure out how to do it. Any tips?
update: This only needs to work in webkit browsers, so you can bring your webkit trickbox! :)

It's not possible in plain HTML/CSS.
It would be possible in embedded SVG using a filter such as feColorMatrix to set all channels to one colour except the opacity.
It would be possible in a <canvas> using a composite operation, such as first drawing the image, then drawing a single colour over the top with source-out mode.
It might be possible in IE using a MaskFilter, using the MaskFilter to generate a masking colour (eg. white) laid over a fixed colour (eg. black). However I think you'll lose any variable-opacity smooth edges.
It's going to be a lot of browser-sniffing and annoyance. I'd try to avoid it.

Considering you've tagged this with webkit, you should have a look at the Surfin' Safari blog post about CSS masks.
E.g. Is this what you want?
<!doctype html>
<style>
div {
width: 215px;
height: 174px;
background: black;
-webkit-mask-image: url("http://webkit.org/images/icon-gold.png");
}
</style>
<div></div>

Related

Any other way to clip container except for CSS clip-path?

I've been trying to find a solution for the 3d day and I am going crazy now. I need to clip a container to a specific shape. The container has a background image with background-attachment: fixed; so it's not static (from the viewers point of view). The layer behind the shaped container is not static also, so I cannot just use some png mask to overlay my container. CSS clip-path works perfectly for all major browsers except for IE! Support for IE 10 and 11 is a must according to my client, so I am trying to find a solution for this. Is there anything I can use to replace clip-path with? Thanks in advance!
I've found this article (https://css-tricks.com/background-image-shapes/) that perfectly describes my issue, except that the image I am working with has background-attachment: fixed;

Really cool javascript or CSS feature in website

Does anybody know how the eyeball in this website is designed? Is this javascript (jQuery perhaps), or simply HTML5 and CSS? I just don't really understand how you get a little image in that shape, get it's onhover method, set a new picture, and then make it clickable. Is this a button?
http://animalvfx.com/work/
They use one image as the background (found here: http://animalvfx.com/images/bg-open-close.png).
They are only using CSS, they have a hover state on the class that sets the background position to a negative offset.
Basically the styles are:
.slide-holder .opener {
width: 30px;
height: 38px;
overflow: hidden;
position: absolute;
bottom: -38px;
background: url(../images/bg-open-close.png) no-repeat;
}
.opener:hover {
background-position: 0 -76px;
}
Effectively you are only seeing one part of the background image at a time. Because the image states are similar, it appears to be looking up.
The click event of the eye is using jQuery slidedown
If you want to find out how things work yourself, you can use the developer console in most popular web browsers. Then use the HTML inspector tool to inspect the element you are interested in.
Developers consoles are usually activated by pressing F12. This works in any decent modern web browser (and Firefox with Firebug)
It is a sprite - http://animalvfx.com/images/bg-open-close.png - on hover the background image is shifted from the centered eyeball to the offset one.
.opener:hover {
background-position: 0 -76px;
}
I believe he compressed his javascript so its not legible to the human eye but I believe he uses a combination of jquery/javascript, and css3. The hover where the eye changes its appearance I believe is just some simple javascript to change the image when hovered over. I know for sure a toggle class is being used when you click the eye because you can see the class change on the list in the HTML source (it originally is set to display: none). This definitely seems like the work of slideDown from jQuery. Hope this helps :]

2 part CSS "wallpaper" that resizes to browser

My designer believes this cannot be done, however it seems possible to me. (Although I have limited CSS experience). However, he also said the background couldn't be fixed, and stackoverflow has proved his wrong in the past; so I question his knowledge.
JQuery can be used if this cannot be done in pure CSS.
The top half will be a gradient that has full flexible to skew left, right, up, down without much distortion. The bottom half is an image that is ideally made for the 1280 x 1024 resolution (as this is the most popular browser display resolution). Then depending on the requirements needed it will sketch and skew to whatever size it needs. Still allowing all of the image to be seen.
The ration between the top half and bottom half is always 50% 50% independent of browser resolution.
I would also like if both the top and bottom parts are fixed.
In a perfect world (one without IE), id like to do this with css3 gradients and multiple backgrounds in 1 DIV. However, because IE9 isnt out yet, I think the best way to approach it would be 2 divs in a DIV container and using a PNG repeating background for the top div.
It should be noted I am going to use css3pie.com to allow some CSS3 for IE6-8 (but I dont want to rely on it, unless 100% proven)
Is this possible with just CSS? How would you do it?
If not possible with just CSS, is there a way I can get JavaScript/JQuery to aid?
I am thinking a base of 1280 x 1024 isn't the best idea because it seems to have an odd radio.
Edit 1
Oh yeah, I have a WIP too:
http://meyers.ipalaces.org/extra/
It looks good in 1280 x 1024...now its just getting the whole resizing of the top DIV to be 50% so the image is 50%.
I'd still like ALL of the water to be seen, because I like the look of the rocks at the bottom. However, I am open to alternative ideas that don't accomplish what I want 100%, but come close.
Edit 2
How about using the top gradient as the true CSS2 background and then just putting a <img> at the bottom of it to resize? Perhaps that will allow for CSS2 ability. I am reference some work-around techniques here: A list apart
Edit 3
I am still looking for results that work on IE6 and also don't cause Internet explorer to lag. I am setting a bounty of 50 to help attract more attention.
I have successfully came up with 2 ways to do this:
Method 1
Click here to view demo
Using CSS3 background-size I was able to set 2 div elements to on top of each other with min-height: 50% and then using background-size: 100% 50% they successfully accomplish what I am looking for.
This method was just a proof of concept, as IE6-8 does not support background-size, I didn't pursue tweaking this method perfectly. As it stands, it currently messes up when you scroll despite have background-attachment: fixed;. I ditched this CSS3 method in order to look for better methods using CSS tricks...
Method 2
Click here to view demo
Following the examples I found from A List Apart (Article | Example1 | Example2). I used Technique #2 from Example 1, and I was able to emulate what I wanted to do using just CSS2. (I am not 100% sure how or why this works, but it does)
Because I am also going to use CSS3PIE to give IE6-8 CSS3 the ability to do linear gradients, border-radius, and box-shadow; I opted to use a linear gradient instead of an image for the top background.
Problems
CSS2 Method from Technique #2, Example 1 does not work with IE6 Correctly
Creates excessive lag in all current Internet Explorers
It can be done with CSS only. No PIEs necessary. Just an IE6 bug and some filter magic.
Demo:
http://www.bundyo.org/test/FPB.html
Do this using raphaeljs. Create a background DIV that becomes a canvas, draw a rect to 50% of the page height (if using jquery then use $(window).resize() to monitor for a window resize and $(window).height() to get the 50% into pixels).
You can fill in the raphealjs rect with specifing it's fill value to something like fill: "90-#000000-#ffffff"
As for the image:
Place the image using raphealjs' image OR just embed it using HTML and update it's height-scale using jquery as mentioned above.
I've done something like this just recently using about 10 lines of code.
Also: Change your water.png, it's about 275kb, where as the next largest file on your page (the css) is like 1.5kb.
If you want to keep the horizon of the water at 50% on your screen, I would suggest a simpler method;
Create an image (probably about 1280 wide) in Photoshop of water on bottom and gradient on top. Fade the top gradient into a solid light blue(#68b for example). Fade the left, right and bottom of the image into the same solid color(#68b).
Set the background of your page as follows;
html {
background: #68b url(waterimage.png) center center no-repeat;
}
In your case, you'll probably want to apply the background to #wdth-100 instead of html, but it all depends on which element you want to put your background on.
All done. Let me know if that works for you.
I don't have a link to your top image, so i used the same image for top and bottom.
You should probably use a CSS solution for normal browsers and the JS for IE.
<script type='text/javascript'>
$(document).ready(function() {
wh=$(window).height();
ww=$(window).width();
if(wh%2) {
h1=Math.round(wh/2);
h2=Math.round(wh/2)-1;
} else {
h1=h2=wh/2;
}
img1=$("<IMG/>",{'src':'http://meyers.ipalaces.org/images/bottom-bg.jpg','id':'img1'} )
.css({'width':ww,'height':h1,'top':'0','left':'0','position':'absolute','z-index':'-100'});
img2=$("<IMG/>",{'src':'http://meyers.ipalaces.org/images/bottom-bg.jpg','id':'img2'} )
.css({'width':ww,'height':h2,'top':h1,'left':'0','position':'absolute','z-index':'-100'});
$(document.body).append(img1);
$(document.body).append(img2);
});
$(window).resize(function() {
wh=$(window).height();
ww=$(window).width();
if(wh%2) {
h1=Math.round(wh/2);
h2=Math.round(wh/2)-1;
} else {
h1=h2=wh/2;
}
$('#img1').css({'width':ww,'height':h1,'top':'0','left':'0'});
$('#img2').css({'width':ww,'height':h2,'top':h1,'left':'0'});
});
</script>
The pragmatic answer would seem to be to do it using multiple divs with their own background, all of which would be positioned absolutely and behind everything else using z-index.
I know that's not the clean markup solution with a single div with some magic CSS, but this is a tricky problem in pure CSS in any browser, and almost certainly impossible if you need to support IE6.
An even more pragmatic answer would be to say "I'll support IE6 as far as I can, but if it can't support my lovely background effect then that's just tough luck for anyone still using it".

How to preserve aspect ratio when scaling image using one (CSS) dimension in IE6?

Here's the problem. I have an image:
<img alt="alttext" src="filename.jpg"/>
Note no height or width specified.
On certain pages I want to only show a thumbnail. I can't alter the html, so I use the following CSS:
.blog_list div.postbody img { width:75px; }
Which (in most browsers) makes a page of uniformly wide thumbnails, all with preserved aspect ratios.
In IE6 though, the image is only scaled in the dimension specified in the CSS. It retains the 'natural' height.
Here's an example of a pair of pages that illustrate the problem:
The list, which should show thumbnails
A single blog post, which shows the full-size image.
I'd be very grateful for all suggestions, but would like to point out that (due to the limitations of the clients chosen platform) I'm looking for something that doesn't involve modifying the html. CSS would also be preferable to javascript.
EDIT: Should mention that the images are of different sizes and aspect ratios.
Adam Luter gave me the idea for this, but it actually turned out to be really simple:
img {
width: 75px;
height: auto;
}
IE6 now scales the image fine and this seems to be what all the other browsers use by default.
Thanks for both the answers though!
I'm glad that worked out, so I guess you had to explicitly set 'auto' on IE6 in order for it to mimic other browsers!
I actually recently found another technique for scaling images, again designed for backgrounds. This technique has some interesting features:
The image aspect ratio is preserved
The image's original size is maintained (that is, it can never shrink only grow)
The markup relies on a wrapper element:
<div id="wrap"><img src="test.png" /></div>
Given the above markup you then use these rules:
#wrap {
height: 100px;
width: 100px;
}
#wrap img {
min-height: 100%;
min-width: 100%;
}
If you then control the size of wrapper you get the interesting scale effects that I list above.
To be explicit, consider the following base state: A container that is 100x100 and an image that is 10x10. The result is a scaled image of 100x100.
Starting at the base state, the
container resized to 20x100, the
image stays resized at 100x100.
Starting at the base state, the
image is changed to 10x20, the image
resizes to 100x200.
So, in other words, the image is always at least as big as the container, but will scale beyond it to maintain it's aspect ratio.
This probably isn't useful for your site, and it doesn't work in IE6. But, it is useful to get a scaled background for your view port or container.
Well, I can think of a CSS hack that will resolve this issue.
You could add the following line in your CSS file:
* html .blog_list div.postbody img { width:75px; height: SpecifyHeightHere; }
The above code will only be seen by IE6.
The aspect ratio won't be perfect, but you could make it look somewhat normal.
If you really wanted to make it perfect, you would need to write some javascript that would read the original picture width, and set the ratio accordingly to specify a height.
The only way to do explicit scaling in CSS is to use tricks such as found here.
IE6 only, you could also use filters (check out PNGFix). But applying them automatically to the page will need javascript, though that javascript could be embedded in the CSS file.
If you are going to require javascript, then you might want to just have javascript fill in the missing value for the height by inspecting the image once the content has loaded. (Sorry I do not have a reference for this technique).
Finally, and pardon me for this soapbox, you might want to eschew IE6 support in this matter. You could add _width: auto after your width: 75px rule, so that IE6 at least renders the image reasonably, even if it is the wrong size.
I recommend the last solution simply because IE6 is on the way out: 20% and going down almost a percent a month. Also, I note that your site is recreational and in the UK. Both of these help the demographic lean to be away from IE6: IE6 usage drops nearly 40% during weekends (no citation sorry), and UK has a much lower IE6 demographic (again no citation, sorry).
Good luck!

Gradient fill using jQuery?

I've got a <div> that needs a gradient background. However, the size of the div is variable, which lands me back in "can't do gradients in CSS" land.
However, I'm pretty sure this is possible in jQuery, I just can't seem to find a decent example. Does anyone have something they can point my way?
Thanks.
in case that someone needs this, and if you think that the jQuery plugin is too heavy, you can use this
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00A622', endColorstr='#00B726'); /* for IE */
background: -webkit-gradient(linear, left top, left bottom, from(#00A622), to(#00B726)); /* for webkit browsers */
background: -moz-linear-gradient(top, #00A622, #00B726); /* for firefox 3.6+ */
While this will most likely give you precisely what you want, there seem to be quite a few potential collisions. Give it a shot, though; if it fails, I recommend generating the gradient server-side.
Not Jquery but a suggestion: you could generate your gradient with SVG: http://www.w3schools.com/svg/svg_grad_linear.asp
The Background Canvas plugin lets you do that sort of thing and more.
Is it absolutely necessary to generate the gradient rather than simply create one in your favorite graphics program? Might be more efficient to save resources by simply tiling a graphic.
Why not calculate the gradiant to be larger than the div and hide the excess in overflow so on resize the rest is revealed?

Categories

Resources