How to convert a rectangle to TRBL CSS rect value?
I'm not quite sure how to put this, but here goes...
The css clip attribute is defined like so: rect(top, right, bottom, left). However, I'm exploring the use of a custom开发者_JAVA技巧 Rectangle 'class' to encapsulate some operations. The rectangle class has the attributes height, width and x, y.
The x and y values are encapsulated in a Point object, and the height and width are encapsulated in a Dimension object, the rectangle being a composite of a point (its top-left location) and a dimension (width and height).
So far so good. I though it would be pretty simple on the basis of having the rectangles x, y, width and height values to define the css rect attribute in terms of top, right, bottom, left, but I've become hopelessly confused- I've been googling for a while, and I can't seem to find any documentation as to what the TRBL values actually are or what they represent. For example, should I be thinking in terms of co-ordinates, in which case, surely I can describe the rectangle as a css rect using the rectangles x position for Top, x position + width for Right, the rectangles height + y for Bottom and its y position for Left... but thats a load of BS, surely?
Also, surely rect is actually an inset, or have I just inverted my understanding of clip? I'd appreciate some advice. What I want to be able to do is
(i) Define a rectangle using x, y, width and height (ii)Express the rectangle in TRBL form so that I can manipulate a divs clipping behaviour (iii)Change x, y, width or height and recalculate in terms of TRBL and goto (ii)
I appreciate there are some other factors here, and some intermediary transforms to be done, but I've confused myself pretty badly-
Can anyone give me some pointers?
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!
精彩评论