«Решение» было в основном просто лучшим пониманием свойства css rect в терминах координатного пространства.
Я запутался в том, как определить, где должен появиться прямоугольник CSS-клипа. Ответ на самом деле прост, как только вы поймете, что в терминах css rect, «пространство координат» - это размеры обрезаемого элемента (E), и вы всегда можете представить, что E имеет его верхний левый угол как имеющий координаты x = 0, y = 0.
Итак, давайте предположим, что у нас есть элемент E, и он имеет высоту 200 и ширину 300. Мы можем описать его так:
E= {x:0, y:0, width:300, height:200}
Его координаты x и y, насколько нам известно при отображении значений TRBL прямоугольника отсечения, равны 0, 0. Итак, давайте рассмотрим прямоугольник отсечения, пример, определенный так
C= {x:30, y:30, width:150, height:150}
Поскольку C.x и C.y относятся к координатному пространству E, а E.x и E.y всегда равны 0, мы можем просто полностью игнорировать E.x и E.y во всех случаях. Фактически, если мы не заинтересованы в ограничении C (прямоугольника отсечения) до E, мы можем полностью отказаться от всех знаний об E и использовать метод, подобный приведенному ниже, для преобразования C в объявление css rect.
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)';
}
Итак, со следующей разметкой HTML (рассмотрим элемент img как E)
<div class='.clipComponent'>
<div id="contentClipper" class=".clipContent'>
<img src="whatever.jpg"/>
</div>
</div>
... и CSS
.clipComponent {position:relative}
.clipContent {position:absolute; clip:rect(auto);}
... у нас будет несжатое изображение (поскольку .clipContent будет соответствовать размеру img, потому что мы определили его с помощью auto). Теперь, чтобы обрезать его, мы могли бы передать C (определенный выше) в функцию toCssRect и применить его к div .clipContent следующим образом:
var clipDiv= document.getElementById('contentClipper')
, clipRect= {x:10, y:10, width:100, height:20};
clipDiv.style.clip= toCssRect(clipRect);
И вот мы здесь. Преимущество этого в том, что вы можете перемещать прямоугольник, добавляя значения
к его свойствам x и y, или увеличивайте и уменьшайте прямоугольник, изменяя его свойства width и height. После каждой модификации вы преобразуете прямоугольник в объявление css rect и устанавливаете его как значение clip. Это хорошо подходит для анимации.
Если вы хотите реализовать свой собственный класс прямоугольника, обратите внимание, что по крайней мере с Safari и Chrome, если вы реализуете toString для возврата результатов метода toCssRect, вы можете просто назначить прямоугольник свойству clip объекта стиля элементов - для иллюстрации рассмотрим приведенный ниже объект:
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;
}
}
Теперь вы можете анимировать и кодировать достаточно четко (предположим, объекты и функции, определенные выше)
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);
Надеюсь, все это имеет смысл!