Multiple masked image - html

I am trying to make multiple masked images.
How can I make;
image_01 + mask_image_01 = image_02
image_02 + mask_image_02 = image_03 ?
** image_02 is result of image_01 with mask_image_01.
(should be running on both Chrome and IE)

Assuming that I've understood you right, you can just use the background property for an image:
CSS:
#image_o1 {
background: transparent url(http://davidrhysthomas.co.uk/linked/astrid_avatar.png) top left no-repeat;
}
HTML:
<img id="image_o1" src="http://davidrhysthomas.co.uk/linked/mask.png" />
JS Fiddle demo.
The only major problem with this method is that it uses the masking image in the src of the img element, and puts the 'real' image in the background.
If JavaScript is an option, then you could use the image you want to mask as the src of the image element(s), and then switch that for a mask, though this is a little messy (and could definitely be improved):
function imageMask(){
var masked = document.getElementsByClassName('masked');
var mD, mU, rImg;
for (i=0; i<masked.length; i++){
mD = window.getComputedStyle(masked[i],null).backgroundImage;
mU = mD.substring(mD.indexOf('(')+1,mD.indexOf(')'));
rImg = masked[i].src;
masked[i].src = mU;
/*
For some (probably obvious) reason:
masked[i].style.backgroundImage = rImg;
refused to work, so I'm using 'setAttribute()' instead, in a
hackish and hideous workaround.
*/
masked[i].setAttribute('style','background-image: url(' + rImg + ');');
}
};
window.onload = imageMask();
JS Fiddle demo
Browser compatibility might be a problem with the JavaScript approach, though, as IE (I think) doesn't support either .getElementsByClassName() or window.getComputedStyle(). The majority of other browsers, though, seem happy enough with it. Tested in Firefox 7 and Chromium 14 on Ubuntu 11.04.

Related

Retina Devices in web developing: Do I still need to have 2x images?

A lot of the information about Retina devices comes from ~2013 but not much recently.
It seems like, for example in retina.js, it includes anything with a device pixel ratio of > 1.5 to be "retina", but don't all smartphones have well over 1.5 these days? My desktop computer does as well.
My question then, why not just always serve the highest possible resolution images you have access to instead of creating the half-sized versions for "non-retina" devices, which as far as I know don't really exist much and won't suffer much from being served a higher resolution image.
Thanks!!!
Using 2x images is a huge pain.
Who can know what is "best," but I'm currently working with images in a combo like this:
I use a parent element so that the image will fill it - and that parent/or it's ancestors will determine any limits. You can use the picture element. (usually, the src are supplied by a CMS or something {{image.small.url}} etc.
The official answer to your questions would be, that people don't serve the higher res file to everything - because the file is bigger and they want the site to load as fast as possible. / but if you double the images size (twice as big as it will ever be presented, and compress to ~40 or so) then use the parent element to size it - it's actually a smaller file size. There are very specific studies on this. I don't know how that works for painting and browser rendering, though.
MARKUP
<figure class='poster'>
<img src='' alt=''
data-small='http://placehold.it/600'
data-medium='http://placehold.it/1000'
data-large='http://placehold.it/2000'
/>
</figure>
STYLES (stylus)
figure // just imagine the brackets if you want
margin: 0
img
display: block
width: 100%
height: auto
.poster
max-width: 400px
SCRIPT
$(document).on('ready', function() {
// $global
var $window = $(window);
var windowWidth;
var windowHeight;
function getWindowDimentions() {
windowWidth = $window.width();
windowHeight = $window.height();
}
function setResponsibleImageSrc(imageAncestorElement, container) {
var large = false; // innocent until proven guilty
var medium = false; // "
var context;
if ( !container ) {
context = windowWidth;
} else {
context = $(container).outerWidth();
}
var large = context > 900;
var medium = context > 550;
$(imageAncestorElement).each( function() {
var $this = $(this).find('img');
var src = {};
src.small = $this.data('small');
src.medium = $this.data('medium');
src.large = $this.data('large');
if ( large ) {
$this.attr('src', src.large);
} else if ( medium ) {
$this.attr('src', src.medium);
} else {
$this.attr('src', src.small);
}
});
};
$window.on('resize', function() { // this should jog a bit
getWindowDimentions();
setResponsibleImageSrc('.poster', 'body');
}).trigger('resize');
});
It all depends on what you are doing - and there is no silver bullet yet. The context for each image is so unique. My goal is to get in the ballpark for each size - keep the images compressed to 40 in Photoshop on export... double the size they should be, and then the parent squishes them for retina. The size is actually smaller in most cases.
CodePen example: http://codepen.io/sheriffderek/pen/bqpPra

