- 注册时间
- 2013-2-13
- 最后登录
- 2023-10-13
- 阅读权限
- 200
- 积分
- 9360
- 精华
- 1
- 帖子
- 2411
    
|
发表于 2017-5-16 12:13:51
|显示全部楼层
有不少人通过各种方式问我关于drawTriangles出现白线的问题,这其实是一个老问题了
用过drawTriangles的朋友,大多都看过我的一篇文章
HTML5高级编程之图形扭曲及其应用
http://lufylegend.com/forum/forum.php?mod=viewthread&tid=94
drawTriangles函数的原理就如下图这样,将两次变形通过clip裁剪一下,然后接在一起

但是,canvas的clip有个不足,就是对接起来并不那么完美,两个clip之间出现了一条缝,所以drawTriangles最终的效果会是这样

这就尴尬了....
而其实这一效果在不同浏览器中也是不一样的,有的浏览器会好一些,我一直在等待浏览器自身的完善,能够解决这个问题
但是很长时间过去了,估计这个问题不一定会被修复了,实际上图片扭曲是咱们自己要这么做的,人家clip的用途也并不是为了实现这个效果,所以,还是自己想想办法如何才能解决吧
要说完美的解决方案,我一时也想不到(也不是一时了,好几年了都...),不过投机取巧的方案倒是有的,比如像下面这样

