天啊!好问题!
那么让我们看看我们有什么。一个具有一堆“约束”的系统,这些“约束”是 2 个点的集合。约束本身成对出现,它们形成两条线,形成一条┘
形状(盒子的右下角)。
如果我们单独绘制每条约束线,我们会看到:
这都是水平的红线和垂直的蓝线。画一个我们就可以看到┘
形状,每条长红线实际上是数百条小线,每条线的底部┘
形状,端对端。有数百个┘
就在这里,它们一起使它看起来像一个有凝聚力的网格。事实上,每个人都已经是独立的,这对我们来说很容易。
这个形状就是我们确定某种边界框所需的全部。而且看起来每个Point
in a Constraint
带有原始值,所以我们将它们保存为sx
and sy
.
如果我们知道盒子在新位置的边界,并且我们知道原始边界,因为我们已经保存了约束的所有点值,那么我们应该是黄金。
一旦我们有了 Constraint 的原始边界框及其当前边界框,我们所要做的就是使用这两个框调用 drawImage :ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);
我写了一个新的Constraint.prototype.draw
例程,看起来像这样:
等等。
有几种方法可以“修补”漏洞,这完全取决于您,否则您将不得不进行转换。
看一下代码。我没有改变太多。寻找!!!
在代码中(我的编辑)和DEBUG:
在代码中(调试代码,以防图像未加载或您想查看线框)。
http://jsfiddle.net/simonsarris/Kuw6P/ http://jsfiddle.net/simonsarris/Kuw6P/
代码很长,所以我不想将其全部粘贴到这里,但这里有一个备份,以防 jsfiddle 出现故障:https://gist.github.com/simonsarris/5405304 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's 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);
};