Reduce the size of text in angularjs when line breaks?

I have a responsive app for desktop and mobile.
In the app i have a div which randomly shows texts of all kinds of lengths.
I want to do the following:
If the line breaks because the length of the text is too wide for the width of that div, i want the font-size to reduce itself (I am using em's in my app).
Is it something i need to build directive for it? is it something that was built and used wildly?
Writing a robust solution for this problem is going to be non-trivial. As far as I know, there's no way to tell whether a line of text breaks. However, we do know the criteria for line breaking is the width of the text being wider than the element, accounting for padding.
The Canvas API has a method called measureText which can be used to measure a string, using a given context with a font and size set. If you spoof the settings of the element with a canvas, then you can measure the text with the canvas and adjust the size until it fits without overflowing.
I've written up a rough implementation of the way I would tackle this.
function TextScaler(element) {
var canvas = document.createElement('canvas'),
context = canvas.getContext('2d');
var scaler = {};
scaler.copyProps = function() {
var style = element.style.fontStyle,
family = element.style.fontFamily,
size = element.style.fontSize,
weight = element.style.fontWeight,
variant = element.style.fontVariant;
context.font = [style, variant, weight, size, family].join(' ');
};
scaler.measure = function(text) {
text = text || element.innerText;
return context.measureText(text);
};
scaler.overflows = function() {
var style = window.getComputedStyle(element),
paddingLeft = style['padding-left'],
paddingRight = style['padding-right'],
width = style.width - paddingLeft - paddingRight;
return scaler.measure() > width;
};
scaler.decrease = function() {
// decrease font size by however much
};
scaler.auto = function(retries) {
retries = retries || 10;
if(retries <= 0) {
scaler.apply();
console.log('used all retries');
}
if(scaler.overflows()) {
scaler.decrease();
scaler.auto(retries - 1);
} else {
console.log('text fits');
scaler.apply();
}
};
scaler.apply = function() {
// copy the properties from the context
// back to the element
};
return scaler;
}
After you've sorted out some of the blank details there, you'd be able to use the function something like this:
var element = document.getElementById('');
var scaler = TextScaler(element);
scaler.auto();
If it doesn't manage to decrease it within 10 retries, it will stop there. You could also do this manually.
while(scaler.overflows()) {
scaler.decrease();
}
scaler.apply();
You'd probably want some fairly fine tuned logic for handling the decrease function. It might be easiest to convert the ems to pixels, then work purely with integers.
This API could quite trivially be wrapped up as a directive, if you want to use this with Angular. I'd probably tackle this with two attribute directives.
<div text-scale retries="10">Hello world</div>
Of course, if it's not important that all the text is there onscreen, then you can just use the text-overflow: ellipsis CSS property.

Calculate size of SVG element in HTML page

How can I reliably ask for the size (in pixels) an SVG element is taking up on the host page?
Both svg.offsetWidth and svg.getBoundingClientRect().width work in Chrome v34.
Neither of those work correctly in Firefox v29. (The former is empty, the latter returns incorrect values.)
Test Page: http://jsfiddle.net/dL5pZ/3/
The motivation for this question is to get a reliable implementation for this answer, which requires knowing the aspect ratio of the outside of the element. Further, for this question I need to know the actual size of the SVG, or at least something that returns proportionate values across different calls and a resizing element.
I've been down that road before. Unfortunately, most of the functions for getting the size of the <svg> element are buggy in Firefox. The only working solution I found was using window.getComputedStyle(svgElement).width (or height), which needs to be parsed (and also only works when svgElement.display == 'block', which it is in your example).
I have adopted your fiddle to work in Firefox: http://jsfiddle.net/dL5pZ/5/
Update: The issue with display 'inline' was fixed some time ago around Firefox 29.
Update 2: As mentioned in another answer, getBoundingClientRect should also work nowadays.
Some more info from my research because I've spent the last 2 days working on this issue..
So, it always works in Chrome and Opera, it works in IE if you add preserveAspectRatio="xMinYMin slice" but Firefox seems buggy.
To make it work cross platform try:
a) accessing width and height of SVG directly - Ch,O,IE
b) getComputedStyle:
var style = window.getComputedStyle(svg, null);
var svgWidth = style.getPropertyValue("width").slice(0, -2); // "1240px" -> "1240"
keep in mind that for single queries it is fine, but when you try to do it about 60 times per second then the browser becomes very slow
c) as we know this issue happens when we have
<div><svg style="width:100%; height:100%"></svg></div>
and the width and height of SVG element are 1 in Firefox.. but these dimensions are as same as the dimensions of the div parent element which you can access! But to make life harder it doesn't work in IE.
So reassuming, this is my final cross browser code:
if(!svg.width.baseVal.value || svg.width.baseVal.value < 2){
//this is the FF case
if(!this.parentElement) return;
this.width = this.parentElement.clientWidth;
this.height = this.parentNode.clientHeight;
}
else{
//this works for Ch,O,IE
this.width = svg.width.baseVal.value;
this.height = svg.height.baseVal.value
}
getBoundingClientRect has been fixed in Firefox from version 33 onwards and will do what you want it to now. See bug 530985 for details.
This was the way I fixed it:
var heightComponents = ['height', 'paddingTop', 'paddingBottom', 'borderTopWidth', 'borderBottomWidth'],
widthComponents = ['width', 'paddingLeft', 'paddingRight', 'borderLeftWidth', 'borderRightWidth'];
var svgCalculateSize = function (el) {
var gCS = window.getComputedStyle(el), // using gCS because IE8- has no support for svg anyway
bounds = {
width: 0,
height: 0
};
heightComponents.forEach(function (css) {
bounds.height += parseFloat(gCS[css]);
});
widthComponents.forEach(function (css) {
bounds.width += parseFloat(gCS[css]);
});
return bounds;
};
Using your jsFiddle: http://jsfiddle.net/dL5pZ/7/
This is what I ended up using:
var svgWidth = svg.clientWidth || window.getComputedStyle(svg).width.slice(0, -2),
svgHeight = svg.clientHeight || window.getComputedStyle(svg).height.slice(0, -2);
as clientWidth and clientHeight always return 0 in Firefox.
For d3 users:
var svg = d3.select('#yoursvg')[0][0],
svgWidth = svg.clientWidth || window.getComputedStyle(svg).width.slice(0, -2),
svgHeight = svg.clientHeight || window.getComputedStyle(svg).height.slice(0, -2);
Hope it helps.
<button onclick="demosvg()">click on</button>
<svg>
//<image xlink:href="demo.jpg" id="img1" height="200" width="200"/>
<img id="myImg" src="demo.jpg" style="width:500px;height:98px;">
</svg>
<div id="demo"></div>
<script>
function demosvg() {
var var1 = document.getElementById("img1").naturalWidth;
document.getElementById("demo").innerHTML = "width is: " + var1+ " pixels";
}
</script>

