I'm working on a JavaScript image resizing feature which rely on the IE only DXImageTransform addon.
Wanting to address modern browsers as well, I gave a shot to canvas, with pretty good results.
However, I face an issue in my resize function, which is the following:
function Resize(oObj, flMultiplier)
{
var canvas = document.getElementById('canvas');
var canvasContext = canvas.getContext('2d');
oObj.style.visibility = 'hidden';
canvasContext.clearRect(0,0,canvas.width,canvas.height); // clear canvas
canvasContext.fillStyle = 'rgba(0,0,0,0.4)';
canvasContext.scale(flMultiplier,flMultiplier);
canvasContext.drawImage(oObj, 0, 0);
}
If my image becomes bigger than the canvas item, then one will see only a portion of the image, which is bad.
I tried to tweak the canvas size at runtime, but if affects the display of the resized image.
So I ended up declaring a big canvas element, which is pretty OK, except that the css overflow of my web page is adjusted on my biggest element, and not on my resized image, which is a pain.
So I guess there are two ways to solve my problem:
Try to exclude the big canvas element from the overflow scheme
Try to update the canvas element size when resizing (I may have missed something there)
I haven't tried that myself, but perhaps you can create a canvas element out of the Dom, with document.createElement. It could be of arbitrary size without disturbing the display.
Now, I lack context (why do you resize images this way instead of using width and height attributes, among other questions) so maybe I am missing the point.
Related
There is one simple task I want to achieve.
I have an image in a variable width container.
The container can have a width of 300, 400, 700, or 900 pixels. This is done by the means of media-queries
The image should take up all the width of that container. So it will be also 300, 400, 700, or 900 pixels wide.
The image should have different sources for all that width values. So I can serve smaller images on mobile phones.
I thought that this could be done with the srcset attribute of the img element, maybe under help of the sizes attribute. width something like this
<img src="http://dummyimage.com/300x200/abc/000"
alt="dummy"
srcset="
http://dummyimage.com/900x200/abc/000 900w,
http://dummyimage.com/700x200/abc/000 700w,
http://dummyimage.com/400x200/abc/000 400w,
http://dummyimage.com/300x200/abc/000 300w
"
/>
But it's not working in that way, because the browser chooses the image in proportion to the width of the display port and not to that of the image itself.
Example with use of picturefill polyfill from http://scottjehl.github.io/picturefill/: http://codepen.io/HerrSerker/pen/itBJy . This does not work, because it will take the one image that is the next size.
I could of course take that into account and change my srcset to this
srcset="
http://dummyimage.com/900x200/abc/000 999999w,
http://dummyimage.com/700x200/abc/000 900w,
http://dummyimage.com/400x200/abc/000 700w,
http://dummyimage.com/300x200/abc/000 400w
"
This will work on the desktop, but fails on retina displays, because the device pixel ratio is taken into account here, but in a different way than with the media queries. And it is not useful, because the image should know about the width of the viewport and of the same width and that at compile time? No way. Image I use the image in a grid system. The image has different widthes if I'm in a 3 column grid on desktop devices and a 1 column grid on smart phones. That should not be in the responsibility of the image to calulate the ratio of width and viewport-width.
I did not have any luck with the sizes attribute as well (no example here). The reason is tha same as above. In the sizes attibute I say which amount of the viewport width should my image be wide according to media queries. This is so off. How should the image know?
So I came around with this solution. I setup a data-srcset attribute with the same syntax as the srcset attribute itself, but with a custom JavaScript programming. Example here: http://codepen.io/HerrSerker/pen/tCqJI
jQuery(function($){
var reg = /[\s\r\n]*(.*?)[\s\r\n]+([^\s\r\n]+w)[\s\r\n]*(,|$)/g;
var regw = /(.*)w/;
var sets, $set, set, myMatch, i, w, that, last;
var checkData = function() {
$('img[data-srcset]').each(function() {
that = $(this);
$set = that.data('srcset');
sets = [];
while(myMatch = reg.exec($set)) {
set = {};
set.src = myMatch[1];
set.w = (myMatch[2].match(regw))[1];
sets[set.w] = set;
}
w = that.width();
last = 0;
for (i in sets) {
last = i;
if (w <= i) {
that.attr('src', sets[i].src);
return;
}
}
that.attr('src', sets[last].src);
});
};
checkData();
$(window).on('resize', checkData);
});
This works, but it feels wrong. But maybe not, as the specifications says for responsive images to behave just in the way that it does. But I feel that it's the wrong way. 90 % of use cases for responsive images won't work with the spec.
So am I wrong? Didn't I use the srcset in the defined way? Did I understand the spec incorrectly? And do the W3C and Responsive Images Community Group think in such a way apart from reality?
Are the smaller images scaled down versions of the bigger image? Or are they cropped (art direction)? If the latter, you should use picture and source media.
The reason the browser only uses the viewport for deciding which image to download is that it's the only thing that is available when the browser wants to download an image. The CSS (probably) isn't downloaded yet. So if you use srcset+sizes, you have to repeat the breakpoints and image widths in sizes.
This question seems like a duplicate of Responsive full width image banner with fixed height using srcset
Like zcorpan said, what you are trying to do falls under the "art-direction" use-case (since the different images have different proportions), so you should use the <picture> element, rather than srcset. See the other question's answers for a syntax example.
I'm adapting a wordpress theme and it would be nice to have the text of the whole page scale depending on the width of each container div.
So far all the widths are in % but as w3c mentions the font-size property only takes into account the font-size of the parent and not the size of the container div.
As multiple other answers hint, I could do that with javascript and target each container div,
which though being a very helpful answer from my point of view doesn't apply to my problem because I dont know all the possible container ids or classes since I have to account for future plugin installations which could output text, e.t.c.
so is there any other way to do this?
Not without Javascript. CSS bases font-size percentages based on height of a line, there are no width-based controls.
I'd strongly recommend changing your design.
If you want to try to go with it, I'm not sure how proficient you are at Javascript, but you could iterate through DOM nodes, look for a common condition, find the width of the DIV, and move forward that way.
one possible solution could be to target only the body element and change its font-size, this way every font-size should adapt due to the parent changing.
this solution combined with media queries to target the most common screen size should be perfect.
Based on that, I pieced together the following ( http://jsfiddle.net/8TrTU/73/ )
function adaptFontSize() {
var defaultW = 100;
var defaultFontSize = 16;
var width = parseInt($("#header").width());
var fontSize = (defaultFontSize * width)/defaultW+"px";
$("#page").css('font-size', fontSize);
// alert(width +" "+ defaultFontSize * width+ " " fontSize);
}
$(document).ready(adaptFontSize);
$(window).resize(adaptFontSize);
opinions? possible improvements?
I am wondering if it is possible to shrink an image widget down to a size that is smaller than the image resource itself. I have tried the following:
imageResource.setSize(size, size);
imageResource.setPixelSize(size, size);
I have also tried re-sizing in the CSS file. But when I size the image to smaller than the original, it just crops it down and doesn't actually shrink it. It seems to me the solution is to use a high resolution, smaller image that I can scale up if need be, but I feel like I'm missing something here.
You can use CSS3 background-size property to scale the image:
http://www.w3schools.com/cssref/css3_pr_background-size.asp
Note that it's not supported in some very old browsers.
You can also try with,
ImageResorce myImage = new ImageResource();
myImage.getElement().setAttribute("height","20px");
myImage.getElement().setAttribute("width","20px");
cheers !!!
I need to give an overlay texture to 100+ images
like this.
I have transparent .PNG texture file. if i use this as background then it will go behind the <img>. And I don't want to add another <img> or any extra span, div for texture and z-index.
Is there any other way to achieve it in CSS?
I need to use specific texture .png so i cannot use CSS gradient only.
I don't want to use main product image as background.
I'm afraid you're going to have a very hard time getting that texture overlaid on the image without some added element to put it on. If you can't affect the html output, a little javascript would do the trick.
Another option is to place the texture over the top of the other image with absolute positioning. It's hard to know if that's a viable option without more context, however. Here's an example: http://jsfiddle.net/cPSFQ/1/.
Glad your post is tagged with CSS3
http://jsfiddle.net/WQTeE/2/
You have to create a reverse mask of the overlay. I tested this in FF9 and Chrome 16
img.stockphoto{
-webkit-mask-box-image: url(http://koivi.com/php-gd-image-watermark/watermarks/Sample-trans.png);
-o-mask-image: url(http://koivi.com/php-gd-image-watermark/watermarks/Sample-trans.png);
-moz-mask-image: url(http://koivi.com/php-gd-image-watermark/watermarks/Sample-trans.png);
mask-image: url(http://koivi.com/php-gd-image-watermark/watermarks/Sample-trans.png);
}
You can try this.
http://jsfiddle.net/Bs7nv/
In this all I am doing is displaying an image and a div in which we can use the texture image as background and absolute positioning to display over the actual image.
There is no pure css solution to your question that's cross browser compatible. I realize that this answer doesn't meet your original criteria, but I figured I'd supply it anyways so that you could have it as an option.
Using pseudo elements (:before) would be a logical choice for CSS3, but alas, they don't work on img tags.
You'll have to do something, rather change the mark-up or add some javascript. Assuming you can't edit the mark-up (sometimes you can't control your source data), but can control the javascript, you could do it with pure javascript like this:
var transparentImage = "http://rd.cas.de/tim/native/image.png";
var imageList = document.getElementsByTagName("img");
var arrImages = [];
for (var i = 0; i < imageList.length; i++ ) {
// store the images as is first, otherwise the list is living and
// you loop forever...
arrImages.push(imageList[i]);
}
for (i = 0; i < arrImages.length; i++ ) {
// first wrap all the images in a relative positioned div.
var wrapper = document.createElement('div');
var newImg = document.createElement("img");
newImg.setAttribute("src", transparentImage);
newImg.style.position = "absolute";
wrapper.appendChild(newImg);
wrapper.appendChild(arrImages[i].cloneNode(true));
arrImages[i].parentNode.replaceChild(wrapper, arrImages[i]);
}
Here's a jsfiddle that does what you want (but with javascript).
I'm programming a debate-graph with Raphael JS. Users can add nodes to the graph. Eventually the graph gets really big and the canvas is still the same size. the canvas (in raphael js: paper) is inside another div with "overflow: scroll;", so lets ignore screen real estate
Is there a way that I resize the canvas without reloading the page (to assign new X/Y values)?
Alternatively, can I create a second bigger canvas in parallel and copying all the elements over? is there a way?
If I understand your question, just call setSize() to expand the size of the canvas to the size needed as you need it. I've used this in a div with overflow:scroll to get the effect you describe.
In my case, I didn't want to resize, I wanted to zoom.
In other words, show the user the growing graph inside a constant-sized div.
So I needed: setViewBox()