The 'solution' was basically just a better understanding of the css rect property in terms of co-ordinate space.
I confused about how to determine where a css clip rect would appear. The answer is actually simple once you realise that in terms of css rect, the 'co-ordinate space' is the dimensions of the element being clipped (E), and that you can always conceive of E as having its top left corner as having the co-ordinates x=0, y=0.
So lets assume we have an element E, and it has a height of 200 and a width of 300. We can describe it like so
E= {x:0, y:0, width:300, height:200}
Its x and y co-ordinates, in as far as we are concerned when plotting the TRBL values of the clipping rect is 0, 0. So lets consider the clipping rect, an example defined like so
C= {x:30, y:30, width:150, height:150}
As C.x and C.y refer to the co-ordinate space of E, and E.x and E.y are always 0, we can just ignore E.x and E.y entirely, in all cases. In fact, unless we are concerned with constraining C (the clipping rect) to E, we can do away with all knowledge of E entirely, and use a method like below to transform C into a css rect declaration.
function toCssRect(rectangle)
{
var left= parseInt(rectangle.x)
, right= parseInt(left + rectangle.width)
, top= parseInt(rectangle.y)
, bottom= parseInt(top + rectangle.height);
return 'rect(' + top + 'px ' + right + 'px ' + bottom + 'px ' + left +'px)';
}
So, with the following HTML markup (consider the img element as E)
<div class='.clipComponent'>
<div id="contentClipper" class=".clipContent'>
<img src="whatever.jpg"/>
</div>
</div>
... and CSS
.clipComponent {position:relative}
.clipContent {position:absolute; clip:rect(auto);}
... we'll have an unclipped image (as .clipContent will accomodate the size of img because we defined it with auto). Now in order to clip it, we could pass C (defined above) to the toCssRect function and apply it to the .clipContent div like so
var clipDiv= document.getElementById('contentClipper')
, clipRect= {x:10, y:10, width:100, height:20};
clipDiv.style.clip= toCssRect(clipRect);
And there we are. The advantage of this is that you can move the rectangle by adding values
to its x and y properties, or grow and shrink the rectangle by modifying its width and height properties. After each modification, you transform the rectangle to a css rect declaration and set is as the value of clip. This lends itself to a animation pretty well.
If you want to implement your own rectangle class, note that at least with Safari and Chrome, if you implement toString to return the results of the toCssRect method, you can just assign the rectangle to the clip property of an elements style object- for sake of illustration, consider the object literal below:
var clipRect=
{
x:30,
y:40,
width:10,
height:30,
toString: function ()
{
return toCssRect(this);
},
translate: function (dx, dy)
{
this.x+= dx || 0;
this.y+= dy || 0;
return this;
}
}
Now you can animate and code quite clearly (assume the objects and functions defined above)
setInterval(function ()
{
// translate will add 1px to the value of the rectangles x position,
// (moving it down) and then return a reference to the clipRect object.
// When you assign the clipRect object to the divs style object
// JavaScript will attempt to convert the clipRect object to a primitive,
// which will invoke toString and return the css string- nice and clean
clipDiv.style.clip= clipRect.translate(1, 0);
}, 500);
Hope all that makes sense!