HTML/DOM: color/bgColor; do values other than 16 HTML-colors give (un)predictable results?

Running this code in browser, if no colour is entered, 'green'(undefined) is rendered.
Random/garbage value leads to black background...
...not selecting or transparent gives white(null)
<HTML>
<HEAD>
<TITLE>Document Object Demo</TITLE>
</HEAD>
<BODY>
<SCRIPT LANGUAGE=Javascript>
var sAnswer = window.prompt("Please enter your favourite color : choose from the following Yellow, Green, Red, Blue, Pink, Orange, Black, Gray")
document.bgColor = sAnswer
document. write ("<H1>Welcome " + sAnswer + ":-)!!</H1><HR>We are very happy to demonstrate the usage of <I> document. write</I>. Do remember to view the source!<P>")
</SCRIPT>
</BODY>
</HTML>
I use IE9...!
Why is this happening?
You are having this problem because the browser will try to parse something out of w/e you set the bgColor to...
Now your Javascript is fairly questionable, and I can not think of a reason you'd want to do this, but your code should probably look more like this.
(function () {
// Prompts the user to give an answer, this prevents further code execution
var sAnswer = window.prompt("Please enter your favourite color : choose from the following Yellow, Green, Red, Blue, Pink, Orange, Black, Gray");
// Takes care of all falsy valuyes, 0, null, undefined, false
// Ideally some more validation on the input should be done
if(sAnswer) {
document.body.style.backgroundColor = sAnswer;
document.write ("<h1>Welcome " + sAnswer + ":-)!!</h1><hr><p>We are very happy to demonstrate the usage of <i> document. write</i>. Do remember to view the source!</p>");
} else {
document.write ("<p>You did not fill in a valid answer! Refresh.</p>");
}
}());
OR keep asking the question until a valid answer is given.. (fairly evil imo)
(function () {
var sAnswer;
do {
sAnswer = window.prompt("Please enter your favourite color : choose from the following Yellow, Green, Red, Blue, Pink, Orange, Black, Gray")
} while ( !sAnswer );
document.body.style.backgroundColor = sAnswer;
document.write ("<h1>Welcome " + sAnswer + ":-)!!</h1><hr><p>We are very happy to demonstrate the usage of <i> document. write</i>. Do remember to view the source!</p>");
}());
Code not tested but fairly confident it should work :p
Edit, how does it get to the colour green?
In short, undefined is typecasted to a string which can be used to set the bgColor property, which in turn is parsed and interpreted as a color, making invalid hex characters count for 0. Read this for a more in depth explanation.
Internet Explorer used this interpretation and the other browsers followed so to not break backwards compatibility.
There is nothing such as default color. There is default css style which differs in different browsers (See Browsers' default CSS stylesheets).
For your code, you should most likely check the answer provided by the user whether it make even sense to set bgColor.
Moreover this proeprty is deprecated: https://developer.mozilla.org/en/DOM/document.bgColor.
You should be probably setting the background via: document.body.style.backgroundColor.

Is there any way to set a CSS min-width on an element that is floated?

I have this html:
<div id="subNav"></div>
<div id="feed"></div>
<div id="feedBar"></div>
I have floated all of these divs left. I set the width of #subNav and #feedBar, but on #feed I set its min-width . It takes the min-width even though the window is larger. Is there any way that with floating you can make the min-width work? I am trying to make a flexible layout on the page.
The following answer uses a JavaScript solution, in response to #Chromedude's comment (to the original question):
#David Is there any way to override this behavior? with javascript?
I'm sure there's a far more simple way of doing this (certainly with a JavaScript library), but this was the best I could come up with at this time of morning (in the UK):
var feed = document.getElementById('feed');
var width = document.width;
var feedBarWidth = document.getElementById('feedBar').clientWidth;
var subNavWidth = document.getElementById('subNav').clientWidth;
feed.setAttribute('style', 'width: ' + (width - (subNavWidth + feedBarWidth)) + 'px');
JS Fiddle demo.
Using jQuery (just as a suggestion as to the ease offered by a library):
var bodyWidth = $(document).width();
var subNavWidth = $('#subNav').width();
var feedBarWidth = $('#feedBar').width();
$('#feed').css('width', bodyWidth - (subNavWidth + feedBarWidth));
Use a grid system such as the one in Foundation 3. When placed on a div representing an element of the grid, min-width behaves just fine.
To get min-width to work without a grid, use a CSS rule that inserts an invisible pseudo-element with the desired minimum paragraph width.
p:before {
content: "";
width: 10em;
display: block;
overflow: hidden;
}
Further details are at the source where I learned this.