made

Coordinate Conversion Made Easy – the power of GeometryUtils

In a previous post we introduced the GeometryUtils interface and the getBoxQuads() API for retrieving the CSS box geometry of a DOM node. GeometryUtils also takes care of another important problem: converting coordinates reliably from one DOM node to another. For example, you might want to find the bounding-box of one element relative to another element, or you might want to convert event coordinates from the viewport to some arbitrary element.

Existing APIs

Until now, simple cases could be handled using getBoundingClientRect() and some math, but complex cases (e.g. involving CSS transforms) were almost impossible to handle using standard APIs. The nonstandard APIs webkitConvertPointToPage and webkitConvertPageToPoint are a big improvement, but apart from not being standardized, they’re not as powerful as they need to be. In particular it’s more convenient and more robust to provide an API for directly converting coordinates from one element to another.[1]

New APIs

GeometryUtils introduces three new methods for coordinate conversion:

  • to.convertPointFromNode(point, from) converts a a point relative to the top-left of the first border-box of “from” to a point relative to the top-left of the first border-box of “to”. The point is a DOMPointInit, which means you can pass a DOMPoint or a JS object such as {x:0, y:0}.
  • to.convertRectFromNode(rect, from) converts a a DOMRect relative to the top-left of the first border-box of “from” to a DOMQuad relative to the top-left of the first border-box of “to” by converting the vertices of the DOMRect. It converts to a DOMQuad to ensure that the result is accurate even if it needs to be rotated or skewed by CSS transforms.
  • to.convertQuadFromNode(quad, from) converts a DOMQuad from “from” to “to”. It’s just like convertRectFromNode except for taking a DOMQuad.

As with getBoxQuads, a node can be an Element, TextNode or Document; when a Document is used, the coordinates are relative to the document’s viewport.

Example:

<div id="d" style="position:absolute; transform:rotate(45deg); left:100px; top:100px; width:100px; height:100px;"></div>
<div id="e" style="position:absolute; left:100px; top:100px; width:100px; height:100px;"></div>
var p1 = document.convertPointFromNode({
    x:0, y:0
  }, document.getElementById("e")
);
// p1.x == 100, p1.y == 100
 
var p2 = document.convertPointFromNode({
    x:0, y:0
  }, document.getElementById("d")
);
// p2.x == 150, p2.y == 150 - 50*sqrt(2) (approx)
 
p2 = document.getElementById("e").convertPointFromNode({
    x:0, y:0
  }, document.getElementById("d")
);
// p2.x == 50, p2.y == 50 - 50*sqrt(2) (approx)
 
var q1 = document.convertRectFromNode(
  new DOMRect(0, 0, 50, 50), 
  document.getElementById("e")
);
// q1.p1.x == 100, q1.p1.y == 100
// q1.p2.x == 150, q1.p2.y == 100
// q1.p3.x == 150, q1.p3.y == 150
// q1.p4.x == 100, q1.p4.y == 150
 
var q2 = document.convertQuadFromNode(
  new DOMQuad({
    x:60, y:50
  }, {
    x:90, y:50
  }, {
    x:100, y:100
  }, {
    x:50, y:100
  }), 
  document.getElementById("e")
);
// q2.p1.x == 100, q2.p1.y == 100
// q2.p2.x == 150, q2.p2.y == 100
// q2.p3.x == 140, q2.p3.y == 150
// q2.p4.x == 110, q2.p4.y == 150
p1
p2

Sometimes it’s useful to convert to or from an element’s CSS content-box, padding-box or margin-box. This is supported via an optional ConvertCoordinateOptions dictionary with the following options:

  • fromBox: one of "content", "padding", "border" or "margin", selecting which CSS box of the first fragment of the from node the input point(s) are relative to.
  • toBox: selects which CSS box of the first fragment of the to node the returned point(s) are relative to.

As a special case, this makes it easy to convert points between different
CSS box types of the same element. For example, to convert a point from an
element’s border-box to be relative to its content-box, use
element.convertPointFromNode(point, element, {toBox:"content"}).

Example:

<div id="e" style="position:absolute; padding:20px; left:100px; top:100px; width:60px; height:60px;"></div>
var p1 = document.convertPointFromNode({
    x:0, y:0
  }, document.getElementById("e"), 
  {fromBox:"content"}
);
// p1.x == 120, p1.y == 120
 
