tag:blogger.com,1999:blog-15843928351749745422024-03-13T06:35:24.974+01:00Code and Stuffsatrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.comBlogger37125tag:blogger.com,1999:blog-1584392835174974542.post-41220284275096026052015-06-13T01:10:00.001+02:002021-06-10T21:36:52.570+02:00CSS3: Compositing
<style type="text/css">
@keyframes L14122028427509602605 {
0% { background-position: -125px 0px; }
5% { background-position: -87px -1px; }
10% { background-position: -52px -6px; }
15% { background-position: -24px -26px; }
20% { background-position: -7px -67px; }
25% { background-position: 0px -125px; }
30% { background-position: -7px -184px; }
35% { background-position: -24px -225px; }
40% { background-position: -52px -245px; }
45% { background-position: -87px -250px; }
50% { background-position: -125px -250px; }
55% { background-position: -164px -250px; }
60% { background-position: -199px -245px; }
65% { background-position: -227px -225px; }
70% { background-position: -244px -184px; }
75% { background-position: -250px -125px; }
80% { background-position: -244px -67px; }
85% { background-position: -227px -26px; }
90% { background-position: -199px -6px; }
95% { background-position: -164px -1px; }
100% { background-position: -125px 0px; }
}
@keyframes L24122028427509602605 {
0% { background-position: -125px 0px; }
5% { background-position: -87px -1px; }
10% { background-position: -52px -6px; }
15% { background-position: -24px -26px; }
20% { background-position: -7px -67px; }
25% { background-position: 0px -125px; }
30% { background-position: -7px -184px; }
35% { background-position: -24px -225px; }
40% { background-position: -52px -245px; }
45% { background-position: -87px -250px; }
50% { background-position: -125px -250px; }
55% { background-position: -164px -250px; }
60% { background-position: -199px -245px; }
65% { background-position: -227px -225px; }
70% { background-position: -244px -184px; }
75% { background-position: -250px -125px; }
80% { background-position: -244px -67px; }
85% { background-position: -227px -26px; }
90% { background-position: -199px -6px; }
95% { background-position: -164px -1px; }
100% { background-position: -125px 0px; }
}
@keyframes L34122028427509602605 {
0% { background-position: 0px 0px; }
5% { background-position: 0px -2px; }
10% { background-position: 0px -28px; }
15% { background-position: 0px -127px; }
20% { background-position: 0px -334px; }
25% { background-position: 0px -625px; }
30% { background-position: 0px -917px; }
35% { background-position: 0px -1124px; }
40% { background-position: 0px -1223px; }
45% { background-position: 0px -1249px; }
50% { background-position: 0px -1250px; }
55% { background-position: 0px -1249px; }
60% { background-position: 0px -1223px; }
65% { background-position: 0px -1124px; }
70% { background-position: 0px -917px; }
75% { background-position: 0px -625px; }
80% { background-position: 0px -334px; }
85% { background-position: 0px -127px; }
90% { background-position: 0px -28px; }
95% { background-position: 0px -2px; }
100% { background-position: 0px 0px; }
}
@-webkit-keyframes L14122028427509602605 {
0% { background-position: -125px 0px; }
5% { background-position: -87px -1px; }
10% { background-position: -52px -6px; }
15% { background-position: -24px -26px; }
20% { background-position: -7px -67px; }
25% { background-position: 0px -125px; }
30% { background-position: -7px -184px; }
35% { background-position: -24px -225px; }
40% { background-position: -52px -245px; }
45% { background-position: -87px -250px; }
50% { background-position: -125px -250px; }
55% { background-position: -164px -250px; }
60% { background-position: -199px -245px; }
65% { background-position: -227px -225px; }
70% { background-position: -244px -184px; }
75% { background-position: -250px -125px; }
80% { background-position: -244px -67px; }
85% { background-position: -227px -26px; }
90% { background-position: -199px -6px; }
95% { background-position: -164px -1px; }
100% { background-position: -125px 0px; }
}
@-webkit-keyframes L24122028427509602605 {
0% { background-position: -125px 0px; }
5% { background-position: -87px -1px; }
10% { background-position: -52px -6px; }
15% { background-position: -24px -26px; }
20% { background-position: -7px -67px; }
25% { background-position: 0px -125px; }
30% { background-position: -7px -184px; }
35% { background-position: -24px -225px; }
40% { background-position: -52px -245px; }
45% { background-position: -87px -250px; }
50% { background-position: -125px -250px; }
55% { background-position: -164px -250px; }
60% { background-position: -199px -245px; }
65% { background-position: -227px -225px; }
70% { background-position: -244px -184px; }
75% { background-position: -250px -125px; }
80% { background-position: -244px -67px; }
85% { background-position: -227px -26px; }
90% { background-position: -199px -6px; }
95% { background-position: -164px -1px; }
100% { background-position: -125px 0px; }
}
@-webkit-keyframes L34122028427509602605 {
0% { background-position: 0px 0px; }
5% { background-position: 0px -2px; }
10% { background-position: 0px -28px; }
15% { background-position: 0px -127px; }
20% { background-position: 0px -334px; }
25% { background-position: 0px -625px; }
30% { background-position: 0px -917px; }
35% { background-position: 0px -1124px; }
40% { background-position: 0px -1223px; }
45% { background-position: 0px -1249px; }
50% { background-position: 0px -1250px; }
55% { background-position: 0px -1249px; }
60% { background-position: 0px -1223px; }
65% { background-position: 0px -1124px; }
70% { background-position: 0px -917px; }
75% { background-position: 0px -625px; }
80% { background-position: 0px -334px; }
85% { background-position: 0px -127px; }
90% { background-position: 0px -28px; }
95% { background-position: 0px -2px; }
100% { background-position: 0px 0px; }
}
.P4122028427509602605div {
position:absolute;
width: 250px;
height: 250px;
animation-iteration-count: infinite;
animation-timing-function: linear;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
}
#P4122028427509602605main {
position:relative;
width: 250px;
height: 250px;
}
#P4122028427509602605L14122028427509602605 {
background-image:url('https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXuOtHz44e9CXr55F9Y2Z6xW705gIPvIuGuWfN8EklH-FnWaNOqmpXs0fUc6sa8rdz5RgS5bPIp0us0iVXkMFKwz4nT1WMcVoF5xVZL7mX9i8bdMSzvuMRKSiBqZRdkkN0L8YFmh3-QXA/s1600/L1.jpg');
z-index:1;
animation-name: L14122028427509602605;
animation-duration: 5.4s;
-webkit-animation-name: L14122028427509602605;
-webkit-animation-duration: 5.4s;
}
#P4122028427509602605L24122028427509602605 {
background-image:url('https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3Z545PBg1_uuCWj-724Yt9pnUxhz5QHY_Y4eL8rX9BKv-RqpEZLeTcNPYKW3LtLEWHncOqsJjQo90ATOYHTW43TOENEBWMb2j6DeHk9n3tzXy5b8WuvYONnbuDAlhjwTiDSk-6j_9bO4/s1600/L2.jpg');
mix-blend-mode: difference;
-webkit-mix-blend-mode: difference;
z-index:2;
animation-name: L24122028427509602605;
animation-duration: 4s;
-webkit-animation-name: L24122028427509602605;
-webkit-animation-duration: 4s;
}
#P4122028427509602605L34122028427509602605 {
mix-blend-mode: hue;
-webkit-mix-blend-mode: hue;
background-image:url('https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRY9Xin3cGSx-iY22NEcJ7RFttz12pngMYh2UAPz61aOYu6Eiema7IK3Y1WtsuzapJVvVT26xPvhTjo3drZt0Ag7vNlPwBreA77UBpZRkJNBstZSr4mj0TI2zwWGwKOLGdeLnsUZGouDM/s1600/L3.jpg');
z-index:3;
animation-name: L34122028427509602605;
animation-duration: 5s;
-webkit-animation-name: L34122028427509602605;
-webkit-animation-duration: 5s;
opacity: 1;
}
</style>
CSS3 Supports Image Compositing! The animation below uses only CSS (no Javascript, no GIF).
Requires Firefox 32+, Chrome 41+.
<p/>
<br/>
<div id="P4122028427509602605main">
<div class="P4122028427509602605div" id="P4122028427509602605L14122028427509602605">
</div>
<div class="P4122028427509602605div" id="P4122028427509602605L24122028427509602605">
</div>
<div class="P4122028427509602605div" id="P4122028427509602605L34122028427509602605">
</div>
</div>
satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-87892482636836479902015-01-15T19:00:00.000+01:002015-01-16T00:28:15.721+01:00Java: DNS QueryGetting information about a host or a domain in Java is actually quite simple if you use the <a href="http://www.oracle.com/technetwork/java/jndi/index.html">JNDI (Java Naming and Directory Interface)</a>. This interface, available since java 1.3, offers a standardized access to a range of directory services. Among them the DNS.
<p/>
Its usage can be quite simple. For instance, asking for the IP of a host is simply:
<pre><code class="prettyprint">DirContext ctx = new InitialDirContext();
Attributes attr = ctx.getAttributes("dns:/www.example.com");
String ip = attr.get("a").get().toString();
</code></pre>
<p/>
Getting the MX record of a domain is just as simple:
<pre><code class="prettyprint">DirContext ctx = new InitialDirContext();
Attributes attr = ctx.getAttributes("dns:/gmail.com",
new String[] { "MX" });
String host = attr.get("MX").get().toString();
</code></pre>
<p/>
And so is quering a different DNS server. The following example will query google's DNS for the MX record of gmail.com:
<pre><code class="prettyprint">DirContext ctx = new InitialDirContext();
Attributes attr = ctx.getAttributes("dns://8.8.8.8/gmail.com",
new String[] { "MX" });
String host = attr.get("MX").get().toString();
</code></pre>
<h1>More</h1>
More information can be found at the following sites:
<ul>
<li><a href="http://docs.oracle.com/javase/7/docs/technotes/guides/jndi/jndi-dns.html">http://docs.oracle.com/javase/7/docs/technotes/guides/jndi/jndi-dns.html</a></li>
<li><a href="http://docs.oracle.com/javase/tutorial/jndi/TOC.html">http://docs.oracle.com/javase/tutorial/jndi/TOC.html</a></li>
</ul>satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-73475465631655217872014-01-02T15:33:00.000+01:002015-06-26T09:05:58.041+02:00SBS-3 to Base station Traffic CompressionListening only to ADS-B data from an <a href="http://www.kinetic.co.uk/">SBS-3</a> antenna can consist of something like 20-30KB/s of continuous data. If you have the device turned on 24/7 for a whole year this will sum up to more than half a Tera Byte of data. For most people this is just fine since it should still fall under the terms of use of most service providers or because the device is in the local network.
<p/>For others, however, it could be a problem. Take for instance a setup where the antenna will have to transmit the data via cellular network or via modem. Let's not forget that the data is outbound and on a line with 1Mbit/s out speed the basestation will eat up about 15% of the bandwidth.
<p/>Fortunately the traffic is quite repetitive and a constant flow is not really necessary. So this leaves the door open to compression and some nice people did all the work for us.
<p/>In this example the local network of the antenna is called Net A and the one of the client Net B. To compress the traffic we will need an additional computer on Net A that we will call Encoder. Here a Raspberry Pi or similar could be really ideal.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_v1wB62oGO59VdpGoSl4rePN1msOqoYCiOYf4YRSLtWIztl9LkycQnRFt-dgQOkqeOUilxRgGWcmNJdrhFhvTOm5TO0QqHRh0zLTqcbd9mSvYfvx6wbt_33HiztaVOhGUjtk47hz3IrY/s1600/text3933.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_v1wB62oGO59VdpGoSl4rePN1msOqoYCiOYf4YRSLtWIztl9LkycQnRFt-dgQOkqeOUilxRgGWcmNJdrhFhvTOm5TO0QqHRh0zLTqcbd9mSvYfvx6wbt_33HiztaVOhGUjtk47hz3IrY/s400/text3933.png" /></a></div>
<p/>For the tunnel we will use <a href="http://nmap.org/ncat/">ncat</a> and we will only compress the outbound traffic. Assuming that the antenna has the IP 192.168.1.2, on the Encoder we will run the following command:
<pre class="prettyprint">ncat -l 10001 -c 'ncat 192.168.1.2 10001 | gzip -c'</pre>
<p/>Assuming that the encoder's IP is 192.168.1.3, on the client in Net B we will run
<pre class="prettyprint">ncat -l 10001 -c 'ncat 192.168.1.3 10001 | gunzip -c'</pre>
To get ncat and <a href="http://gnuwin32.sourceforge.net/packages/gzip.htm">gzip</a> on windows you can either install them directly or use <a href="http://cygwin.org/">cygwin</a>.
<p/>now we just have to configure the basestation software to access localhost instead of the antenna and all traffic in going to be compressed.
<h1>Results</h1>
With some simple measurements, I could notice that the trick should allow you to reduce the traffic from the original 20KB/s to about 1KB/s.
Since gzip will compress data in blocks the flow of data will be much less regular. Fortunately it looks like the basestation software does not care about this.
<h1>Other software</h1>
Initially I tried to use a compressed SSH tunnel. Strangely there was no reduction in the traffic size. I probably did something wrong in setting the tunnel up. Since ncat worked so well I did not bother finding out what went wrong with the SSH tunnel.
<p/>Instead of gzip one could also use other compression software like <a href="http://tukaani.org/xz/">xz</a>, <a href="http://www.bzip.org/">bzip2</a>, etc. Such software might have even better compression ratios. Beware, however, that some algorithm use big compression buffers and might require quite some data before actually returning something.
<h1>Links</h1>
<dl>
<dt>kinetic avionics</dt> <dd><a href="http://www.kinetic.co.uk/">http://www.kinetic.co.uk/</a></dd>
<dt>ncat</dt> <dd><a href="http://nmap.org/ncat/">http://nmap.org/ncat/</a></dd>
<dt>gzip for windows</dt> <dd><a href="http://gnuwin32.sourceforge.net/packages/gzip.htm">http://gnuwin32.sourceforge.net/packages/gzip.htm</a></dd>
<dt>cygwin</dt> <dd><a href="http://cygwin.org/">http://cygwin.org/</a></dd>
</dl>satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-25899607249740089552013-04-13T00:00:00.000+02:002014-03-02T17:08:36.337+01:00SVG Filters: ColorMatrixThe Matrix you can enter below will be multiplied against all the color vectors of the image on the right below.
<style type="text/css">
input[type=range]{
width: 90px;
}
img.p2589960724974008955target {
-webkit-filter: url(#p2589960724974008955filter);
filter: url(#p2589960724974008955filter);
}
#p2589960724974008955 table {
margin: 10px auto;
}
#p2589960724974008955 td {
border-spacing:0;
border-collapse: collapse;
border: solid 1px silver;
}
.p25899607249740089551 td {
text-align:center;
}
</style>
<script type="text/javascript">
var a = 0;
function updatep2589960724974008955() {
var matrix = "";
$("input[type=range]").each(function(index, obj) {
matrix = matrix + $(obj).val() + " ";
});
var item = $("#p2589960724974008955filter").get(0);
var parent = item.parentNode;
item.getElementsByTagName("feColorMatrix")[0].setAttribute('values', matrix);
$("#p2589960724974008955output").text(matrix);
parent.removeChild(item);
parent.appendChild(item);
}
$(function() {
$("input[type=range]").each(makeRange);
$("input[type=range]").bind('change', updatep2589960724974008955);
});
function makeRange(dummy, element) {
return;
if ($.browser.mozilla) {
var width = $(element).width();
var minimum = +$(element).attr("min");
var maximum = +$(element).attr("max");
var step = $(element).attr("step");
var size = maximum - minimum;
var value = $(element).val();
// 1 and 2
var newDiv = $('<div style="overflow:scroll; display:inline-block;width:' + width + 'px; height:15px;">\
<div style="height:0px;width:' + (width * 4) + 'px"> </div></div>');
newDiv.insertBefore($(element));
// scroll to initial value
newDiv.scrollLeft(width * 3 *((value - minimum) / size));
// 3
newDiv.scroll(function(e){
// 3.1
var width = $(this).children().first().width() - $(this).width();
var value = this.scrollLeft / width;
// 3.2
var size = maximum - minimum;
var fval = minimum + size * value;
var ival = Math.floor(fval / step) * step;
ival = ival.toFixed(Math.ceil(Math.abs(Math.log(step))));
// 3.3
$(element).val(ival);
// 3.4
$(element).trigger('change');
});
// 4
$(element).css("position","absolute");
$(element).css("opacity","0");
$(element).css("left", "-5000px");
$(element).css("top", "-5000px");
}
}
</script>
<div id="p2589960724974008955">
<table>
<tr class="p2589960724974008955head">
<th class="p2589960724974008955r">R</th><th class="p2589960724974008955g">G</th><th class="p2589960724974008955b">B</th><th class="p2589960724974008955a">A</th><th>1</th>
</tr>
<tr class="p2589960724974008955r">
<td class="p2589960724974008955r"><input type="range" min="-1" max="1" step="0.1" value="1"/></td>
<td class="p2589960724974008955g"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<td class="p2589960724974008955b"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<td class="p2589960724974008955a"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<td class="p25899607249740089551"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<th>R</th>
</tr>
<tr class="p2589960724974008955g">
<td class="p2589960724974008955r"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<td class="p2589960724974008955g"><input type="range" min="-1" max="1" step="0.1" value="1"/></td>
<td class="p2589960724974008955b"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<td class="p2589960724974008955a"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<td class="p25899607249740089551"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<th>G</th>
</tr>
<tr class="p2589960724974008955b">
<td class="p2589960724974008955r"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<td class="p2589960724974008955g"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<td class="p2589960724974008955b"><input type="range" min="-1" max="1" step="0.1" value="1"/></td>
<td class="p2589960724974008955a"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<td class="p25899607249740089551"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<th>B</th>
</tr>
<tr class="p2589960724974008955a">
<td class="p2589960724974008955r"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<td class="p2589960724974008955g"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<td class="p2589960724974008955b"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<td class="p2589960724974008955a"><input type="range" min="-1" max="1" step="0.1" value="1"/></td>
<td class="p25899607249740089551"><input type="range" min="-1" max="1" step="0.1" value="0"/></td>
<th>A</th>
</tr>
<tr class="p25899607249740089551">
<td class="p2589960724974008955r">0</td>
<td class="p2589960724974008955g">0</td>
<td class="p2589960724974008955b">0</td>
<td class="p2589960724974008955a">0</td>
<td class="p25899607249740089551">1</td>
<th>1</th>
</tr>
</table>
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<filter id="p2589960724974008955filter">
<feColorMatrix type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0"/>
</filter>
</svg>
<table><tr><td><img src="http://3.bp.blogspot.com/-ZkKUcZjoCsk/R3e7ByW5fUI/AAAAAAAAIGo/iM5B0iPst64/s250/P1010742.JPG"/></td>
<td><img class="p2589960724974008955target" src="http://3.bp.blogspot.com/-ZkKUcZjoCsk/R3e7ByW5fUI/AAAAAAAAIGo/iM5B0iPst64/s250/P1010742.JPG"/></td>
</tr></table>
The SVG filter that is being applied to the image is the following.
<pre class="prettyprint">
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
<filter id="filterid">
<feColorMatrix type="matrix" values="<span id="p2589960724974008955output">1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 </span>"/>
</filter>
</svg>
</pre>
To apply such a filter to an HTML element one simply has to put the SVG filter
somewhere in the page and apply it with the following CSS3 code.
<pre class="prettyprint">
img {
-webkit-filter: url(#filterid);
filter: url(#filterid);
}
</pre>
</div>satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-54022290361120299792013-03-28T00:02:00.001+01:002013-04-11T13:50:43.648+02:00Battery Status (firefox)<div id="battery5402229036112029979">
<div id="level5402229036112029979"></div>
</div>
<style type="text/css">
#battery5402229036112029979 {
border-radius:8px;
border: solid 4px darkred;
float:right;
width: 80px;
height: 200px;
position: relative;
margin: 20px;
margin-top: 0px;
text-align: center;
font-weight: bold;
}
#level5402229036112029979{
position: absolute;
bottom: 0px;
background-color: green;
left:0px;
right:0px;
}
</style>
<script type='text/javascript'>
var nav5402229036112029979 = window.navigator.battery || window.navigator.webkitBattery;
function update5402229036112029979() {
$("#level5402229036112029979").height(nav5402229036112029979.level * 200);
if (nav5402229036112029979.level < 0.33) {
$("#level5402229036112029979").css("background-color","red");
$("#battery5402229036112029979").css("border-color","darkred");
} else if (nav5402229036112029979.level < 0.66) {
$("#level5402229036112029979").css("background-color","yellow");
$("#battery5402229036112029979").css("border-color","brown");
} else {
$("#level5402229036112029979").css("background-color","green");
$("#battery5402229036112029979").css("border-color","darkgreen");
}
}
$(function(){
if (nav5402229036112029979 == undefined) {
$("#battery5402229036112029979").text("N/A");
return;
}
update5402229036112029979();
nav5402229036112029979.addEventListener('levelchange', update5402229036112029979, false);
});
</script>
A web page can read the level of the computer's battery (if any) and it is really easy. It is all in the <code class="prettyprint">window.navigator.battery</code> object. This object has a property <code class="prettyprint">level</code> that indicates the current battery level as a number between 0 and 1. There is no need to poll the value. Level changes can be tracked with the "levelchange" event. The object tells also if the battery is being charged or used and has fields with hints on charging/dischanrging times. As for the level also this values are trackable registering event handlers.
<p/>
This is especially useful in web applications. For instance, with this API available, an application could be implemented so that power intensive operations like animations, audio and video are disabled, or limited to a minimum, when the battery level is getting too low. It could also return to the normal setting as soon as the power is connected.
<p/>
Unfortunately, as of March 2013, I know only of Firefox that supports this W3C Candidate Recommendation.
<h2>Howto</h2>
So, here is the code. First the HTML. There is nothing that is really needed to be done in HTML to access the battery status.
To display the level I simply created two DIVs, one for the whole battery the other for the current state.
<pre class="prettyprint">
<div id="battery"><div class="level"></div></div>
</pre>
Also the CSS is just for the display: some round borders and backgrounds.
<pre class="prettyprint">
#battery {
border: solid 4px darkred;
border-radius: 8px;
width: 80px;
height: 200px;
position: relative;
}
#battery .level {
position: absolute;
bottom: 0px;
background-color: red;
left:0px;
right:0px;
}
</pre>
It is the Javascript that is the most interesting. It registers an event that when triggered will update the battery indicator. Note: code uses some JQuery.
<pre class="prettyprint">
// let's be ready for webkit (they sayed they will use the prefix)
var battery = window.navigator.battery || window.navigator.webkitBattery;
function update() {
var level = battery.level;
$("#battery .level").height(level * 200);
// should probably define 3 classes, one for each color state
if (level < 0.33) {
$("#battery .level").css("background-color","red");
$("#battery").css("border-color","darkred");
} else if (level < 0.66) {
$("#battery .level").css("background-color","yellow");
$("#battery").css("border-color","brown");
} else {
$("#battery .level").css("background-color","lightgreen");
$("#battery").css("border-color","darkgreen");
}
}
// and finally when the DOM is ready let's update and register the event
$(function(){
if (battery == undefined) {
// sorry no battery status api support
return;
}
update();
// and here we register the event
battery.addEventListener('levelchange', update, false);
});
</pre>
<h2>Links</h2>
Here a few links to other people's posts about this:
<ul>
<li><a href="http://www.w3.org/TR/battery-status/">The W3C specs</a></li>
<li><a href="http://davidwalsh.name/battery-api">David Walsh</a></li>
<li><a href="https://developer.mozilla.org/en/docs/DOM/window.navigator.battery">Mozilla Developer Network</a> </li>
</ul>satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-47158925226353177322013-02-26T00:21:00.000+01:002013-02-26T09:49:49.631+01:00SVG Filter TestsApplying SVG filters to various things
<h1>Videos</h1>
Apply filter to WebRTC Webcam capture. Webcam code was taken from <a href="https://developer.mozilla.org/en-US/docs/WebRTC/Taking_webcam_photos">Mozilla</a>.
<p/>
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
<filter id="svgFilter4715892522635317732">
<feColorMatrix type="saturate" values="0"/>
<feConvolveMatrix preserveAlpha="true" kernelMatrix="-1 -1 -1 -1 8 -1 -1 -1 -1"/>
<feComponentTransfer>
<feFuncR type="linear" intercept="1" slope="-1"/>
<feFuncG type="linear" intercept="1" slope="-1"/>
<feFuncB type="linear" intercept="1" slope="-1"/>
</feComponentTransfer>
</filter>
</svg>
<style type="text/css">
#video4715892522635317732, #dolph4715892522635317732 {
filter: url(#svgFilter4715892522635317732) ;
-webkit-filter: url(#svgFilter4715892522635317732) ;
}
</style>
<video id="video4715892522635317732"></video>
<script type="text/javascript">
var width = 480, height = 0, video = 0;
(function() {
var streaming = false;
video = $('#video4715892522635317732').get(0);
navigator.getMedia = ( navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
navigator.getMedia(
{
video: true,
audio: false
},
function(stream) {
if (navigator.mozGetUserMedia) {
video.mozSrcObject = stream;
} else {
var vendorURL = window.URL || window.webkitURL;
video.src = vendorURL.createObjectURL(stream);
}
video.play();
},
function(err) {
console.log("An error occured! " + err);
}
);
video.addEventListener('canplay', function(ev){
if (!streaming) {
height = video.videoHeight / (video.videoWidth/width);
video.setAttribute('width', width);
video.setAttribute('height', height);
streaming = true;
}
}, false);
})();
</script>
<p/>Or on a normal video (source wikipedia <a href="http://en.wikipedia.org/wiki/File:GibraltarpediA_introduction_video.ogg">http://en.wikipedia.org/wiki/File:GibraltarpediA_introduction_video.ogg</a>);
<video id="dolph4715892522635317732" width="480" controls="controls" autoplay="autoplay" audio="muted" muted>
<source type="video/ogg" src="http://upload.wikimedia.org/wikipedia/commons/6/60/GibraltarpediA_introduction_video.ogg"></source>
</video>
<h1>Canvas</h1>
To test the canvas I will reuse my Image Compositing post <a href="http://satreth.blogspot.ch/2011/11/html5-canvas-image-plasma.html">"plasma"</a> like animation.
<p/>
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
<filter id="svgFilter8793703053794003705">
<feGaussianBlur stdDeviation="10" />
</filter>
</svg>
<style type="text/css">
#video8793703053794003705{
filter: url(#svgFilter8793703053794003705) ;
-webkit-filter: url(#svgFilter8793703053794003705) ;
}
</style>
<canvas id="video8793703053794003705">
</canvas>
<script type="text/javascript">
var images=[];
var t = 0;
function draw() {
var canvas = document.getElementById("video8793703053794003705");
var ctx = canvas.getContext("2d");
ctx.globalCompositeOperation = 'copy'; // forget the past
// draw first image
ctx.drawImage(images[0], 0, 0);
var px = -150.0 + 150.0 * Math.sin(0.86 * t + 2.3) * Math.sin(13 + t * 0.52);
var py = -200.0 + 200.0 * Math.sin(t * 1.3)* Math.sin(13 + t * 0.32);
ctx.globalCompositeOperation = 'lighter';
ctx.drawImage(images[1], px, py);
// increase the iteration
t = t + 0.06;
// reschedule
window.setTimeout("draw()", 50);
}
$(function(){
images[0] = new Image();
images[0].src = 'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhai2sQjB1vp-RbyeS-YuZ3z_Cavyd_6Qw5RsLnB9ncPSOIQMCL2XmqcAkno1MfvJENsl_N6ZgQwUQ8v18q-JgGUV_wlEofLh3n7aLkqcputdZy_G6q85FkIFx2e9tGpScpuTjsjE9l33U/s800/one.jpg';
images[1] = new Image();
images[1].src = 'https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-xXe-lc4531DC7aXjKC53uZ62Oo46xaw3CVbcnfF3217RvzLSZpqj7KybuJRdnsD2xN_faIs75HHQZsMWFJ5RZT-gbpWAIK96qHdkGCVBKVQFwWpGVuMoMlJ8JEkpp_rIBw4N7nXLmuM/s800/two.jpg';
window.setTimeout("draw()", 50);
});
</script>
<h1>Youtube</h1>
Youtube can work using flash or html5. Probably the HTML5 uses a video tag or a canvas (never actually checked that), but we are interested in the flash version. By default, if available, youtube uses flash (as of feb 2013).
<iframe id="video7702031316558626589" width="560" height="315" src="http://www.youtube.com/embed/VwbrC__IK18?autoplay=1" frameborder="0" allowfullscreen></iframe>
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
<filter id="svgFilter7702031316558626589">
<feMorphology operator="erode" radius="3"/>
<feMorphology operator="dilate" radius="3"/>
</filter>
</svg>
<style type="text/css">
#video7702031316558626589 {
filter: url(#svgFilter7702031316558626589) ;
-webkit-filter: url(#svgFilter7702031316558626589) ;
}
</style>
<a href="http://www.youtube.com/watch?v=VwbrC__IK18">Click Here</a> for the original Rhett & Link GMM video.
<h1>Problems</h1>
Mid february 2013 i tested Mac Firefox 19, Mac Chrome 25 and Windows Firefox 19
<ul>
<li>Chome shows some strange behaviour with animated stuff (e.g. convolution not applied) </li>
<li>Firefox SVG filters are quite slow (especially the erode and dilate)</li>
<li>Firefox SVG filters are not applied to flash videos on Windows. They are on a Mac 10.6</li>
</ul>
satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-84957113283407997052013-02-13T21:00:00.000+01:002013-04-25T09:22:08.573+02:00C++ PolymorphicUsed to Java I was quite surprised to discover that the RTTI of C++ works "polymorphic" only when the classes contain at least one virtual method. This means that if we have two classes, A and B where B inherits from A, and we ask for the typeid of an instance of B from a dereferenced A pointer, RTTI will tell us the type is B only if A has a virtual method otherwise it will tell us the type is A.
<p/>This is best shown in code:
<pre class="prettyprint">
#include <iostream>
#include <typeinfo>
class A { };
class B : public A { };
class VA {
virtual void dummy(){ };
};
class VB : public VA { };
int main() {
B* b = new B; // typeid is B, ok
A* a = new B; // typeid is A!
std::cout << "b: " << typeid(*b).name() << std::endl;
std::cout << "a: " << typeid(*a).name() << std::endl;
VB* vb = new VB; // typeid is VB, ok
VA* va = new VB; // typeid is VB, just like java :-)
std::cout << "vb: " << typeid(*vb).name() << std::endl;
std::cout << "va: " << typeid(*va).name() << std::endl;
return 0;
}
</pre>
will output the following:
<pre class="prettyprint">
b: 1B
a: 1A
vb: 2VB
va: 2VB
</pre>
The second line tells us that the type is A even if we created the object with "new B".
<p/>
This implies that we will not be allowed to dynamic_cast an A pointer to a B one. gcc will reports that the cast is not permitted becase the "source type is not polymorphic".
<pre class="prettyprint">
A* a = new B;
B* c = dynamic_cast<B*>(a); // compilation error
</pre>
It is, however, perfectly fine to cast the classes with the virtual method:
<pre class="prettyprint">
VA* va = new VB;
VB* vc = dynamic_cast<VB*>(va);
</pre>
satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-2636389368410054652013-01-30T23:07:00.002+01:002013-04-25T13:50:27.627+02:00Animating SVG Filters applied to HTML elementsAnimating CSS3 filters is possible. While the ones defined directly in CSS can be animated with CSS3 transitions, SVG filters require another approach. We can use SVG Animations. It is not as trivial as the transitions but still quite simple.
<h1>Setup</h1>
To animate SVG filters we simply have to put an animate tag as child of the element we want to animate. Animations can be timed, concatenate and even started with javascript.
<p/>
Here an example on how to animate the intercept of all the RGB transfer functions of the feComponentTransfer filter from -1 to 1 and back repeatedly.
<pre class="prettyprint">
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
<filter id="<b>myfilter</b>">
<feComponentTransfer>
<feFuncR type="linear" slope="1" intercept="-1">
<animate attributeName="intercept" attributeType="XML"
begin="0s" dur="4s" repeatCount="indefinite"
values="-1;1;-1"/>
</feFuncR>
<feFuncG type="linear" slope="1" intercept="-1">
<animate attributeName="intercept" attributeType="XML"
begin="0s" dur="4s" repeatCount="indefinite"
values="-1;1;-1"/>
</feFuncG>
<feFuncB type="linear" slope="1" intercept="-1">
<animate attributeName="intercept" attributeType="XML"
begin="0s" dur="4s" repeatCount="indefinite"
values="-1;1;-1"/>
</feFuncB>
</feComponentTransfer>
</filter>
</svg>
</pre>
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
<filter id="one263638936841005465">
<feComponentTransfer>
<feFuncR type="linear" slope="1" intercept="-1">
<animate attributeName="intercept" attributeType="XML" begin="0s" dur="4s" repeatCount="indefinite" values="-1;1;-1"/>
</feFuncR>
<feFuncG type="linear" slope="1" intercept="-1">
<animate attributeName="intercept" attributeType="XML" begin="0s" dur="4s" repeatCount="indefinite" values="-1;1;-1"/>
</feFuncG>
<feFuncB type="linear" slope="1" intercept="-1">
<animate attributeName="intercept" attributeType="XML" begin="0s" dur="4s" repeatCount="indefinite" values="-1;1;-1"/>
</feFuncB>
</feComponentTransfer>
</filter>
</svg>
As per usual the filter is applied to the dom element with some CSS:
<pre class="prettyprint">
<style type="text/css">
#someElement {
filter: url(#myfilter);
-webkit-filter: url(#myfilter);
}
</style>
</pre>
<style type="text/css">
#imgone263638936841005465 img {
filter: url(#one263638936841005465);
-webkit-filter: url(#one263638936841005465);
}
</style>
<div id="imgone263638936841005465">
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5W95NUwyoFw5JRc4KovRjjtFn2phFS1muexWmeMVtnmoUqKB8ZaNx8GbPkXwzf-FBBciEBjKgwmWtbqTMfv2aVn6g7Py_vvQPQbbZPxWmWa1KRffHaWwXvQIRJqg-imhJ7OaoMzHqmds/h120/dog1.jpg"/>
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirUSB_EIev8C1LFSu6D74rhXEy_2o66xjt9FJZmoQqvIyAUomOh0ID8J2zW_3L_yVLlI8ncI6geDspX0bNdI642OzNXbe5oKRzQv6D8VLzPCscAyAfIMm1pgJbJYJYRYJl3COPuyrw27I/h120/leit.jpg"/>
</div>
<h1>Triggering animations on hover (Firefox)</h1>
Unfortunately setting the begin attribute to mouseover or click does not work. This probably because the filter is not applied to an SVG image but an HTML DOM element.
<p/>
We will, therefore, need some Javascript to simulate a CSS3 Transition for an SVG filter. Looks like there is some problems with SVG filter animations in chrome, so this only works properly with <b>firefox</b>.
<p/>
JQuery has the very handy hover method to add the two event handlers. As implemented the hover transitions must be very short (0.5s or so). A cleaner implementation should check the actual position of the one animation to start the other. This would allow smoother transition with no jumps when the transition happens before the previous one ends.
<pre class="prettyprint">
$(function() { // on DOM ready register the events
$("#theItem").hover(function(event){
// stop the out event
$("#myfilter animate").get(1).endElement();
// start the in one
$("#myfilter animate").get(0).beginElement();
}, function(event){
$("#myfilter animate").get(0).endElement();
$("#myfilter animate").get(1).beginElement();
});
});
</pre>
The filter will need this time two animation with undefined begin and end times. An animated saturation filter would look like this:
<pre class="prettyprint">
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
<filter id="myfilter">
<feColorMatrix type="saturate" values="0">
<animate attributeName="values" attributeType="XML"
begin="<b>indefinite</b>" end="<b>indefinite</b>" dur="0.5s"
fill="freeze" from="0" to="1"/>
<animate attributeName="values" attributeType="XML"
begin="<b>indefinite</b>" end="<b>indefinite</b>" dur="0.5s"
fill="freeze" from="1" to="0"/>
</feColorMatrix>
</filter>
</svg>
</pre>
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
<filter id="two263638936841005465">
<feColorMatrix type="saturate" values="0">
<animate attributeName="values" attributeType="XML" begin="indefinite" end="indefinite" dur="0.5s" fill="freeze" from="0" to="1"/>
<animate attributeName="values" attributeType="XML" begin="indefinite" end="indefinite" dur="0.5s" fill="freeze" from="1" to="0"/>
</feColorMatrix>
</filter>
</svg>
<style type="text/css">
#imgwto263638936841005465 {
filter: url(#two263638936841005465);
-webkit-filter: url(#two263638936841005465);
}
</style>
<script type="text/javascript">
$(function() {
$("#imgwto263638936841005465").hover(function(event){
$("#two263638936841005465 animate").get(1).endElement();
$("#two263638936841005465 animate").get(0).beginElement();
}, function(event){
$("#two263638936841005465 animate").get(0).endElement();
$("#two263638936841005465 animate").get(1).beginElement();
});
});
</script>
On firefox moving the mouse over the image should add color to it.
<p/>
<img id="imgwto263638936841005465" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5W95NUwyoFw5JRc4KovRjjtFn2phFS1muexWmeMVtnmoUqKB8ZaNx8GbPkXwzf-FBBciEBjKgwmWtbqTMfv2aVn6g7Py_vvQPQbbZPxWmWa1KRffHaWwXvQIRJqg-imhJ7OaoMzHqmds/s150/dog1.jpg"/>
<h1>Chrome Vs. Firefox</h1>
With CSS3 SVG Filters firefox seams to work better. It appears to implement more stuff. I found three things where Chrome appears to have some problems:
<ul>
<li>Animating some of the filters, for instance the ColorMatrix's values attribute (but I'm not sure if it has to)</li>
<li>Support for some common attributes of SVG filters (result, X, Y, Width, Height)</li>
<li>Strangely, when called while handling some specific DOM event, the beginElement function will run the animation only the first time</li>
</ul>satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com1tag:blogger.com,1999:blog-1584392835174974542.post-33798832266204572712013-01-17T10:01:00.000+01:002013-11-04T22:55:12.411+01:00HTML5 Range Input Hack (Firefox)<b>UPDATE:</b> Firefox 23 added support for the input range
<p/>
Firefox does not implement the input type range yet. So here's a quick hack that creates a scrollbar for them. The code is implemented using <a href="http://jquery.com/">JQuery</a>. I'm sure there are plugins for JQuery that do this, but wanted to try my idea.
<p/><b>WARNING:</b> Did not test it much and the range input needs all attributes (min, max, step)
<p/>The idea is pretty simple.
For each input element with type range do the following:
<ol>
<li>Create a div of same size as the input and set its overflow attribute to scroll</li>
<li>Add a horizontally bigger element to this div</li>
<li>Add a scroll event listener to the div that will:
<ol>
<li>Compute the percentual of scroll</li>
<li>Scale that to the min, max and step values of the input range</li>
<li>Set the range value to the scale value</li>
<li>inform the input it changed</li>
</ol>
</li>
<li>Make the input invisible by setting its opacity to 0 and position it somewhere far away (left:-5000, top:-5000). Do NOT set the display value to none!</li>
</ol>
<pre class="prettyprint">
function makeRange(dummy, element) {
if ($.browser.mozilla) {
var width = $(element).width();
var minimum = +$(element).attr("min");
var maximum = +$(element).attr("max");
var step = $(element).attr("step");
var size = maximum - minimum;
var value = $(element).val();
// 1 and 2
var newDiv = $('<div style="overflow:scroll; display:inline-block;width:' + width + 'px; height:15px;">\
<div style="height:0px;width:' + (width * 4) + 'px">&nbsp;</div></div>');
newDiv.insertBefore($(element));
// scroll to initial value
newDiv.scrollLeft(width * 3 *((value - minimum) / size));
// 3
newDiv.scroll(function(e){
// 3.1
var width = $(this).children().first().width() - $(this).width();
var value = this.scrollLeft / width;
// 3.2
var size = maximum - minimum;
var fval = minimum + size * value;
var ival = Math.floor(fval / step) * step;
ival = ival.toFixed(Math.ceil(Math.abs(Math.log(step))));
// 3.3
$(element).val(ival);
// 3.4
$(element).trigger('change');
});
// 4
$(element).css("position","absolute");
$(element).css("opacity","0");
$(element).css("left", "-5000px");
$(element).css("top", "-5000px");
}
}
// call this when the Document is loaded
$(function(){
// for each input element of type range
$("input[type=range]").each(makeRange);
});
</pre>
If this method is used in a page where ranges are create dynamically in javascript, make sure to run it only on the newly created range. Otherwise you will end up with duplicate scrollbars on existing ranges.satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-31531953572902760842013-01-16T23:18:00.002+01:002013-01-17T10:17:04.668+01:00Miniature Effect with single SVG Filter (Firefox)<p/>In a previous attempt to create a <a href="http://satreth.blogspot.ch/2012/09/css3-firefox-miniature.html">minuature filter for firefox</a> I used multiple DIVs each showing a different level of blur. This works fine, especially if Webkit support is needed, but it is a little complicated to implement when needed multiple times.
<p/>When firefox support alone is ok, the whole effect can be implemented in one single SVG filter. We just have to combine the correct ones.
<p/>This new implementation uses merging of multiple filter steps. Currently this only works in <b>Firefox</b>.
The filter is:
<pre class="prettyprint">
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
<filter id="svgFilter3153195357290276084">
<feGaussianBlur y="0" height="100%" in="SourceGraphic" stdDeviation="8" result="b1"/>
<feGaussianBlur y="5%" height="90%" in="SourceGraphic" stdDeviation="7" result="b2"/>
<feGaussianBlur y="10%" height="80%" in="SourceGraphic" stdDeviation="6" result="b3"/>
<feGaussianBlur y="15%" height="70%" in="SourceGraphic" stdDeviation="5" result="b4"/>
<feGaussianBlur y="20%" height="60%" in="SourceGraphic" stdDeviation="4" result="b5"/>
<feGaussianBlur y="25%" height="50%" in="SourceGraphic" stdDeviation="3" result="b6"/>
<feGaussianBlur y="30%" height="40%" in="SourceGraphic" stdDeviation="2" result="b7"/>
<feGaussianBlur y="35%" height="30%" in="SourceGraphic" stdDeviation="1" result="b8"/>
<feGaussianBlur y="40%" height="20%" in="SourceGraphic" stdDeviation="0" result="b9"/>
<!-- the center needs to be unblurred (identity component transfer) -->
<feComponentTransfer x="0" y="45%" width="100%" height="10%" in="SourceGraphic" result="a"/>
<feMerge x="0" y="0" width="100%" height="100%" >
<feMergeNode in="SourceGraphic"/>
<feMergeNode in="b1"/>
<feMergeNode in="b2"/>
<feMergeNode in="b3"/>
<feMergeNode in="b4"/>
<feMergeNode in="b5"/>
<feMergeNode in="b6"/>
<feMergeNode in="b7"/>
<feMergeNode in="b8"/>
<feMergeNode in="b9"/>
<feMergeNode in="a"/>
</feMerge>
</filter>
</svg>
</pre>
<p/>In the first part of the filter a set of 8 gaussian blurs, of always smaller section of the source image, are created. In the second one, they are composed with the simple alpha composition.
<p/>As in the original post the filter is applied using CSS with something like:
<pre class="prettyprint">
img, video {
filter: url(#filterId);
}
</pre>
This time there is no need for a container DIV nor a positioning one. The filter can be applied to any DOM element.
<p/>
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
<filter id="svgFilter3153195357290276084">
<feGaussianBlur y="0" height="100%" in="SourceGraphic" stdDeviation="8" result="b1"/>
<feGaussianBlur y="5%" height="90%" in="SourceGraphic" stdDeviation="7" result="b2"/>
<feGaussianBlur y="10%" height="80%" in="SourceGraphic" stdDeviation="6" result="b3"/>
<feGaussianBlur y="15%" height="70%" in="SourceGraphic" stdDeviation="5" result="b4"/>
<feGaussianBlur y="20%" height="60%" in="SourceGraphic" stdDeviation="4" result="b5"/>
<feGaussianBlur y="25%" height="50%" in="SourceGraphic" stdDeviation="3" result="b6"/>
<feGaussianBlur y="30%" height="40%" in="SourceGraphic" stdDeviation="2" result="b7"/>
<feGaussianBlur y="35%" height="30%" in="SourceGraphic" stdDeviation="1" result="b8"/>
<feGaussianBlur y="40%" height="20%" in="SourceGraphic" stdDeviation="0" result="b9"/>
<feComponentTransfer x="0" y="45%" width="100%" height="10%" in="SourceGraphic" result="a">
</feComponentTransfer>
<feMerge x="0" y="0" width="100%" height="100%" >
<feMergeNode in="SourceGraphic"/>
<feMergeNode in="b1"/>
<feMergeNode in="b2"/>
<feMergeNode in="b3"/>
<feMergeNode in="b4"/>
<feMergeNode in="b5"/>
<feMergeNode in="b6"/>
<feMergeNode in="b7"/>
<feMergeNode in="b8"/>
<feMergeNode in="b9"/>
<feMergeNode in="a"/>
</feMerge>
</filter>
</svg>
<style type="text/css">
#myimg3153195357290276084 {
filter: url(#svgFilter3153195357290276084) ;
-webkit-filter: url(#svgFilter3153195357290276084) ;
}
</style>
<img id="myimg3153195357290276084" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirUSB_EIev8C1LFSu6D74rhXEy_2o66xjt9FJZmoQqvIyAUomOh0ID8J2zW_3L_yVLlI8ncI6geDspX0bNdI642OzNXbe5oKRzQv6D8VLzPCscAyAfIMm1pgJbJYJYRYJl3COPuyrw27I/s1600/leit.jpg"/>
satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-31516199078738981452012-12-24T00:52:00.002+01:002013-05-04T00:38:17.385+02:00CSS3 SVG Filters (1)<a href="http://www.w3.org/TR/filter-effects/">CSS3 Filters</a> (not to be confused with the, now deprecated, <a href="http://msdn.microsoft.com/en-us/library/ms532847(v=vs.85).aspx">Microsoft CSS filters</a>) are used to post-process the rendering of parts of the DOM.
They are still a Draft and might change in the future. However, firefox and webkit have already some implementations.
<p/>Filters are enabled on one or more DOM elements with the CSS property <code class="prettyprint">filter</code>. There are two quite different ways to implement filters. The more immediate one is by adding one or more filter directly in the CSS. The other is by specifying an URL to a <a href="http://www.w3.org/TR/SVG/filters.html">SVG filter</a>. This latter way is much more flexible and feature rich. It requires, however, that the browser supports SVG. Fortunately all major ones do so.
<h2>Example/Generator</h2>
In this example only some SVG filters are shown.
<script type="text/javascript">
var helper3151619907873898145 = {
"blur": {
"default": 0,
"update": function(value) {
$("#blur_svg3151619907873898145").get(0).setAttribute("stdDeviation", value);
$(".blur_svg3151619907873898145").html(value);
}
},
"saturate": {
"default" : 1,
"update": function(value) {
$("#saturate_svg3151619907873898145").attr("values", value);
$(".saturate_svg3151619907873898145").html(value);
}
},
"brightness": {
"default" : 0,
"update": function(value) {
var svgval = value;
$("#brightness_svg3151619907873898145").children().attr("slope", svgval);
$(".brightness_svg3151619907873898145").html(svgval);
}
},
"sepia": {
"default" : 0,
"update": function(value) {
var matrix = "";
matrix += (0.393 + 0.607 * (1 - value)) + " " + (0.769 - 0.769 * (1 - value)) + " " + (0.189 - 0.189 * (1 - value)) + " 0 0 ";
matrix += (0.349 - 0.349 * (1 - value)) + " " + (0.686 + 0.314 * (1 - value)) + " " + (0.168 - 0.168 * (1 - value)) + " 0 0 ";
matrix += (0.272 - 0.272 * (1 - value)) + " " + (0.534 - 0.534 * (1 - value)) + " " + (0.131 + 0.869 * (1 - value)) + " 0 0 ";
matrix += "0 0 0 1 0";
$("#sepia_svg3151619907873898145").attr("values", matrix);
$("#sepia_matrix_svg3151619907873898145").html(matrix);
$(".sepia_svg3151619907873898145").html(value);
}
},
"hue": {
"default" : 0,
"update": function(value) {
$("#hue_svg3151619907873898145").attr("values", value);
$(".hue_svg3151619907873898145").html(value);
}
}
};
function update3151619907873898145() {
var name = ("" + $(this).attr("id")).replace("3151619907873898145", "");
var effect = helper3151619907873898145[name];
var current_value = $("#" + name + "3151619907873898145").val();
try {
effect.update(current_value);
var blur = $("#blur3151619907873898145").val();
helper3151619907873898145["blur"].update(blur == 0 ? 1 : 0);
helper3151619907873898145["blur"].update(blur == 0 ? 0 : blur);
} catch(x) {
}
}
// register event listeners
$(function() {
$(".ui").change(update3151619907873898145);
});
</script>
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
<filter id="2svgFilter3151619907873898145">
<feMorphology operator="erode" in="SourceGraphic" radius="6" />
</filter>
<filter id="svgFilter3151619907873898145">
<feGaussianBlur id="blur_svg3151619907873898145" in="SourceGraphic" stdDeviation="0"/>
<feColorMatrix id="saturate_svg3151619907873898145" type="saturate" values="1"/>
<feComponentTransfer id="brightness_svg3151619907873898145">
<feFuncR type="linear" slope="1"/>
<feFuncG type="linear" slope="1"/>
<feFuncB type="linear" slope="1"/>
</feComponentTransfer>
<feColorMatrix type="matrix"
values="1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0" id="sepia_svg3151619907873898145"/>
<feColorMatrix id="hue_svg3151619907873898145" type="hueRotate" values="0"/>
</filter>
</svg>
<style type="text/css">
#myimg3151619907873898145 {
filter: url(#svgFilter3151619907873898145) ;
-webkit-filter: url(#svgFilter3151619907873898145) ;
}
</style>
<div><img id="myimg3151619907873898145" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5W95NUwyoFw5JRc4KovRjjtFn2phFS1muexWmeMVtnmoUqKB8ZaNx8GbPkXwzf-FBBciEBjKgwmWtbqTMfv2aVn6g7Py_vvQPQbbZPxWmWa1KRffHaWwXvQIRJqg-imhJ7OaoMzHqmds/s1600/dog1.jpg"/></div>
<p/>
<table>
<tr>
<th>Filter</th><th></th><th>Range</th>
</tr>
<tr>
<td>Blur:</td>
<td><input class="ui" type="range" id="blur3151619907873898145" min="0" max="10" value="0"/></td>
<td>Positive value (pixels)</td>
</tr>
<tr>
<td>Saturation:</td>
<td><input class="ui" type="range" id="saturate3151619907873898145" min="0" max="1" step="0.1" value="1"/></td>
<td>Between 0 and 1</td>
</tr>
<tr>
<td>Brightness:</td>
<td><input class="ui" type="range" id="brightness3151619907873898145" min="0" max="10" step="0.1" value="1"/></td>
<td>Positive</td>
</tr>
<tr>
<td>Sepia:</td>
<td><input class="ui" type="range" id="sepia3151619907873898145" min="0" max="1" step="0.1" value="0"/></td>
<td>Positive</td>
</tr>
<tr>
<td>Hue Rotation:</td>
<td><input class="ui" type="range" id="hue3151619907873898145" min="-180" max="180" value="0"/></td>
<td>Any number of degrees</td>
</tr>
</table>
<h3>CSS</h3>
<pre class="prettyprint">
#element {
filter: url(#<b>myfilter</b>);
-webkit-filter: url(#<b>myfilter</b>);
}
</pre>
<h3>HTML</h3>
Somehwere in the HTML code we have to place this SVG tag. Since it's size is 0x0 it should not affect the rendering of the page.
The only child of this SVG is the filter we set in the CSS (myfilter).
<pre class="prettyprint">
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
<filter id="<b>myfilter</b>">
<!-- Blur -->
<feGaussianBlur in="SourceGraphic" stdDeviation="<span class="blur_svg3151619907873898145">1</span>"/>
<!-- Saturation -->
<feColorMatrix type="saturate" values="<span class="saturate_svg3151619907873898145">1</span>"/>
<!-- Brightness -->
<feComponentTransfer>
<feFuncR type="linear" slope="<span class="brightness_svg3151619907873898145">1</span>"/>
<feFuncG type="linear" slope="<span class="brightness_svg3151619907873898145">1</span>"/>
<feFuncB type="linear" slope="<span class="brightness_svg3151619907873898145">1</span>"/>
</feComponentTransfer>
<!-- Sepia (with color matrix:
(0.393+0.607*[1-<span class="sepia_svg3151619907873898145">0</span>]) (0.769-0.769*[1-<span class="sepia_svg3151619907873898145">0</span>]) (0.189-0.189*[1-<span class="sepia_svg3151619907873898145">0</span>]) 0 0
(0.349-0.349*[1-<span class="sepia_svg3151619907873898145">0</span>]) (0.686+0.314*[1-<span class="sepia_svg3151619907873898145">0</span>]) (0.168-0.168*[1-<span class="sepia_svg3151619907873898145">0</span>]) 0 0
(0.272-0.272*[1-<span class="sepia_svg3151619907873898145">0</span>]) (0.534-0.534*[1-<span class="sepia_svg3151619907873898145">0</span>]) (0.131+0.869*[1-<span class="sepia_svg3151619907873898145">0</span>]) 0 0
0 0 0 1 0
-->
<feColorMatrix type="matrix"
values="<span id="sepia_matrix_svg3151619907873898145">1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0</span>"/>
<!-- Hue Rotation -->
<feColorMatrix type="hueRotate" values=" <span class="hue_svg3151619907873898145">0</span>"/>
</filter>
</svg>
</pre>
<h2>Chrome Problems</h2>
While implementing the scripts of this post I encountered a problem with chrome. When changing some of the filters by modifying the DOM with javascript the image was not updated. I noticed however that
when the blur was changed, the filter was applied. A quick workaround was, therefore, to change the blur and set it back at each value change.
<p/>
A probably better solution to the problem is to remove and re-add the filter.
satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-18976847186055168692012-11-12T23:58:00.002+01:002015-05-13T16:23:09.718+02:00Java SnippetsJust some code snippets that I found useful. Not necessarily the best or fastest solutions.
<h1>Generics</h1>
<h2>Return Types</h2>
To get the compiler to understand a generic return type, simply add a dummy class parameter.
<pre class="prettyprint lang-java">
public static <A> A someMethod(Class<A> dummy) {
}
// calling the method
someMethod(Double.class);
</pre>
<h1>Collections</h1>
<h2>Single Element List</h2>
Create a list of one single element.
<pre class="prettyprint lang-java">
Arrays.asList(element);
</pre>
<h2>Iterable Iterator</h2>
Looping over an iteartor with a foreach is not possible. An Iterable is needed.
<pre class="prettyprint lang-java">
/**
* Put this method in a Utility class. It can then be imported as class
* or statically.
*/
public static <T> Iterable<T> toIterable(final Iterator<T> the_iterator) {
return new Iterable<T>() {
public Iterator<T> iterator() {
return the_iterator;
}
};
}
...
for(T t : toIterable(an_iterator)) {
// do something
}
</pre>
<h2>Foreach on XML NodeList elements</h2>
Creating simple Iterable will allow us to iterate over NodeLists
<pre class="prettyprint lang-java">
Iterable<Element> toIterable(final NodeList list) {
return new Iterable<Element>() {
@Override public Iterator<Element> iterator() {
return new Iterator<Element>() {
int position = 0;
@Override public void remove() {
throw new UnsupportedOperationException();
}
@Override public Element next() {
if (!hasNext()) throw new NoSuchElementException();
return (Element) list.item(position++);
}
@Override public boolean hasNext() {
// move to next
while(position < list.getLength() && !(list.item(position) instanceof Element)) ++position;
return position < list.getLength();
}
};
}
};
}
// used
Element someElement = ...;
for (Element child : toIterable(someElement.getChildNodes()) {
/// TODO something
}
</pre>
<h1>Loops</h1>
<h2>Multiple nested loops break</h2>
<pre class="prettyprint">
// given a matrix of size n x k
// we want to know if it contains a value greater than <em>val</em>
double val = 1;
boolean found = false;
<b>label:</b> for(int i = 0; i < n; ++i) {
for(int j = 0; j < k; ++j) {
if (matrix[i][j] > val) {
found = true;
break <b>label</b>; // get out of both for loops
}
}
}
</pre>
Note: this post might grow in timesatrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-55097122009796455652012-09-15T01:00:00.000+02:002013-02-21T00:07:42.082+01:00CSS3 Miniature Effect
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
<filter id="svg1Blur5509712200979645565">
<feGaussianBlur in="SourceGraphic" stdDeviation="5"/>
</filter>
<filter id="svg2Blur5509712200979645565">
<feGaussianBlur in="SourceGraphic" stdDeviation="4"/>
</filter>
<filter id="svg3Blur5509712200979645565">
<feGaussianBlur in="SourceGraphic" stdDeviation="3"/>
</filter>
<filter id="svg4Blur5509712200979645565">
<feGaussianBlur in="SourceGraphic" stdDeviation="2"/>
</filter>
<filter id="svg5Blur5509712200979645565">
<feGaussianBlur in="SourceGraphic" stdDeviation="1"/>
</filter>
</svg>
<style type="text/css">
.image5509712200979645565 {
background: url("https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirUSB_EIev8C1LFSu6D74rhXEy_2o66xjt9FJZmoQqvIyAUomOh0ID8J2zW_3L_yVLlI8ncI6geDspX0bNdI642OzNXbe5oKRzQv6D8VLzPCscAyAfIMm1pgJbJYJYRYJl3COPuyrw27I/s1600/leit.jpg");
position: absolute;
width: 447px;
}
.shadow5509712200979645565 {
-webkit-box-shadow: 3px 3px 8px black;
-o-box-shadow: 3px 3px 8px black;
-ms-box-shadow: 3px 3px 8px black;
-moz-box-shadow: 3px 3px 8px black;
box-shadow: 3px 3px 8px black;
}
.borderfix5509712200979645565 {
-webkit-box-shadow: 3px 3px 8px black;
-o-box-shadow: 3px 3px 8px black;
-ms-box-shadow: 3px 3px 8px black;
-moz-box-shadow: 3px 3px 8px black;
box-shadow: 3px 3px 8px black;
margin: 20px auto;
height: 305px;
width:427px;
overflow: hidden;
border: solid 10px white;
}
.miniature5509712200979645565 {
margin: -10px;
position: relative;
height: 325px;
width:447px;
}
.one5509712200979645565 {
height: 325px;
z-index:1;
background-position: 0px 0px;
filter: url(#svg1Blur5509712200979645565);
-webkit-filter: blur(5px);
}
.two5509712200979645565 {
height: 275px;
top: 25px;
background-position: 0px -25px;
filter: url(#svg2Blur5509712200979645565);
-webkit-filter: blur(4px);
z-index:2;
}
.three5509712200979645565 {
height: 225px;
top: 50px;
background-position: 0px -50px;
filter: url(#svg3Blur5509712200979645565);
-webkit-filter: blur(3px);
z-index:3;
}
.four5509712200979645565 {
height: 175px;
top: 75px;
background-position: 0px -75px;
filter: url(#svg4Blur5509712200979645565);
-webkit-filter: blur(2px);
z-index:4;
}
.five5509712200979645565 {
height: 125px;
top: 100px;
background-position: 0px -100px;
filter: url(#svg5Blur5509712200979645565);
z-index:5;
-webkit-filter: blur(1px);
}
.six5509712200979645565 {
height: 75px;
top: 125px;
background-position: 0px -125px;
z-index:6;
}
</style>
<h2>Miniature effect</h2>
<p/>
It has been implemented using 6 divs stacked one on top of the other using css. The higher the z-index, the narrower and less blurred it is. The blur is applied using <a href="https://developer.mozilla.org/en-US/docs/Applying_SVG_effects_to_HTML_content">SVG filters</a>.
<p/>
The six layers are splitting the picture in 13 stripes. The mid one is not blurred.
<div class="borderfix5509712200979645565">
<div class="miniature5509712200979645565">
<div class="image5509712200979645565 one5509712200979645565"></div>
<div class="image5509712200979645565 two5509712200979645565"></div>
<div class="image5509712200979645565 three5509712200979645565"></div>
<div class="image5509712200979645565 four5509712200979645565"></div>
<div class="image5509712200979645565 five5509712200979645565"></div>
<div class="image5509712200979645565 six5509712200979645565"></div>
</div>
</div>
<P/> The original picture is:
<div class="borderfix5509712200979645565">
<div class="miniature5509712200979645565">
<img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirUSB_EIev8C1LFSu6D74rhXEy_2o66xjt9FJZmoQqvIyAUomOh0ID8J2zW_3L_yVLlI8ncI6geDspX0bNdI642OzNXbe5oKRzQv6D8VLzPCscAyAfIMm1pgJbJYJYRYJl3COPuyrw27I/s1600/leit.jpg" />
</div>
</div>
<h2>The code</h2>
<div class="shadow5509712200979645565" style="margin: 0px 10px 10px 10px; padding: 10px; float: right; position: relative; width: 200px; height: 130px;">
<div style="background-color: #aaa;border: solid 1px silver; margin: 3px;top: 0px; left:0px; right: 0px; bottom: 0px; position: absolute;">
<div style="padding: 0px 5px; left: 0px; right: 0px; position: absolute; top: 0px;">Layer 1</div>
<div style="padding: 0px 5px; left: 0px; right: 0px; position: absolute; bottom: 0px;">Lots of Blur</div>
<div style="background-color: #ccc;border: solid 1px silver; margin: 3px; left: 0px; right: 0px; position: absolute; top: 20px; bottom: 20px">
<div style="padding: 0px 5px; left: 0px; right: 0px; position: absolute; top: 0px;">Layer 2</div>
<div style="padding: 0px 5px; left: 0px; right: 0px; position: absolute; bottom: 0px;">Little Blur</div>
<div style="background-color: #eee;padding: 0px 5px; border: solid 1px silver; margin: 3px; left: 0px; right: 0px; position: absolute; top: 20px; bottom: 20px">Layer 3
<div style="padding: 0px 5px; left: 0px; right: 0px; position: absolute; bottom: 0px;">No Blur</div>
</div>
</div>
</div>
</div>
As explained earlier the effect consists of 6 div tags stacked, blurred and sized with css. This layers are enclosed in two more divs. One for the positioning and the outer one to clip and add the border.
On the right an example is shown on how the layers are stacked and sized (only 3 layers shown).
<p/>
Blurring is obtained by applying an SVG filter to the HTML content via the CSS filters. SVG filters can be embedded in the HTML page, but should be without the namespace (not valid XML).
For convenience only two of the 5 filters are shown.
<pre class="prettyprint">
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg">
<filter id="blur5">
<feGaussianBlur in="SourceGraphic" stdDeviation="5"/>
</filter>
<filter id="blur4">
<feGaussianBlur in="SourceGraphic" stdDeviation="4"/>
</filter>
...
</svg>
</pre>
In HTML the 6 layers look like the following:
<pre class="prettyprint">
<div class='border'>
<div class='positioning'>
<div class='layer1'></div>
<div class='layer2'></div>
<div class='layer3'></div>
<div class='layer4'></div>
<div class='layer5'></div>
<div class='layer6'></div>
</div>
</div>
</pre>
<p/>
The picture used in the example is 447 pixel wide and 325 pixel high. We want the central layer to be of half the hight of the visible part of the other layers. This will give us 13 horizontal slices of the original picture. Each slice is 25 pixel high (325/13).
<pre class="prettyprint">
.positioning > div {
background: url("https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirUSB_EIev8C1LFSu6D74rhXEy_2o66xjt9FJZmoQqvIyAUomOh0ID8J2zW_3L_yVLlI8ncI6geDspX0bNdI642OzNXbe5oKRzQv6D8VLzPCscAyAfIMm1pgJbJYJYRYJl3COPuyrw27I/s1600/leit.jpg");
position: absolute;
width: 447px; /* this is the width of the picture */
left: 0px;
}
.positioning {
/* we shift the picture to cut 10px away (see border) */
margin: -10px;
position: relative;
height: 325px;
width: 447px;
}
.border {
/* cut away a 10px border by making div smaller */
overflow: hidden;
height: 305px;
width: 427px;
}
.layer1 {
/* inherited position absolute from .positioning > div */
z-index:1;
top: 0px;
bottom: 0px;
background-position: 0px -100px;
filter: url(#blur5);
-webkit-filter: blur(5px);
}
.layer2 {
z-index:2;
top: 25px; bottom: 25px;
/* align background images */
background-position: 0px -25px;
filter: url(#blur4);
-webkit-filter: blur(4px);
}
.layer3 {
z-index:3;
top: 50px; bottom: 50px;
background-position: 0px -50px;
filter: url(#blur3);
-webkit-filter: blur(3px);
}
.layer4 {
z-index:5;
top: 75px; bottom: 75px;
background-position: 0px -75px;
filter: url(#blur2);
-webkit-filter: blur(2px);
}
.layer5 {
z-index:5;
top: 100px; bottom: 100px;
background-position: 0px -100px;
filter: url(#blur1);
-webkit-filter: blur(1px);
}
.layer6 {
z-index:6;
top: 125px; bottom: 125px;
background-position: 0px -125px;
/* no blur */
}
</pre>
<p/>
And that's it. Not all pictures give a nice result with this effect. It is out of the scope of this post to address the selection of good pictures for the miniature effect.
<p/><b>UPDATE</b>: <a href="http://satreth.blogspot.ch/2013/01/css3-miniature-with-single-filter.html">Single filter implementation</a> that does not need any additional divs (Only firefox)satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-704711483792524782012-06-19T23:00:00.000+02:002012-07-17T11:53:19.679+02:00CSS UnitsCSS defines a lot of units for different type of measures. Here a few examples and some explanations. The interactive parts should work on Firefox and webkit (where applicable), did not test on IE and Opera.
<h1>Length units</h1>
<h2>Absolute</h2>
The main absolute length (size) unit, when working for the screen, is the pixel (<code class="prettyprint lang-css">px</code>).
<p/>
CSS defines also some other absolute length units. These are more useful for print, but can be used also on a display (discouraged). The discouraging holds also the other way around: px should be used with care when printing.
<style type="text/css">
.info70471148379252478 {
display: none;
}
div.info70471148379252478 dt {
float: left;
width: 20%;
}
div.info70471148379252478 dd {
width: 80%;
}
.block70471148379252478 {
margin-top: 3px;
background-color: darkgrey;
height: 1em;
}
div.abs70471148379252478 > input:checked + div > .block70471148379252478 {
background-color: blue;
}
.abs70471148379252478 input:checked + div > div.info70471148379252478 {
display: block;
position: absolute;
padding-left: 20px;
left: 50%;
top: 0px;
bottom: 0px;
right:0px;
}
div.abs70471148379252478 div span {
display: inline-block;
width: 50px;
}
div.abs70471148379252478 > div {
width: 50%;
padding-left: 30px;
}
div.abs70471148379252478 > input:checked + div,
div.abs70471148379252478 > input:checked + div > .info70471148379252478 {
background-color:#FABC02;
}
div.abs70471148379252478 > input {
position: absolute;
}
</style>
<div class="block abs70471148379252478" style="position:relative;">
<input type='radio' name='unit70471148379252478'/>
<div>
<div class="info70471148379252478">
<dl>
<dt>pt</dt><dd>3/4</dd>
<dt>mm</dt><dd>25.4/96</dd>
<dt>pc</dt><dd>1/16</dd>
<dt>cm</dt><dd>2.54/96</dd>
<dt>in</dt><dd>1/96</dd>
</dl>
</div>
<span>1px</span>
<span class="block70471148379252478" style="width: 1px;"></span>
</div>
<input type='radio' name='unit70471148379252478'/>
<div>
<div class="info70471148379252478">
<dl>
<dt>px</dt><dd>4/3</dd>
<dt>mm</dt><dd>25.4/72</dd>
<dt>pc</dt><dd>1/12</dd>
<dt>cm</dt><dd>2.54/72</dd>
<dt>in</dt><dd>1/72</dd>
</dl>
</div>
<span>1pt</span>
<span class="block70471148379252478" style="width: 1pt"></span>
</div>
<input type='radio' name='unit70471148379252478'/>
<div>
<div class="info70471148379252478">
<dl>
<dt>px</dt><dd>96/25.4</dd>
<dt>pt</dt><dd>72/25.4</dd>
<dt>pc</dt><dd>6/25.4</dd>
<dt>cm</dt><dd>0.1</dd>
<dt>in</dt><dd>10/2.54</dd>
</dl>
</div>
<span>1mm</span>
<span class="block70471148379252478" style="width: 1mm"></span>
</div>
<input type='radio' name='unit70471148379252478'/>
<div>
<div class="info70471148379252478">
<dl>
<dt>px</dt><dd>16</dd>
<dt>pt</dt><dd>12</dd>
<dt>mm</dt><dd>25.4/6</dd>
<dt>cm</dt><dd>2.54/6</dd>
<dt>in</dt><dd>1/6</dd>
</dl>
</div>
<span>1pc</span>
<span class="block70471148379252478" style="width: 1pc"></span>
</div>
<input type='radio' name='unit70471148379252478'/>
<div>
<div class="info70471148379252478">
<dl>
<dt>px</dt><dd>96/2.54</dd>
<dt>pt</dt><dd>72/2.54</dd>
<dt>mm</dt><dd>10</dd>
<dt>pc</dt><dd>6/2.54</dd>
<dt>in</dt><dd>1/2.54</dd>
</dl>
</div>
<span>1cm</span>
<span class="block70471148379252478" style="width: 1cm"></span>
</div>
<input type='radio' name='unit70471148379252478'/>
<div>
<div class="info70471148379252478">
<dl>
<dt>px</dt><dd>72</dd>
<dt>pt</dt><dd>96</dd>
<dt>mm</dt><dd>25.4</dd>
<dt>pc</dt><dd>6</dd>
<dt>cm</dt><dd>2.54</dd>
</dl>
</div>
<span>1in</span>
<span class="block70471148379252478" style="width: 1in"></span>
</div>
</div>
<p/>
<h2>Font Relative</h2>
<p/>
<div style="margin-right: 20px; margin-bottom: 20px; position: relative; float: left; width: 250px; height: 2em; font-size: 110px;padding:20px 0px 0px 0px;font-family: arial" class="block">
<div style="line-height: 1; position: absolute; bottom: 0px; left: 95px; width: 100px; height: 2em">0.<br/>x</div>
<div style="position: absolute; bottom: 16px; left: 170px; width: 2px; border-right: 1px solid silver; border-top: 1px solid silver; border-bottom: 1px solid silver; height: 1ex;"></div>
<div style="position: absolute; bottom: 16px; left: 80px; width: 2px; border-left: 1px solid silver; border-top: 1px solid silver; border-bottom: 1px solid silver; height: 1em;"></div>
<div style="position: absolute; top: 26px; left: 95px; width: 1ch; border-left: 1px solid silver; border-top: 1px solid silver; border-right: 1px solid silver; height: 20px"></div>
<div style="position: absolute; bottom: 30px; left: 180px; width: 22px; font-size:20px;">1ex</div>
<div style="position: absolute; bottom: 65px; left: 30px; width: 22px; font-size:20px;">1em</div>
<div style="position: absolute; top: 0px; left: 105px; width: 100px; font-size:20px;">1ch</div>
</div>
All major browsers support at least two font relative units: <code class="prettyprint lang-css">em</code> and <code class="prettyprint lang-css">ex</code>. As the "image" on the side shows, the <code class="prettyprint lang-css">em</code> is the total font height while the <code class="prettyprint lang-css">ex</code> is usually the height of the x character (one exception is when the font doesn't have the letter x). The font that is used for this sizes is the one applied to the tag (therefore the inherited one if none is explicitly specified).
<p/>
Another font relative measure of units is the <code class="prettyprint lang-css">rem</code>. The rem (root em) is the same as the normal em but related to the root element.
<p/>
And there is also <code class="prettyprint lang-css">ch</code>. This last font related unit is the advancement of the character '0' (zero) of the current font. In fonts that are not monospaced the advancement of a character depends of the character (see below).
<style type="text/css">
.chexample70471148379252478 .even70471148379252478 {
-moz-transition: margin-top 1s, height 1s, border-color 1s;
-o-transition: margin-top 1s, height 1s, border-color 1s;
-ms-transition: margin-top 1s, height 1s, border-color 1s;
-webkit-transition: margin-top 1s, height 1s, border-color 1s;
transition: margin-top 1s, height 1s, border-color 1s;
margin-right: -2px; margin-top: 0px; width: 1ch; border-left: 2px silver solid; height: 10px;float:left;
}
.chexample70471148379252478:hover .even70471148379252478 {
margin-top: -30px;
height: 40px;
border-color: green;
}
.chexample70471148379252478:hover .even70471148379252478.red70471148379252478 {
border-color: red;
}
.chexample70471148379252478 {
font-size: 30px; position:relative;
padding: 20px;
}
</style>
<div style="clear: both"></div>
<div class="block chexample70471148379252478">
<div>00000mmmm</div>
<div class="even70471148379252478"></div>
<div class="even70471148379252478"></div>
<div class="even70471148379252478"></div>
<div class="even70471148379252478"></div>
<div class="even70471148379252478"></div>
<div class="even70471148379252478"></div>
<div class="even70471148379252478 red70471148379252478"></div>
<div class="even70471148379252478 red70471148379252478"></div>
<div class="even70471148379252478 red70471148379252478"></div>
<div class="even70471148379252478 red70471148379252478"></div>
<div style="clear:both"></div>
</div>
<p/>
The <code class="prettyprint lang-css">ch</code> unit is currently (June 2012) not supported by webkit browsers.
<h2>Viewport relative</h2>
CSS3 introduces also viewport relative units: vh, vw and vmin.
<div class="block">
1vh = 1% of the height of the initial viewport<br/>
1vw = 1% of the width of the initial viewport<br/>
1vmin = 1% of the smallest between width and height of viewport
</div>
<h2>Percent</h2>
One more unit is the percent. Percents are relative to something. In the case of fonts they are related to the parent. For lengths (for instance: width and top), the percent, is related to the size of the first positioned element, or when none, to the size of the whole document.
<h1>Rotation Units</h1>
Rotation units are used, for instance, in transformations and radial gradients.
<style type="text/css">
.animate70471148379252478 {
position: relative;
height: 200px;
padding-top: 20px;
}
.txt70471148379252478 {
-moz-transition: -moz-transform 1s;
-moz-transform: rotate(0deg);
-webkit-transition: -webkit-transform 1s;
-webkit-transform: rotate(0deg);
transition: transform 1s;
transform: rotate(0deg);
background-color: white;
-moz-box-shadow: 2px 2px 5px black;
-webkit-box-shadow: 2px 2px 5px black;
-ms-box-shadow: 2px 2px 5px black;
-o-box-shadow: 2px 2px 5px black;
box-shadow: 2px 2px 5px black;
padding: 10px;
}
.turn70471148379252478:hover ~ .txt70471148379252478 {
-moz-transform: rotate(1turn);
-webkit-transform: rotate(1turn);
transform: rotate(1turn);
}
.deg70471148379252478:hover ~ .txt70471148379252478 {
-moz-transform: rotate(10deg);
-webkit-transform: rotate(10deg);
transform: rotate(10deg);
}
.rad70471148379252478:hover ~ .txt70471148379252478 {
-moz-transform: rotate(1rad);
-webkit-transform: rotate(1rad);
transform: rotate(1rad);
}
.grad70471148379252478:hover ~ .txt70471148379252478 {
-moz-transform: rotate(10grad);
-webkit-transform: rotate(10grad);
transform: rotate(10grad);
}
.txt70471148379252478 {
position: absolute;
width: 150px;
height: 100px;
border: solid 1px silver;
left: 330px;
top:20px;
}
.animate70471148379252478 > .r70471148379252478 {
padding: 5px 0px;
}
.animate70471148379252478 > .r70471148379252478:hover {
background-color: silver;
}
.txt70471148379252478 > .r70471148379252478 {
-moz-transition: opacity 1s;
-webkit-transition: opacity 1s;
-ms-transition: opacity 1s;
-o-transition: opacity 1s;
transition: opacity 1s;
opacity: 0;
position: absolute;
top: 10px;
left: 10px;
}
.txt70471148379252478 > .default70471148379252478 {
-moz-transition: opacity 1s;
-webkit-transition: opacity 1s;
-ms-transition: opacity 1s;
opacity: 1;
position: absolute;
top: 10px;
left: 10px;
right:10px;
}
.r70471148379252478:hover ~ .txt70471148379252478 > .default70471148379252478 {
opacity: 0;
}
.turn70471148379252478:hover ~ .txt70471148379252478 > .turn70471148379252478 {
opacity: 1;
}
.deg70471148379252478:hover ~ .txt70471148379252478 > .deg70471148379252478 {
opacity: 1;
}
.rad70471148379252478:hover ~ .txt70471148379252478 > .rad70471148379252478 {
opacity: 1;
}
.grad70471148379252478:hover ~ .txt70471148379252478 > .grad70471148379252478{
opacity: 1;
}
</style>
<div class="animate70471148379252478">
<div class="turn70471148379252478 r70471148379252478">1turn</div>
<div class="rad70471148379252478 r70471148379252478">1rad</div>
<div class="deg70471148379252478 r70471148379252478">10deg</div>
<div class="grad70471148379252478 r70471148379252478">10grad</div>
<div class="txt70471148379252478">
<div class="r70471148379252478 turn70471148379252478"><div>1 turn equals</div><div>2π rad</div><div>360 deg</div><div>400 grad</div>
</div>
<div class="r70471148379252478 rad70471148379252478"><div>1 rad equals</div><div>1/2π turns</div><div>180/π deg</div><div>200/π grad</div>
</div>
<div class="r70471148379252478 deg70471148379252478"><div>1 deg equals</div><div>1/360 turns</div><div>π/180 rad</div><div>9/10 grad</div>
</div>
<div class="r70471148379252478 grad70471148379252478"><div>1 grad equals</div><div>1/400 turns</div><div>π/200 rad</div><div>10/9 deg</div>
</div>
<div class="default70471148379252478">Move the mouse over the units on the left</div>
</div>
</div>
<h1>Other units</h1>
CSS defines also units for pixel density, time (s, ms), frequencies (hz, khz), color, etc. I will not cover them here since quite trivial (time and frequencies) or enough complex to deserve a separate post (color, densities).
<h1>Mixing Units</h1>
Finally, there is another very nice feature that plays a role here. Let's assume we are using an element that has width of 50% wide and has a border of 10px. What if we want to place beneath it another element with same width but no border. Setting a width of 50% would make it 20px to narrow (2 borders of 10px) and the actual width depends on the size of the container. Fortunately CSS3 can perform computation. We can set the width of the second element to "calc(50% + 20px)".
<div class="block">
<div style="background-color: silver; width:50%; border: 10px solid">width:50%; + 2x 10px border</div>
<div style="background-color: red; width:50%;">width:50%</div>
<div style="background-color: green; color: #efe; width:-moz-calc(50% + 20px);width:-webkit-calc(50% + 20px);width:calc(50% + 20px);">width: calc(50% + 20px)</div>
</div>
<p/>
The source code (without background colors) for the example above is
<pre class="prettyprint lang-html">
<div style="<b>width:50%;</b> border:<b>10px</b> solid">width:50%; + 2x 10px border</div>
<div style="<b>width:50%;</b>">width:50%</div>
<div style="<b>width:-moz-calc(50% + 20px); width:-webkit-calc(50% + 20px); width:calc(50% + 20px);</b>">width: calc(50% + 20px)</div>
</pre>
<h1>Further reading</h1>
You can get some more information about units here:
<p/>
<a href="http://www.w3.org/TR/css3-values">http://www.w3.org/TR/css3-values</a><br/>
<a href="https://developer.mozilla.org/en/CSS/length">https://developer.mozilla.org/en/CSS/length</a><br/>satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-62887955516166241522012-06-08T22:43:00.001+02:002012-06-12T11:34:03.836+02:00CSS3 Layout - columns<style type="text/css">
.playground6288795551616624152 {
margin-top: 20px;
}
.text6288795551616624152{
padding: 20px;
}
#two6288795551616624152:checked ~ .text6288795551616624152 {
-moz-column-count:2;
-webkit-column-count:2;
column-count:2;
}
#three6288795551616624152:checked ~ .text6288795551616624152 {
-moz-column-count:3;
-webkit-column-count:3;
column-count:3;
}
#width6288795551616624152:checked ~ .text6288795551616624152 {
-moz-column-width:100px;
-webkit-column-width:100px;
column-width:100px;
}
#narrowgap6288795551616624152:checked ~ .text6288795551616624152 {
-moz-column-gap:0px;
-webkit-column-gap:0px;
column-gap:0px;
}
#defaultgap6288795551616624152:checked ~ .text6288795551616624152 {
}
#widegap6288795551616624152:checked ~ .text6288795551616624152 {
-moz-column-gap:4em;
-webkit-column-gap:4em;
column-gap:4em;
}
#line6288795551616624152:checked ~ .text6288795551616624152 {
-moz-column-rule: solid black 1px;
-webkit-column-rule: solid black 1px;
column-rule: solid black 1px;
}
#span6288795551616624152:checked ~ .text6288795551616624152 #pre6288795551616624152 {
-moz-column-span: all;
-webkit-column-span: all;
column-column-span: all;
}
#bbefore6288795551616624152:checked ~ .text6288795551616624152 p:first-of-type {
-moz-column-break-before: always;
-webkit-column-break-before: always;
break-before: column;
}
#bafter6288795551616624152:checked ~ .text6288795551616624152 p:first-of-type {
-moz-column-break-after: always;
-webkit-column-break-after: always;
break-after: column;
}
.source6288795551616624152{ display:none; }
#bbefore6288795551616624152:checked ~ pre .bbefore6288795551616624152source,
#bbefore6288795551616624152:checked ~ pre .break6288795551616624152source,
#bafter6288795551616624152:checked ~ pre .bafter6288795551616624152source,
#bafter6288795551616624152:checked ~ pre .break6288795551616624152source,
#span6288795551616624152:checked ~ pre .span6288795551616624152source,
#line6288795551616624152:checked ~ pre .line6288795551616624152source,
#two6288795551616624152:checked ~ pre .two6288795551616624152source,
#three6288795551616624152:checked ~ pre .three6288795551616624152source,
#widegap6288795551616624152:checked ~ pre .widegap6288795551616624152source,
#narrowgap6288795551616624152:checked ~ pre .narrowgap6288795551616624152source,
#width6288795551616624152:checked ~ pre .width6288795551616624152source {
display: inline !important;
}
</style>
With CSS3 multi column (<a href="http://www.w3.org/TR/css3-multicol">http://www.w3.org/TR/css3-multicol</a>) you can create content that is organized in columns without having to split it yourself or use a javascript library to do it for you. You simply have to set the <code class="prettyprint lang-css">column-count</code> or the <code class="prettyprint lang-css">column-width</code> parameter of a tag and it's content will be shown in columns. Firefox and Webkit based browsers require the vendor prefix. The details of the columns can be controlled with various other parameters. These include setting the width of each column, the gap between the columns and a separator line.
<p/>
Firefox does not fully implement columns. The support is limited to splitting content, but the flow control (column brake and span) is not yet implemented.
<p/>
<h1>Example</h1>
<div class="playground6288795551616624152">
<label for="line6288795551616624152">Show line: </label><input type="checkbox" id="line6288795551616624152" name="line6288795551616624152"/>
<br/>
Columns: <input type="radio" checked="checked" id="two6288795551616624152" name="count6288795551616624152"/> 2, <input type="radio" id="three6288795551616624152" name="count6288795551616624152"/> 3, <input type="radio" id="width6288795551616624152" name="count6288795551616624152"/> 100px
<br/>
Gap: <input type="radio" id="narrowgap6288795551616624152" name="gap6288795551616624152"/> none, <input type="radio" id="defaultgap6288795551616624152" checked="checked" name="gap6288795551616624152"/> default,
<input type="radio" id="widegap6288795551616624152" name="gap6288795551616624152"/> wide
<br/>
<label for="span6288795551616624152">Make block span over columns: </label><input type="checkbox" id="span6288795551616624152" name="span6288795551616624152"/> (not supported by firefox)
<br/>
<label for="bbefore6288795551616624152">Break before first paragraph: </label><input type="checkbox" id="bbefore6288795551616624152" name="bbefore6288795551616624152"/>
<br/>
<label for="bafter6288795551616624152">Break after first paragraph: </label><input type="checkbox" id="bafter6288795551616624152" name="bafter6288795551616624152"/>
<p/>
<h2>Result</h2>
<div class="text6288795551616624152">
<pre class="prettyprint" id="pre6288795551616624152">/* a block of something */</pre>
<p>Here some text from Wikipedia's css page: Cascading Style Sheets (CSS) is a style sheet language used for describing the presentation semantics (the look and formatting) of a document written in a markup language. Its most common application is to style web pages written in HTML and XHTML, but the language can also be applied to any kind of XML document, including plain XML, SVG and XUL.</p>
<p>CSS is designed primarily to enable the separation of document content (written in HTML or a similar markup language) from document presentation, including elements such as the layout, colors, and fonts. This separation can improve content accessibility, provide more flexibility and control in the specification of presentation characteristics, enable multiple pages to share formatting, and reduce complexity and repetition in the structural content (such as by allowing for tableless web design).
CSS can also allow the same markup page to be presented in different styles for different rendering methods, such as on-screen, in print, by voice (when read out by a speech-based browser or screen reader) and on Braille-based, tactile devices. It can also be used to allow the web page to display differently depending on the screen size or device on which it is being viewed. While the author of a document typically links that document to a CSS style sheet, readers can use a different style sheet, perhaps one on their own computer, to override the one the author has specified.
</p></div>
<p/>
<h2>code</h2>
<pre class="prettyprint lang-css">
div.cols {<span class="source6288795551616624152 two6288795551616624152source"><span class="vendorcode">
-moz-column-count:2;
-webkit-column-count:2;</span>
column-count:2;</span><span class="source6288795551616624152 three6288795551616624152source"><span class="vendorcode">
-moz-column-count:3;
-webkit-column-count:3;</span>
column-count:3;</span><span class="source6288795551616624152 width6288795551616624152source"><span class="vendorcode">
-moz-column-width:100px;
-webkit-column-width:100px;</span>
column-width:100px;</span><span class="source6288795551616624152 line6288795551616624152source"><span class="vendorcode">
-moz-column-rule: solid black 1px;
-webkit-column-rule: solid black 1px;</span>
column-rule: solid black 1px;</span><span class="source6288795551616624152 narrowgap6288795551616624152source"><span class="vendorcode">
-moz-column-gap:0px;
-webkit-column-gap:0px;</span>
column-gap:0px;</span><span class="source6288795551616624152 widegap6288795551616624152source"><span class="vendorcode">
-moz-column-gap:4em;
-webkit-column-gap:4em;</span>
column-gap:4em;</span>
}<span class="source6288795551616624152 span6288795551616624152source">
div.cols .somechild {<span class="vendorcode">
/* not supported by firefox as of June 2012 */
-webkit-column-span:all;</span>
column-span:all;
}
</span><span class="source6288795551616624152 break6288795551616624152source">
div.cols p:first-of-type {<span class="source6288795551616624152 bbefore6288795551616624152source"><span class="vendorcode">
/* not supported by firefox as of June 2012 */
-webkit-column-break-before:always;</span>
break-before:column;</span><span class="source6288795551616624152 bafter6288795551616624152source"><span class="vendorcode">
/* not supported by firefox as of June 2012 */
-webkit-column-break-after:always;</span>
break-after:column;</span>
}
</span></pre>
</div>satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-78267149092104415632012-05-27T14:51:00.001+02:002012-09-28T19:01:05.753+02:00CSS3 Reflection (Webkit & Firefox)This effect will only work with recent versions of <b style="color:darkgreen">firefox</b> and <b style="color:darkgreen">webkit</b> based browsers.
<p/>
<style type="text/css">
#content2802005526030680871 {
-webkit-box-reflect: below 0px -webkit-linear-gradient(bottom, rgba(255,255,255,0.3) 0%, transparent 40%, transparent 100%);
padding: 0px 10px;
position:relative;
margin-bottom: 120px;
}
#content2802005526030680871 img {
-moz-box-shadow: 15px 0px 20px -20px #444, -15px 0px 20px -20px #444;
-webkit-box-shadow: 15px 0px 20px -20px #444, -15px 0px 20px -20px #444;
box-shadow: 15px 0px 20px -20px #444, -15px 0px 20px -20px #444;
-webkit-border-radius: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
border: solid 10px darkgrey;
z-index: -1;
}
#content2802005526030680871:before {
content:"";
background: -moz-linear-gradient(top, white, white 30%, rgba(255,255,255,0.9) 65%, rgba(255,255,255,0.7)) 0px 0px, -moz-element(#content2802005526030680871) 0px -127px no-repeat;
-moz-transform: scaleY(-1);
padding: 1px 0px;
background-origin: padding-box, content-box;
background-clip: padding-box, content-box;
position:absolute;
height:140px;
width: 360px; /* should be > image width + margin + shadow */
top: 277px;
left:0px;
}
#video7826714909210441563 {
position:relative;
margin-bottom: 40px;
-webkit-box-reflect: below -40px -webkit-linear-gradient(bottom, rgba(255,255,255,0.3) 0%, transparent 40%, transparent 100%);
}
#video7826714909210441563:before {
content:"";
background: -moz-linear-gradient(top, white, white 30%, rgba(255,255,255,0.9) 65%, rgba(255,255,255,0.7)) 0px 0px, -moz-element(#video7826714909210441563) 0px -60px no-repeat;
-moz-transform: scaleY(-1);
padding: 1px 0px;
background-origin: border-box, content-box;
background-clip: border-box, content-box;
position:absolute;
height:40px;
width: 120px;
top: 100px;
left:0px;
}
</style>
<div id="content2802005526030680871"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5W95NUwyoFw5JRc4KovRjjtFn2phFS1muexWmeMVtnmoUqKB8ZaNx8GbPkXwzf-FBBciEBjKgwmWtbqTMfv2aVn6g7Py_vvQPQbbZPxWmWa1KRffHaWwXvQIRJqg-imhJ7OaoMzHqmds/s1600/dog1.jpg" /></div>
<h1>Howto</h1>
Given following HTML:
<pre class="prettyprint lang-html">
<div id="someid">
<img src="image url" />
<div/>
</pre>
we want "someid" to have a reflection below. The method uses only CSS to implement the effect. No changes to the HTML and no javascript required.
<p/>
In the following example the image is 300px wide and 247px high.
<p/>
<h2>Webkit</h2>
Webkit browsers (for instance safari and google chrome) have the very simple yet apparently not standard, <code class="prettyprint">-webkit-box-reflect</code> css property.
<pre class="prettyprint lang-css">
#someid {
/* need some space for the reflection */
margin-bottom: 120px;
/* the gradient makes the reflection fade out */
-webkit-box-reflect: below 0px -webkit-linear-gradient(bottom, rgba(255,255,255,0.3) 0%, transparent 40%, transparent 100%);
}
</pre>
<p/>
<h2>Firefox</h2>
With firefox we can use the <a href="http://satreth.blogspot.com/2012/05/css3-element.html">element</a> image (an images of a dom element) as background of the vertically flipped <code class="prettyprint">before</code> pseudo element.
<pre class="prettyprint lang-css">
#someid {
position: relative;
/* need some space for the reflection */
margin-bottom: 120px;
}
#someid:before {
content:""; /* needed or nothing will be shown */
background: -moz-linear-gradient(top, white, white 30%, rgba(255,255,255,0.9) 65%, rgba(255,255,255,0.7)) 0px 0px,
-moz-element(#someid) 0px -127px no-repeat;
-moz-transform: scaleY(-1); /* flip the image vertically */
position:relative;
height:140px;
width: 360px; /* should be > image width + margin + shadow */
top: 247px;
left:0px;
}
</pre>
To make the before pseudo element coordinates relative to the someid div we have to change the positioning.
The offset of the element background (-127px) is the height of before pseudo element (140px) - (the height of image (247px) + border of div (20px)).
Note that the firefox solution works only when the page has a solid background. The color of the background has to be the same as the one of the :before pseudo element's gradient.
<p/>Since all properties that have been used for the reflection, and that have a visible effect, are all vendor specific, the two method don't mess with each other.
<h1>Video</h1>
Specs say that the two different methods will update if the content changes. Therefore they should work with video, and they do!
<div id="video7826714909210441563">
<video loop="loop" autoplay="autoplay">
<source type="video/ogg" src="data:video/ogg;base64,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"/>
</video></div>
<h1>Firefox Glitch</h1>
Sometimes, firefox will render the gradient slightly smaller than the element background, resulting in a small line after the reflection fade out. To avoid that we can use a 1px padding on the top and bottom of the pseudo element and set the clipping and origins of the two backgrounds differently:
<pre class="prettyprint lang-css">
padding: 1px 0px;
background-origin: border-box, content-box;
background-clip: border-box, content-box;
</pre>satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-72108351605136382782012-05-20T23:04:00.001+02:002012-06-03T18:54:12.205+02:00Nautilus - Data URI to ClipboardIf running Nautilus (the default file manager of Ubuntu), one can use a script to create a data URI from selected files. We will use <code>xclip</code> to store the URI's in the clipboard and <code>file</code> to identify the MIME type. To install them, either run following command in a terminal<br />
<pre class="prettyprint">sudo apt-get install xclip file
</pre>or install using the software center (here a link <a href="apt:xclip,file">apt:xclip,file</a>).<br />
<br />
Prepare a file containing following script: <br />
<pre class="prettyprint">#!/bin/bash
RESULT=""
for I in $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
do
MIME=`file --mime-type -b "$I"`
BASE=`base64 -w 0 "$I"`
if ["$RESULT" = ""]; then
RESULT="data:$MIME;base64,$BASE"
else
RESULT="${RESULT}\\ndata:$MIME;base64,$BASE"
fi
done
echo -e "$RESULT" | xclip -selection clipboard
</pre>This will look through all the selected files and create a "new line" separated list of Data URIs.<br />
<br />
Put the file it into the <code class="prettyprint">.gnome2/nautilus-scripts/</code> folder and make it executable. <br />
<pre class="prettyprint">ls ~/.gnome2/nautilus-scripts
mv <<scriptname>> ~/.gnome2/nautilus-scripts
chmod +x ~/.gnome2/nautilus-scripts/<<scriptname>>
</pre>With the first command (ls) make sure there is no other script with the same name. Remember to replace <code><<scriptname>></code> with the actual path of the script created before. <br />
<br />
In nautilus you can now right click a file and select the script then go to a editor and paste the URIs.satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-25494457596515463412012-05-17T21:49:00.002+02:002012-06-12T09:48:05.729+02:00CSS3 element background<style type="text/css">
#re8426663978691425953 {
background-image:-moz-element(#a8426663978691425953);
background-repeat: no-repeat;
-moz-transform: scale(1,-0.7);
opacity:0.5;
height: 22px;
background-position: left top;
}
#a8426663978691425953 {
height: 20px;
text-shadow: 1px 1px 0px green;
color: white;
margin: 0px;
padding: 0px 3px;
border: none;
background-color: black;
}
#sbd8426663978691425953 {
border: 1px solid silver;
background-image: -moz-element(#post-body-2549445759651546341);
background-size: 50%;
height: 200px;
background-position: center 10px;
background-repeat: no-repeat;
}
#one8426663978691425953 {
background-image: -moz-element(#two8426663978691425953);
background-repeat: no-repeat;
background-size: 80%;
background-position: right top;
}
#two8426663978691425953 {
background-image: -moz-element(#one8426663978691425953);
background-repeat: no-repeat;
background-size: 80%;
background-position: right top;
}
#cimg2549445759651546341 {
width:110px;
height: 100px;
padding-left: 100px;
background-image: -moz-element(#img2549445759651546341);
}
#master2549445759651546341 {
position:relative;
height: 30px;
}
#master2549445759651546341 div {
width: 100%;
height: 30px;
top: 0px;
left:0px;
position:absolute;
}
#subject2549445759651546341{
z-index: 0;
}
#occlusion2549445759651546341{
z-index: 1;
background-color: white;
}
#target2549445759651546341{
background-image: -moz-element(#subject2549445759651546341);
height: 30px;
}
#cflash2549445759651546341 {
height: 266px;
background-image: -moz-element(#flash2549445759651546341);
}
.post h3 {
font-size: 100%;
}
</style><br />
When posted, the element image worked only with <b style="color: green">firefox</b> using <code class="prettyprint">-moz-element</code>.<br />
<br />
<input id="a8426663978691425953" type="text" value="This text is editable" size="30"/><br />
<div id="re8426663978691425953"> </div><br />
This is done with the css element image. This allows you to use a DOM element as the background of another.<br />
<br />
<h1>How to</h1>the whole magic is done by the <code class="prettyprint">element()</code> image type. When specifying the background image of an element simply use <code class="prettyprint">-moz-element(#id)</code> where <code class="prettyprint">id</code> points to the element to be used as image.<br />
<br />
Here an example. Given following HTML code:<br />
<pre class="prettyprint"><div id="one">I wouldn't steal a car, but I would download it</div>
<div id="two"></div>
</pre><br />
we can place an image of the tag #one as background of tag #two with the following CSS:<br />
<pre class="prettyprint">#two {
background-image: -moz-element(#one);
height: 40px;
}
</pre><br />
<h1>Some tests</h1><h2>Recursion</h2>Recursion does not work on the same element, but an element image of the container of another element image does:<br />
<div id="sbd8426663978691425953"></div><br />
It gets even more interesting when having two mutually recursive backgrounds:<br />
<div style="padding: 10px;"><div id="one8426663978691425953">This is div #1</div><div id="two8426663978691425953">This is div #2</div></div>Try to select the word "This".<br />
<br />
<h2>Animations</h2>What about gifs:<br />
<img style="float:left" border="0" height="100" width="100" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfMVUEA-vXOD3tf_isi9wzAPpYZsS-Lk0SyYqo8y-lUymn12LzDJUjTF8er_vUm_Miq_h_6k1FrVhNL4SwW4_OLBM_v3wnOQ0VTs1CVveIsjbIdJ8WUAUYgbx4kjFQVOmAAZH5v4qDNEE/s400/a.gif" id="img2549445759651546341" /><div id="cimg2549445759651546341"></div><br />
<br />
Flash plugin however will not work.<br />
<br />
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/DI84raB0UCI?feature=player_embedded' frameborder='0'></iframe><br />
<br />
<div id="cflash2549445759651546341"></div><br />
<h2>Hidden elements</h2>The image is generated also when the element is not visible because covered by other elements. Below we have a text that is covered by some other text. <br />
<br />
<div style="padding: 10px;"><div id="master2549445759651546341"><div id="subject2549445759651546341">This is the hidden text<br />
</div><div id="occlusion2549445759651546341">some other text<br />
</div></div></div><br />
Lets try to get the element hidden behind "some other text".<br />
<div style="padding: 10px;"><div id="target2549445759651546341"> </div></div><br />satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-83437853551783671302012-04-18T22:28:00.001+02:002012-06-13T17:51:38.848+02:00Graphiti - EMF TransactionsWhen using Graphiti, changes to the model must be performed within a transaction. Noncompliance will result in an exception. <pre class="prettyprint">java.lang.IllegalStateException: Cannot modify resource set without a write transaction
</pre>
You should not get this problem when only using features.
<p/>EMF Transactions are not only used by graphiti and all the information that follows is not Graphiti dependent.
<h1>How to use</h1>To perform changes on the model you can use the <code class="pretty-print">org.eclipse.emf.transaction.RecordingCommand</code>. This class stores all the changes performed in an editing domain during its execution (<code class="prettyprint">doExecute</code> method). The command will have to be run in the command stack of the transaction domain. This is easier than it sounds: <pre class="prettyprint">TransactionalEditingDomain domain = TransactionUtils.getEditingDomain(model_object);
domain.getCommandStack().execute(new RecordingCommand(domain) {
public void doExecute() {
// do the changes here
}
});
</pre>The TransactionalEditingDomain related classes can be found in the org.eclipse.emf.transaction package. <h1>Rollback</h1>Transactions can be interrupted with exceptions. If done so, all changes done in the doExecute method, up to the exception, are discarded. <pre class="prettyprint">try {
TransactionalEditingDomain domain = TransactionUtils.getEditingDomain(model_object);
domain.getCommandStack().execute(new RecordingCommand(domain) {
public void doExecute() {
// do the changes here
// OperationCanceledException can be replaced with other runtime exception
throw new OperationCanceledException("Please rollback");
}
});
// if here model changed
} catch (OperationCanceledException exception) {
// if here, model did not change because it was interrupted
}
</pre><h1>Nesting</h1>Transactions can be nested. Executing a recording command withing a recording command is possible. And so is interrupting the inner command without affecting the outer one. <pre class="prettyprint">final TransactionalEditingDomain domain = TransactionUtils.getEditingDomain(model_object);
domain.getCommandStack().execute(new RecordingCommand(domain) {
public void doExecute() {
// lets start the second transaction here
try {
domain.getCommandStack().execute(new RecordingCommand(domain) {
public void doExecute() {
// here we can throw an exception to cancel the inner transaction.
throw new OperationCanceledException("Rollback please");
}
});
} catch(OperationCanceledException exception) {
// if exception not catched outer transaction is canceled too
}
}
});
</pre>
<h1>Update: Threads</h1>
You might also get the IllegalStateException when trying to execute a nested RecordingCommand in a different thread than the transaction's one.satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-12456666463942479172012-04-16T22:19:00.002+02:002012-05-28T11:34:23.662+02:00Eclipse RCP Location of PreferencesPreferences in Eclipse 3 have 3 different scopes: <p/><table border="1"><tr> <th>Scope</th><th>Info</th><th>Location</th> </tr>
<tr> <td>DefaultScope</td> <td>Constant Preferences</td> <td>Taken from preferenceCustomization</td> </tr>
<tr> <td>ConfigurationScope</td> <td>Application wide configuration</td> <td>Stored in the <code class="prettyprint">configuration/.settings</code> folder</td> </tr>
<tr> <td>InstanceScope</td> <td>Workspace wide configuration (this is the one you should get from the Activator's <code class="prettyprint">getPreferenceStore</code> if not overridden)</td> <td>Stored in the <code class="prettyprint">.metadata/.plugin</code> folder of the workspace</td> </tr>
</table><p/><b>Note</b> related to <a href="http://satreth.blogspot.com/2012/02/eclipse-rcp-make-it-mac-os-app.html">Mac Export Tricks</a> post: To get all the preferences in the path specified with the <code class="prettyprint">-data</code> parameter use the InstanceScope. This should be the default you get when calling <code class="prettyprint">Activator.getDefault().getPreferenceStore()</code>.satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-64978434351940015652012-04-10T22:12:00.001+02:002012-05-28T11:34:07.606+02:00CSS3 Color Knobs<style type="text/css">
input.r06497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#000}
input.r06497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#005}
input.r06497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#00B}
input.r06497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#00F}
input.r06497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#050}
input.r06497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#055}
input.r06497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#05B}
input.r06497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#05F}
input.r06497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#0B0}
input.r06497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#0B5}
input.r06497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#0BB}
input.r06497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#0BF}
input.r06497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#0F0}
input.r06497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#0F5}
input.r06497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#0FB}
input.r06497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#0FF}
input.r16497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#500}
input.r16497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#505}
input.r16497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#50B}
input.r16497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#50F}
input.r16497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#550}
input.r16497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#555}
input.r16497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#55B}
input.r16497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#55F}
input.r16497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#5B0}
input.r16497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#5B5}
input.r16497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#5BB}
input.r16497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#5BF}
input.r16497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#5F0}
input.r16497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#5F5}
input.r16497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#5FB}
input.r16497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#5FF}
input.r26497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#B00}
input.r26497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#B05}
input.r26497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#B0B}
input.r26497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#B0F}
input.r26497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#B50}
input.r26497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#B55}
input.r26497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#B5B}
input.r26497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#B5F}
input.r26497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#BB0}
input.r26497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#BB5}
input.r26497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#BBB}
input.r26497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#BBF}
input.r26497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#BF0}
input.r26497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#BF5}
input.r26497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#BFB}
input.r26497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#BFF}
input.r36497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#F00}
input.r36497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#F05}
input.r36497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#F0B}
input.r36497843435194001565:checked ~ input.g06497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#F0F}
input.r36497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#F50}
input.r36497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#F55}
input.r36497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#F5B}
input.r36497843435194001565:checked ~ input.g16497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#F5F}
input.r36497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#FB0}
input.r36497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#FB5}
input.r36497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#FBB}
input.r36497843435194001565:checked ~ input.g26497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#FBF}
input.r36497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b06497843435194001565:checked ~ .panel6497843435194001565 { background-color:#FF0}
input.r36497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b16497843435194001565:checked ~ .panel6497843435194001565 { background-color:#FF5}
input.r36497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b26497843435194001565:checked ~ .panel6497843435194001565 { background-color:#FFB}
input.r36497843435194001565:checked ~ input.g36497843435194001565:checked ~ input.b36497843435194001565:checked ~ .panel6497843435194001565 { background-color:#FFF}
.p6497843435194001565 input[type="radio"] {
position:absolute;
left: -10000px;
}
div.k6497843435194001565 {
width:100%;
height:100%;
z-index:1;
background: -moz-radial-gradient(circle closest-side, silver 0%, silver 90%, darkgrey 95%, white 98%, white 99%);
background: -webkit-radial-gradient(circle closest-side, silver 0%, silver 90%, darkgrey 95%, white 98%, white 99%);
background: -ms-radial-gradient(circle closest-side, silver 0%, silver 90%, darkgrey 95%, white 98%, white 99%);
background: -o-radial-gradient(circle closest-side, silver 0%, silver 90%, darkgrey 95%, white 98%, white 99%);
background: radial-gradient(circle closest-side, silver 0%, silver 90%, darkgrey 95%, white 98%, white 99%);
}
div.k6497843435194001565 .I6497843435194001565{
text-align:center;
}
.p6497843435194001565 label:hover {
text-decoration:underline;
}
.p6497843435194001565 label {
font-size: 10px;
position:absolute;
text-align:center;
display: block;
width: 50px;
height: 15px;
color: blue;
z-index: 10;
}
.p6497843435194001565 input:checked ~ div div div.k6497843435194001565 {
-moz-transition: -moz-transform .5s;
-o-transition: -o-transform .5s;
-ms-transition: -ms-transform .5s;
-webkit-transition: -webkit-transform .5s;
transition: transform .5s;
}
.panel6497843435194001565 {
-moz-transition: background-color .5s;
-webkit-transition: background-color .5s;
-ms-transition: background-color .5s;
-o-transition: background-color .5s;
transition: background-color .5s;
height: 100px;
width: 420px;
}
input.r06497843435194001565:checked ~ div div.kr6497843435194001565 div.k6497843435194001565, input.g06497843435194001565:checked ~ div div.kg6497843435194001565 div.k6497843435194001565, input.b06497843435194001565:checked ~ div div.kb6497843435194001565 div.k6497843435194001565, label.k06497843435194001565 {
-moz-transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
-o-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
transform: rotate(-90deg);
}
input.r16497843435194001565:checked ~ div div.kr6497843435194001565 div.k6497843435194001565, input.g16497843435194001565:checked ~ div div.kg6497843435194001565 div.k6497843435194001565, input.b16497843435194001565:checked ~ div div.kb6497843435194001565 div.k6497843435194001565, label.k16497843435194001565 {
-moz-transform: rotate(-30deg);
-webkit-transform: rotate(-30deg);
-o-transform: rotate(-30deg);
-ms-transform: rotate(-30deg);
transform: rotate(-30deg);
}
input.r26497843435194001565:checked ~ div div.kr6497843435194001565 div.k6497843435194001565, input.g26497843435194001565:checked ~ div div.kg6497843435194001565 div.k6497843435194001565, input.b26497843435194001565:checked ~ div div.kb6497843435194001565 div.k6497843435194001565, label.k26497843435194001565 {
-moz-transform: rotate(30deg);
-webkit-transform: rotate(30deg);
-o-transform: rotate(30deg);
-ms-transform: rotate(30deg);
transform: rotate(30deg);
}
input.r36497843435194001565:checked ~ div div.kr6497843435194001565 div.k6497843435194001565, input.g36497843435194001565:checked ~ div div.kg6497843435194001565 div.k6497843435194001565, input.b36497843435194001565:checked ~ div div.kb6497843435194001565 div.k6497843435194001565, label.k36497843435194001565 {
-moz-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
-o-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
}
div.kc6497843435194001565 {
position: relative;
width: 100px;
height: 100px;
float:left;
padding: 20px;
background-color: white;
}
label.k06497843435194001565 {
margin-top:auto;
margin-bottom:auto;
top: 47%;
left: -10%;
}
label.k16497843435194001565 {
margin-top:auto;
margin-bottom:auto;
top: 10%;
left: 10%;
}
label.k26497843435194001565 {
margin-top:auto;
margin-bottom:auto;
top: 10%;
right: 10%;
}
label.k36497843435194001565 {
margin-top:auto;
margin-bottom:auto;
top: 47%;
right: -10%;
}
</style>
Click on the percentages next to the knobs to rotate.
<p/>
<div class="p6497843435194001565">
<input checked="checked" name="r6497843435194001565" class="r06497843435194001565" id="r06497843435194001565" type="radio">
<input name="r6497843435194001565" class="r16497843435194001565" id="r16497843435194001565" type="radio">
<input name="r6497843435194001565" class="r26497843435194001565" id="r26497843435194001565" type="radio">
<input name="r6497843435194001565" class="r36497843435194001565" id="r36497843435194001565" type="radio">
<input checked="checked" name="g6497843435194001565" class="g06497843435194001565" id="g06497843435194001565" type="radio">
<input name="g6497843435194001565" class="g16497843435194001565" id="g16497843435194001565" type="radio">
<input name="g6497843435194001565" class="g26497843435194001565" id="g26497843435194001565" type="radio">
<input name="g6497843435194001565" class="g36497843435194001565" id="g36497843435194001565" type="radio">
<input checked="checked" name="b6497843435194001565" class="b06497843435194001565" id="b06497843435194001565" type="radio">
<input name="b6497843435194001565" class="b16497843435194001565" id="b16497843435194001565" type="radio">
<input name="b6497843435194001565" class="b26497843435194001565" id="b26497843435194001565" type="radio">
<input name="b6497843435194001565" class="b36497843435194001565" id="b36497843435194001565" type="radio">
<div>
<div class="kc6497843435194001565 kr6497843435194001565">
<label for="r06497843435194001565" class="k06497843435194001565"> 0%</label>
<label for="r16497843435194001565" class="k16497843435194001565"> 33%</label>
<label for="r26497843435194001565" class="k26497843435194001565"> 66%</label>
<label for="r36497843435194001565" class="k36497843435194001565">100%</label>
<div class="k6497843435194001565"><div class="I6497843435194001565">I</div></div>
</div>
<div class="kc6497843435194001565 kg6497843435194001565">
<label for="g06497843435194001565" class="k06497843435194001565"> 0%</label>
<label for="g16497843435194001565" class="k16497843435194001565"> 33%</label>
<label for="g26497843435194001565" class="k26497843435194001565"> 66%</label>
<label for="g36497843435194001565" class="k36497843435194001565">100%</label>
<div class="k6497843435194001565"><div class="I6497843435194001565">I</div></div>
</div>
<div class="kc6497843435194001565 kb6497843435194001565">
<label for="b06497843435194001565" class="k06497843435194001565"> 0%</label>
<label for="b16497843435194001565" class="k16497843435194001565"> 33%</label>
<label for="b26497843435194001565" class="k26497843435194001565"> 66%</label>
<label for="b36497843435194001565" class="k36497843435194001565">100%</label>
<div class="k6497843435194001565"><div class="I6497843435194001565">I</div></div>
</div>
<div style="clear:both"></div>
</div>
<div class="panel6497843435194001565"></div>
</div>
<p/>This involves just CSS3 and HTML, no javascript and no images.
Should work on current versions of firefox and chrome.satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-10664957375829083822012-04-08T22:40:00.001+02:002012-06-03T18:53:42.619+02:00CSS3 dialog without javascript<style type="text/css">
.expand1066495737582908382 {
display: none;
}
input.check1066495737582908382:checked + .expand1066495737582908382 {
position: fixed;
top: 0px;
bottom:0px;
left: 0px;
right: 0px;
z-index: 1000;
display: block !important;
}
input.check1066495737582908382:checked + .expand1066495737582908382 .dialog1066495737582908382 {
background-color: white;
margin-left: auto;
margin-right: auto;
margin-top: 10%;
width: 300px;
position:relative;
height: 200px;
padding: 0px 20px;
-moz-box-shadow: 0px 6px 12px #222;
-ms-box-shadow: 0px 6px 12px #222;
-o-box-shadow: 0px 6px 12px #222;
-webkit-box-shadow: 0px 6px 12px #222;
box-shadow: 0px 6px 12px #222;
}
input.check1066495737582908382:checked ~ .bg1066495737582908382 {
position: fixed;
top: 0px;
bottom:0px;
left: 0px;
right: 0px;
opacity: 0.5;
background-color: black;
z-index: 999;
}
.dialog1066495737582908382 .title1066495737582908382 {
background-color: darkblue;
color: white;
font-weight: bold;
padding: 3px 20px;
margin: 0px -20px 20px -20px;
}
.button1066495737582908382 {
float: left;
}
.dialog1066495737582908382 label.label1066495737582908382, .button1066495737582908382 {
padding: 2px 10px;
display:block;
background-color: darkgray;
outline: outset silver 2px;
}
.dialog1066495737582908382 label.label1066495737582908382 {
position: absolute;
right: 20px;
bottom: 20px;
}
.dialog1066495737582908382 label.label1066495737582908382:active, .button1066495737582908382:active {
outline: inset silver 2px;
}
input.check1066495737582908382 {
display: none;
}
</style>
<h2>Quick intro</h2>
I will use a hidden checkbox, some sibling combinators and CSS3's :checked pseudo class to do the magic. The buttons to show and dismiss are only labels for the checkbox. Click on the button below to show the dialog:
<div>
<label class="button1066495737582908382" for="ch11066495737582908382">Show</label>
<div style="clear:both"></div>
</div>
<p/>Other uses of this can be found <a href="http://satreth.blogspot.com/2012/04/css3-toggle-fields.html">here</a>.
<h2>The code</h2>
The CSS for the actual display of the dialog and opaque background:
<pre class="prettyprint">
/** if nothing else do not show the dialog container */
.expand, .bg {
display: none;
}
/** an .expand class immediately following a checked checkbox */
/** this will show the dialog container when the checkbox is checked */
input.check:checked + .expand {
position: fixed;
top: 0px; bottom:0px; left: 0px; right: 0px;
z-index: 10;
display: block !important;
}
/** a .bg class that follows (not necessarily immediately) a checked checkbox */
/** this is the opaque background layer. active when the dialog is visible. */
input.check:checked ~ .bg {
position: fixed;
top: 0px; bottom:0px; left: 0px; right: 0px;
opacity: 0.5;
background-color: black;
z-index: 9;
display: block !important;
}
/** do not show the checkbox that holds the visibility state of the dialog */
input.check {
display: none;
}
</pre>
We used the direct sibling combinator (+) for the .expand class and the general sibling combinator (~) for the background. We could have also used the general one for both. The general matches any sibling, while the direct only the sibling right next to the checkbox.
<p/>
The code above could be made a little more compact by merging the .expand and .bg common parts.
<P/>
All the rest of the CSS is to make the dialog look a little like a dialog.
<pre class="prettyprint">
/** dialog look (centered and with a blue title bar) */
.expand .dialog {
background-color: white;
margin-left: auto;
margin-right: auto;
margin-top: 10%;
width: 300px;
position:relative;
height: 200px;
outline: outset 1px darkgrey;
padding: 0px 20px;
}
.dialog .title {
background-color: darkblue;
color: white;
font-weight: bold;
padding: 3px 20px;
margin: 0px -20px 20px -20px;
}
.dialog label {
position: absolute;
right: 20px;
bottom: 20px;
padding: 2px 10px;
display:block;
background-color: darkgray;
outline: outset silver 2px;
}
.dialog label:active {
outline: inset silver 2px;
}
</pre>
The HTML part is:
<pre class="prettyprint">
<div>
<input class="check" id="check1"/>
<div class="expand">
<div class="dialog">
<div class="title">Alert</div>
CSS3 & HTML5 are fun and so cool!
<label for="check1" class="button">Dismiss</label>
</div>
</div>
<div class="bg"></div>
</div>
<label for="check1" class="button">Show</label>
</pre>
Just use a label linked to the check box to activate the dialog.
<div>
<input type="checkbox" class="check1066495737582908382" id="ch11066495737582908382"/>
<div class="expand1066495737582908382">
<div class="dialog1066495737582908382">
<div class="title1066495737582908382">Alert</div>
CSS3 & HTML5 are fun and so cool!
<label class="label1066495737582908382" for="ch11066495737582908382" class="button">Dismiss</label>
</div>
</div>
<div class="bg1066495737582908382"></div>
</div>satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-1659521754590182332012-04-08T21:32:00.000+02:002012-05-28T11:36:38.727+02:00CSS3 Board<style type="text/css">
@-moz-keyframes hide165952175459018233 {
from {background-color: black;}
to {background-color: white;}
}
@-moz-keyframes show165952175459018233 {
from {background-color: white;}
to {background-color: black;}
}
@-webkit-keyframes hide165952175459018233 {
from {background-color: black;}
to {background-color: white;}
}
@-webkit-keyframes show165952175459018233 {
from {background-color: white;}
to {background-color: black;}
}
@-ms-keyframes hide165952175459018233 {
from {background-color: black;}
to {background-color: white;}
}
@-ms-keyframes show165952175459018233 {
from {background-color: white;}
to {background-color: black;}
}
@-o-keyframes hide165952175459018233 {
from {background-color: black;}
to {background-color: white;}
}
@-o-keyframes show165952175459018233 {
from {background-color: white;}
to {background-color: black;}
}
@keyframes hide165952175459018233 {
from {background-color: black;}
to {background-color: white;}
}
@keyframes show165952175459018233 {
from {background-color: white;}
to {background-color: black;}
}
.xs165952175459018233 {
position: absolute;
-moz-animation-name: hide165952175459018233;
-moz-animation-iteration-count: 1;
-moz-animation-duration: 1s;
-moz-animation-timing-function: ease-out;
-ms-animation-name: hide165952175459018233;
-ms-animation-iteration-count: 1;
-ms-animation-duration: 1s;
-ms-animation-timing-function: ease-out;
-webkit-animation-name: hide165952175459018233;
-webkit-animation-iteration-count: 1;
-webkit-animation-duration: 1s;
-webkit-animation-timing-function: ease-out;
-o-animation-name: hide165952175459018233;
-o-animation-iteration-count: 1;
-o-animation-duration: 1s;
-o-animation-timing-function: ease-out;
animation-name: hide165952175459018233;
animation-iteration-count: 1;
animation-duration: 1s;
animation-timing-function: ease-out;
background-color: white;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
}
.xs165952175459018233:hover {
-moz-animation-name: show165952175459018233;
-moz-animation-iteration-count: 1;
-moz-animation-duration: 0.1s;
-moz-animation-timing-function: linear;
-webkit-animation-name: show165952175459018233;
-webkit-animation-iteration-count: 1;
-webkit-animation-duration: 0.1s;
-webkit-animation-timing-function: linear;
-ms-animation-name: show165952175459018233;
-ms-animation-iteration-count: 1;
-ms-animation-duration: 0.1s;
-ms-animation-timing-function: linear;
-o-animation-name: show165952175459018233;
-o-animation-iteration-count: 1;
-o-animation-duration: 0.1s;
-o-animation-timing-function: linear;
animation-name: show165952175459018233;
animation-iteration-count: 1;
animation-duration: 0.1s;
animation-timing-function: linear;
background-color: black;
}
.contain165952175459018233 {
cursor: none;
position: relative;
height: 400px;
width: 400px;
border:solid 1px black;
background-color: white;
z-index: 1;
}
</style> move the mouse in the white box below. <div class="contain165952175459018233" ><script type="text/javascript">
var rs=20.0;
var w = 100/rs;
for (row = 0; row < rs; row++) {
for (col = 0; col < rs; col++) {
document.write("<div class='xs165952175459018233' style='width: "+ w + "%; height: "+ w + "%; left:" + (row * w) + "%;top:" + (col * w) + "%;'></div>");
}}
</script> </div><h2>How it works</h2>Just a bunch of div placed in a square. Their CSS defines animations when they are shown and when hovered. The hovering effect will quickly darken the background color to black (0.1s). When unhovered the background is set back to white this time a little slower, 1 second. <p/>The 400 cells of the example above are created with a script. <h2>The stylesheet</h2><pre class="prettyprint">@keyframes hide {
from {background-color: black;}
to {background-color: white;}
}
@keyframes show {
from {background-color: white;}
to {background-color: black;}
}
.cell {
position: absolute;
animation-name: hide;
animation-iteration-count: 1;
animation-duration: 1s;
animation-timing-function: ease-out;
background-color: white;
border-radius: 5px;
}
.cell:hover {
animation-name: show;
animation-iteration-count: 1;
animation-duration: 0.1s;
animation-timing-function: linear;
background-color: black;
}
.container {
cursor: none;
position: relative;
height: 400px;
width: 400px;
border: solid 1px black;
background-color: white;
}
</pre><h2>The HTML and script</h2><pre class="prettyprint"><div class="container">
<script type="text/javascript">
var size = 20;
var width = 100/size;
for (row = 0; row < size; row++) {
for (col = 0; col < size; col++) {
document.write("<div class='cell' style='" +
"width: " + width + "%; " +
"height: " + width + "%; " +
"left:" + (row * width) + "%;" +
"top:" + (col * width) + "%;'></div>");
}
}
</script>
</div>
</pre>satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-31556607272788906142012-04-08T21:27:00.002+02:002012-05-28T11:37:15.595+02:00CSS3 Toggle Fields<style type="text/css">
.expand3155660727278890614 {
height: 28px;
font-size: 24px;
overflow: hidden;
border: solid 4px #385;
display: block;
padding: 10px 10px;
margin-bottom: 20px;
background-color: #eff;
-moz-transition-property: height;
-moz-transition-duration: 0.5s;
-moz-border-radius: 10px;
-moz-box-shadow: 5px 5px 5px;
-ms-transition-property: height;
-ms-transition-duration: 0.5s;
-ms-border-radius: 10px;
-ms-box-shadow: 5px 5px 5px;
-webkit-transition-property: height;
-webkit-transition-duration: 0.5s;
-webkit-border-radius: 10px;
-webkit-box-shadow: 5px 5px 5px;
transition-property: height;
transition-duration: 0.5s;
border-radius: 10px;
box-shadow: 5px 5px 5px;
z-index: 1;
}
input.tg3155660727278890614:focus ~ label {
outline: dashed 1px silver;
}
input.tg3155660727278890614:checked + .expand3155660727278890614 {
height: 200px;
-moz-transition-property: height;
-moz-transition-duration: 0.5s;
-ms-transition-property: height;
-ms-transition-duration: 0.5s;
-webkit-transition-property: height;
-webkit-transition-duration: 0.5s;
transition-property: height;
transition-duration: 0.5s;
}
label.link {
color: blue;
cursor: pointer;
}
label.link:hover {
text-decoration: underline;
}
input.tg3155660727278890614 {
position:absolute;
left: -10000px;
}
</style>
<div>
<input type="checkbox" class="tg3155660727278890614" id="ch13155660727278890614"/>
<label for="ch13155660727278890614" class="expand3155660727278890614">
Click here: no javascript involved
<p/>
Just HTML and CSS3 being awesome!
</label>
</div>
<h2>How it works</h2>
The toggle effect uses a hidden checkbox. CSS3 introduces the <a href="http://www.w3.org/TR/selectors/#checked">:checked</a> pseudo class. This combined with the <a href="http://www.w3.org/TR/selectors/#sibling-combinators">Adjacent sibling combinators</a> will allow us to behave differently when the check box is selected and when not. To make check box change state upon a click on some text we will use a label for the checkbox. In HTML this translates to:
<pre class="prettyprint">
<input type="checkbox" class="check" id="check1"/>
<label for="check1" class="expand">
Click here: no javascript involved
<div class="details">
Just HTML and CSS3 being awesome!
</div>
<label>
</pre>
While in this example the part that will expand is the label itself, this is not at all a requirement.
<p/>
The CSS part includes also some transition effect. For the sake of simplicity the code below shows only important parts (no borders, shadows and colors):
<pre class="prettyprint">
.expand {
height: 28px;
font-size: 24px;
overflow: hidden;
display: block;
transition-property: height;
transition-duration: 0.5s;
}
input.check:checked + .expand {
height: 200px;
transition-property: height;
transition-duration: 0.5s;
display:block;
}
input.check {
position: absolute;
left: -10000px;
}
</pre>
NOTE: all code is non vendor specific CSS3. You will have to add -moz- and similar to get to work on the different browsers.
<h2>Quite powerful</h2>
This method turns out to be quite powerful. The label does not have to be next to the checkbox so we can place it where ever we want (<label class="link" for="ch23155660727278890614">click here</label>) and the element next to the hidden checkbox will still get expanded. We can even have multiple label pointing to the same checkbox (<label class="link" for="ch23155660727278890614">another label</label>).
<div>
<input type="checkbox" class="tg3155660727278890614" id="ch23155660727278890614"/>
<div class="expand3155660727278890614">
Clicking here wont do much<p/>
on the label in the text it does
</div>
</div>
<h2>Even more</h2>
There are many more things involved and many more applications of this method. The major advantage is that it will not require javascript to be enabled.
<a href="http://satreth.blogspot.com/2012/04/css3-dialog-without-javascript.html">Here</a> a post about an alert dialog without javascript.
<p/>
A search in google will give you also many other uses of this "hack".
<h2>Accessibility</h2>
If not implemented correctly, this method is not very accesibility friendly. Multiple labels for a check box might confuse a screen reader and labels are not focussable. One quick fix for the latter could be:
<pre class="prettyprint">
input.check:focus ~ label {
outline: dashed 1px silver;
}
</pre>
But this will only work if the label follows the checkbox.satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0tag:blogger.com,1999:blog-1584392835174974542.post-68785516026596709732012-04-05T22:20:00.000+02:002012-05-28T11:37:29.407+02:00CSS3 Text Outline<style type="text/css">
.redBorderShadow6878551602659670973 {
color: #d11;
text-shadow:
white 1px 1px 0px,
white -1px 1px 0px,
white -1px -1px 0px,
white 1px -1px 0px,
white 1px 0px 0px,
white -1px 0px 0px,
white 0px 1px 0px,
white 0px -1px 0px,
black 3px 3px 7px;
font-size:24px;
background-color: #445;
padding:10px;
letter-spacing:1px;
font-weight: bold;
text-align:center;
}
.bg_6878551602659670973 {
background-color: #445;
position:relative;
}
.big_6878551602659670973 {
width:50%;
color: #d11;
font-size:120px;
padding:0px 0px;
font-weight: bold;
text-align:center;
letter-spacing:5px;
float:left;
}
.rbs1_6878551602659670973 {
text-shadow:
white 5px 5px 0px,
white -5px 5px 0px,
white -5px -5px 0px,
white 5px -5px 0px,
black 15px 15px 35px;
}
.rbs2_6878551602659670973 {
text-shadow:
white 5px 5px 0px,
white -5px 5px 0px,
white -5px -5px 0px,
white 5px -5px 0px,
white 5px 0px 0px,
white -5px 0px 0px,
white 0px 5px 0px,
white 0px -5px 0px,
black 15px 15px 35px;
}
</style> <div class="warning">You will need a browser that supports CSS3 to see this page properly.</div>A method to add an outline around some text is to define some solid shadows of the color that we want as border. This shadow will have no blurring and will have to be positioned shifted in all directions. <div class="redBorderShadow6878551602659670973">The quick brown fox jumps over the lazy dog</div><pre class="prettyprint">.bordershadow {
color: #d11;
text-shadow:
white 1px 1px 0px, /* right down */
white -1px 1px 0px, /* left down */
white -1px -1px 0px, /* right up */
white 1px -1px 0px, /* left up */
/** next 4 shadows improve rendering */
white 1px 0px 0px, /* right */
white -1px 0px 0px, /* left */
white 0px 1px 0px, /* down */
white 0px -1px 0px, /* up */
/** lets add some blurred shadow to make it
look a little nicer */
black 3px 3px 7px;
letter-spacing:1px;
}
</pre><h2>4 vs 8 outline shadows</h2>The comment in the code says that second 4 shadows improve rendering. This is especially true for sharp corners. Lets have a closer look: (Left with 4 shadows, right with all 8) <p/><div class="bg_6878551602659670973"><div class="big_6878551602659670973 rbs1_6878551602659670973">xt</div><div class="big_6878551602659670973 rbs2_6878551602659670973">xt</div><div style="clear:both"></div></div><h2>Letter spacing</h2>Letter-spacing was added since, with the "border", the characters are now 2 pixels taller and broader.satrethhttp://www.blogger.com/profile/13072587255261989308noreply@blogger.com0