Ответ 1
О, мой! Большой вопрос!
Итак, посмотрим, что у нас есть. Система, которая имеет кучу "ограничений", которые являются наборами из двух точек. Пробелы сами попадают парами, и они образуют две линии, образуя форму ┘
(внизу справа от окна).
Если бы мы рисовали каждую линию ограничений индивидуально, мы увидели бы это:
Это все горизонтальные красные линии и вертикальные синие линии. Рисуя один, мы просто увидим, что форма ┘
, и каждая длинная красная линия - это действительно сотни маленьких линий, нижняя часть каждой формы ┘
, от конца до конца. Здесь несколько сотен ┘
, и вместе они делают его похожим на сплоченную сетку. Тот факт, что каждый из нас уже индивидуально, делает это легко для нас.
Эта форма - это все, что нам нужно для определения своего рода ограничивающего прямоугольника. И похоже, что каждый Point
в Constraint
имеет исходные значения, поэтому мы сохраним их как sx
и sy
.
Если мы знаем границы ящиков в их новом местоположении, и мы знаем исходные границы, потому что мы сохранили все значения Point для Contraints, тогда мы должны быть золотыми.
Как только у нас есть исходная ограничивающая рамка Ограничения и ее текущий ограничивающий прямоугольник, почему все, что нам нужно сделать, это вызов drawImage с обоими полями: ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);
Я написал новую процедуру Constraint.prototype.draw
, она выглядит так:
И так далее.
Есть несколько способов "исправить" дыры, и это действительно зависит от вас, иначе вам придется окунуться в трансформации.
Посмотрите на код. Я не сильно изменился. Ищите !!!
в коде (мои правки) и DEBUG:
в коде (код отладки в случае, если изображение не загружается или вы хотите увидеть каркасы).
http://jsfiddle.net/simonsarris/Kuw6P/
Код длинный, поэтому я не хочу вставлять его здесь, но здесь резервная копия в случае, если jsfiddle идет вниз: https://gist.github.com/simonsarris/5405304
И вот самая важная часть:
// !!! new super awesome draw routine! So cool we skipped naming it draw2!
Constraint.prototype.draw3 = function(otherP2) {
// NOW dear friends consider what we have. Each box is made out of two lines,
// the bottom and rightmost ones.
// From these lines we can deduce the topleft and bottom-right points
// From these points we can deduce rectangles
// From the skewed rectangle vs the original rectangle we can "stretch"
// an image, using drawImage overloaded goodness.
// AND WE'RE OFF:
// destination rect has 2 points:
//top left: Math.min(this.p2.x, otherP2.x), Math.min(this.p2.y, otherP2.y)
//bottom right: (this.p1.x, this.p1.y)
// image destination rectangle, a rect made from the two points
var dx = Math.min(this.p1.x, Math.min(this.p2.x, otherP2.x));
var dy = Math.min(this.p1.y, Math.min(this.p2.y, otherP2.y));
var dw = Math.abs(this.p1.x - Math.min(this.p2.x, otherP2.x));
var dh = Math.abs(this.p1.y - Math.min(this.p2.y, otherP2.y));
// DEBUG: IF THERE IS NO IMAGE TURN THIS ON:
//ctx.strokeStyle = 'lime';
//ctx.strokeRect(dx, dy, dw, dh);
// source rect 2 points:
//top left: Math.min(this.p2.sx, otherP2.sx), Math.min(this.p2.sy, otherP2.sy)
//bottom right: (this.p1.sx, this.p1.sy)
// these do NOT need to be caluclated every time,
// they never change for a given constraint
// calculate them the first time only. I could do this earlier but I'm lazy
// and its past midnight. See also: http://www.youtube.com/watch?v=FwaQxDkpcHY#t=64s
if (this.sx === undefined) {
this.sx = Math.min(this.p1.sx, Math.min(this.p2.sx, otherP2.sx));
this.sy = Math.min(this.p1.sy, Math.min(this.p2.sy, otherP2.sy));
this.sw = Math.abs(this.p1.sx - Math.min(this.p2.sx, otherP2.sx));
this.sh = Math.abs(this.p1.sy - Math.min(this.p2.sy, otherP2.sy));
}
var sx = this.sx;
var sy = this.sy;
var sw = this.sw;
var sh = this.sh;
// DEBUG: IF THERE IS NO IMAGE TURN THIS ON:
//ctx.strokeStyle = 'red';
//ctx.strokeRect(sx, sy, sw, sh);
// IF we have a source and destination rectangle, then we can map an image
// piece using drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh)
// Only problem, we're not exactly dealing with rectangles....
// But we'll deal. Transformations have kooties anyways.
ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);
};