左边的三角形,如图,把其中三角形的两个点分别移动,将三角形扩大,我们多画一部分,这样和第二个三角形对接的时候,那条缝就会被遮住
而右边的三角形,我们采取同样的方法,把其中一个点移动,也将三角形扩大,实际上右边的三角形比较麻烦,因为和这个三角形对接的是下一组三角形(两个三角形是一组,这个应该不用我多做解释了),而且这个点一旦移动,变形效果就会有偏差
另外,我为了说明效果,移动的距离比较远,实际代码中我们必须只能移动一个单位或者两个单位,否则变形就会出现较大的偏差
好了,原理就是这个原理了,接下来修改drawTriangles的代码部分- LGraphics.prototype.drawTriangles = function (ve, ind, u, tn, lco) {
- var s = this;
- var i, j, l = ind.length, c;
- s.setList.push(function (c) {
- var v = ve, a, k, sw;
- for (i = 0, j = 0; i < l; i += 3) {
- a = 0;
- c.save();
- c.beginPath();
- c.moveTo(v[ind[i] * 2], v[ind[i] * 2 + 1]);
- c.lineTo(v[ind[i + 1] * 2] + (i % 6 == 0 ? 1 : 0), v[ind[i + 1] * 2 + 1]);
- c.lineTo(v[ind[i + 2] * 2] + (i % 6 == 0 ? 0 : 2), v[ind[i + 2] * 2 + 1] + 2);
- c.lineTo(v[ind[i] * 2], v[ind[i] * 2 + 1]);
- c.closePath();
- if (tn) {
- c.lineWidth = tn;
- c.strokeStyle = lco;
- c.stroke();
- }
- c.clip();
- if (i % 6 == 0) {
- sw = -1;
- var w = (u[ind[i + 1 + j] * 2] - u[ind[i + j] * 2]) * s.bitmap.width;
- var h = (u[ind[i + 2] * 2 + 1] - u[ind[i] * 2 + 1]) * s.bitmap.height;
- if (j == 0 && w < 0) {
- for (k = i + 9; k < l; k += 3) {
- if (u[ind[i + 2] * 2 + 1] == u[ind[k + 2] * 2 + 1]) {
- j = k - i;
- break;
- }
- }
- if (j == 0) {
- j = l - i;
- }
- w = (u[ind[i + 1 + j] * 2] - u[ind[i + j] * 2]) * s.bitmap.width;
- }
- if (i + j >= l) {
- w = (u[ind[i + j - l] * 2] - u[ind[i + 1] * 2]) * s.bitmap.width;
- sw = u[ind[i] * 2] == 1 ? 0 : s.bitmap.width * u[ind[i] * 2] + w;
- if (sw > s.bitmap.width) {
- sw -= s.bitmap.width;
- }
- } else {
- sw = s.bitmap.width * u[ind[i + j] * 2];
- }
- sh = s.bitmap.height * u[ind[i] * 2 + 1];
- if (h < 0) {
- h = (u[ind[i + 2 - (i > 0 ? 6 : -6)] * 2 + 1] - u[ind[i - (i > 0 ? 6 : -6)] * 2 + 1]) * s.bitmap.height;
- sh = 0;
- }
- if(sw > 0){
- sw -= 1;
- }
- if(sh > 0){
- sh -= 1;
- }
- var t1 = (v[ind[i + 1] * 2] - v[ind[i] * 2]) / w;
- var t2 = (v[ind[i + 1] * 2 + 1] - v[ind[i] * 2 + 1]) / w;
- var t3 = (v[ind[i + 2] * 2] - v[ind[i] * 2]) / h;
- var t4 = (v[ind[i + 2] * 2 + 1] - v[ind[i] * 2 + 1]) / h;
- c.transform(t1, t2, t3, t4, v[ind[i] * 2], v[ind[i] * 2 + 1]);
- w += 1;
- h += 1;
- c.drawImage(s.bitmap.image,
- s.bitmap.x + sw,
- s.bitmap.y + sh,
- w, h,
- 0, 0,
- w, h);
- } else {
- var w = (u[ind[i + 2 + j] * 2] - u[ind[i + 1 + j] * 2]) * s.bitmap.width;
- var h = (u[ind[i + 2] * 2 + 1] - u[ind[i] * 2 + 1]) * s.bitmap.height;
- if (j == 0 && w < 0) {
- for (k = i + 9; k < l; k += 3) {
- if (u[ind[i + 2] * 2 + 1] == u[ind[k + 2] * 2 + 1]) {
- j = k - i;
- break;
- }
- }
- if (j == 0) {
- j = l - i;
- }
- w = (u[ind[i + 2 + j] * 2] - u[ind[i + 1 + j] * 2]) * s.bitmap.width;
- }
- if (i + 1 + j >= l) {
- w = (u[ind[i + 1 + j - l] * 2] - u[ind[i + 2] * 2]) * s.bitmap.width;
- sw = u[ind[i + 1] * 2] == 1 ? 0 : s.bitmap.width * u[ind[i + 1] * 2] + w;
- if (sw > s.bitmap.width) {
- sw -= s.bitmap.width;
- }
- } else {
- sw = s.bitmap.width * u[ind[i + 1 + j] * 2];
- }
- sh = s.bitmap.height * u[ind[i] * 2 + 1];
- if (h < 0) {
- h = (u[ind[i + 2 - (i > 0 ? 6 : -6)] * 2 + 1] - u[ind[i - (i > 0 ? 6 : -6)] * 2 + 1]) * s.bitmap.height;
- sh = 0;
- }
- var t1 = (v[ind[i + 2] * 2] - v[ind[i + 1] * 2]) / w;
- var t2 = (v[ind[i + 2] * 2 + 1] - v[ind[i + 1] * 2 + 1]) / w;
- var t3 = (v[ind[i + 2] * 2] - v[ind[i] * 2]) / h;
- var t4 = (v[ind[i + 2] * 2 + 1] - v[ind[i] * 2 + 1]) / h;
- c.transform(t1, t2, t3, t4, v[ind[i + 1] * 2], v[ind[i + 1] * 2 + 1]);
- c.drawImage(s.bitmap.image,
- s.bitmap.x + sw,
- s.bitmap.y + sh,
- w+2, h+2,
- 0, -h,
- w+2, h+2);
- }
- c.restore();
- }
- });
- };
复制代码 具体改了什么,大家自己对照下引擎源码吧
把这段代码加到你的js里就能覆盖引擎中的处理了,引擎下次更新我会把它加进去(不要问引擎什么时候更新,我保证引擎不会死了...)
说了半天效果如何呢,看下图吧


对照下上面的图,虽然不算完美,是不是效果也好了很多了 |
|