p1 = document.getElementById("e").convertPointFromNode({
    x:120, y:120
  }, document,
  {toBox:"content"}
);
// p1.x == 0, p1.y == 0
 
p1 = document.getElementById("e").convertPointFromNode({
    x:0, y:0
  }, document.getElementById("e"), 
  {fromBox:"content"}
);
// p1.x == 20, p1.y == 20
 
p1 = document.getElementById("e").convertPointFromNode({
    x:20, y:20
  }, document.getElementById("e"), 
  {toBox:"content"}
);
// p1.x == 0, p1.y == 0
p1
e content-box
e border-box

These APIs are available in Firefox nightly builds and should be released in Firefox 31. Firefox is the first browser to implement these APIs.

Footnote

[1] Consider the following example:

<div style="transform:scale(0)">
  <div id="a">...<>
  <div id="b">...<>
</div>

In this case, converting a point relative to a to be relative to b by converting first to page coordinates and then back to b doesn’t work, because the scale(0) maps every point in a to a single point in the page.

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Giving a talk is cool – getting a song made from your talk is cooler!

Earlier this year, I was lucky enough to speak at Beyond Tellerand in Germany. My talk Fixing the mobile web (video on Vimeo) was a passionate session on how the web is not only for the rich with the coolest, newest devices, but for everyone. Marc Thiele, the organiser of Beyond Tellerand, is not only a good friend who I have a long history with, but also fiercely passionate about making his events memorable. One of the very unique things about this event was that all talks were sampled and remixed live in the breaks between talks by the German electronica artist Baldower.

Here is what they did with my talk. You can hear the song “The Web is for everybody” by Baldower on Soundcloud.

I was first confused but then giggled at the small laugh sample at the end of the song, of course an homage to Melle Mel’s laugh in Grandmaster Flash and the Furious Five’s “The Message”, although I am pretty sure I could not get away with his style:

melle mel in the message music video

You can listen to all the songs from Beyond Tellerand them on Baldower’s Soundcloud page

View full post on Christian Heilmann

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Wercker – Continuous Delivery Made Easy – a webFWD project

There is a great quote by Marc Andreessen who said that “software is eating the world”. What Marc means by this is that software is defining every industry we know; we’re no longer buying records at our local retailer but stream them via Rdio or Spotify. Skype is now the largest telecommunications provider and we’re even talking about the software-defined data-center.

The cloud has become the defacto distribution mechanism for these software services, but has also allowed for disruptive change in how these services are delivered and consumed. Whereas it used to be the case that you would have to purchase a new version of your favorite word processing software at your local retailer, with the cloud, updates can be pushed out incrementally.

Introducing wercker

The key enabler for this new way of developing software is continuous delivery. Software is eating the world, and wercker makes it taste better.

There are several successful companies out there which are big proponents of continuous delivery such as Netflix and Etsy. It is wercker’s mission to democratize continuous delivery for every developer and was founded on this very same premise in the beginning of last year by me, Micha Hernandez van Leuffen, and my cofounder Wouter Mooij out of frustration with existing solutions.

This video introduces wercker and presents our vision on the product:

How it works

Wercker’s flow is simple; it integrates with popular version controls platforms such as Github and Bitbucket on one end and Infrastructure-as-a-Service providers and Platform clouds like Heroku on the other end.

We run any unit tests you might have included in your project and subsequently present the results on a comprehensive dashboard.

You are able to define different environments or deploy targets for, for instance staging or production to which you can deploy your project with a push of a button.

Software is better developed together so wercker also captures the social dynamics that are paired with continuous delivery. The activity feed showcases who in your team broke the build or deployed to which environment. This increases transparency and trust within your team.

Open Source

Apart from offering wercker for free to open source projects we are also in the process of opening up wercker’s build environments. These environments are similar to Heroku’s buildpacks, allowing developers to define not only their own programming stack that they would like to use on wercker, but also the various build and test steps that they want to run.

New languages and frameworks can be integrated with ease as we’ve built these environments upon Chef cookbooks which can subsequently be used for both provisioning and deployment as well. Cookbooks and recipes are already a very big open source movement, which we’re stimulating even more.

The Future

We’re very excited that we’ve raised a seed round led by Shamrock Ventures, Amsterdam-based MicroVC Vitulum Ventures and Greylock Partners. The funding will help us grow our platform and expand our operations.

If you are a developer, sign up for the beta at http://beta.wercker.com. We are also interested in hearing what programming stacks developers are leveraging for their applications and to which environments they are deploying.

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)