帆布避免锯齿状边缘

时间:2014-06-10 19:41:21

标签: javascript html5 canvas

大家好日子:

我正在为牙医建立一个申请表。我使用了插图画家绘制了牙齿图并用一个众所周知的插件导出它。结果太棒了。然后我开始探索插件生成的代码(约3000行)。

这是插件生成的代码的一部分

ctx.save();
ctx.beginPath();
ctx.moveTo(67.9, 113.9);
ctx.bezierCurveTo(67.9, 113.9, 69.9, 89.8, 67.9, 78.8);
ctx.bezierCurveTo(65.9, 67.8, 61.1, 58.8, 58.9, 55.4);
ctx.bezierCurveTo(56.7, 52.0, 54.3, 50.4, 53.6, 49.8);
ctx.bezierCurveTo(52.9, 49.2, 51.1, 48.2, 50.7, 49.8);
ctx.bezierCurveTo(50.3, 51.4, 50.7, 54.8, 50.7, 54.8);
ctx.bezierCurveTo(50.7, 54.8, 47.7, 54.0, 47.5, 55.2);
ctx.bezierCurveTo(47.3, 56.4, 47.1, 57.6, 47.5, 65.6);
ctx.bezierCurveTo(47.9, 73.6, 48.0, 81.4, 47.3, 86.4);
ctx.bezierCurveTo(46.5, 91.4, 42.6, 102.5, 42.6, 102.5);
ctx.lineTo(41.3, 108.1);
ctx.lineTo(47.7, 111.3);
ctx.lineTo(55.0, 113.9);
ctx.lineTo(61.9, 113.9);
ctx.lineTo(67.1, 113.9);
gradient = ctx.createLinearGradient(63.4, 65.4, 53.9, 97.3);
gradient.addColorStop(0.00, "rgb(255, 255, 255)");
gradient.addColorStop(1.00, "rgb(172, 171, 148)");
ctx.fillStyle = gradient;
ctx.fill();

http://jsfiddle.net/Artynok/qL79Y/4/

我的想法是为每个牙齿着色,因为DB存储的数据带有相关信息(病态=>红色,愈合=>蓝色,外部治疗=>紫色)。我创建了一个JSON obj来存储整个代码中渐变的所有坐标,使用一些PHP代码我可以获得所有的渐变数据(ctx.createLinearGradient和RadialGradient)。

在绘制之前多次尝试影响代码之后,我决定在我的JSON上编写存储操作,同时绘制正在进行。所以当画布结束绘制牙齿的一部分时,我抓住渐变坐标,找到带有颜色状态的OBJ并与之匹配:

http://jsfiddle.net/Artynok/qL79Y/3/

直到这里一切正常,除非因为图形得到了渐变但是有锯齿状的线条。我知道我正在重新划过牙齿,即使牙齿有临床状态,因为如果我没有命令以正常颜色进行涂抹,那么其余的牙齿就会开始变得最后一种颜色我已经用过了。

有没有办法去除"擦除"旧的渐变放置新的渐变或改变颜色而不是重绘它?

3 个答案:

答案 0 :(得分:2)

当我在做一个进度条插件时,我必须处理画布质量,事实是画布是光栅图形,这意味着质量永远不会是完美的或非常可扩展的。由于您使用Illustrator导出图形,您是否考虑过使用SVG?它具有相当不错的浏览器支持,因为它的矢量图形始终是最好的质量。

答案 1 :(得分:2)

你可以尝试一种黑客攻击(它不会真正解决锯齿状边缘的问题,但会改善视网膜显示器的外观)。

如果您将图像设为2x,并且通孔CSS会恢复到正常尺寸并且看起来会更好。

JS:

canvas.width = 600;
canvas.height = 600;

CSS:

canvas{
  margin:0 auto;
  background:#333;
  width:300px;
  height:300px;
}

http://jsfiddle.net/qL79Y/6/

答案 2 :(得分:-1)

我解决了这个问题。据我所知,我在同一个图形上绘制了很多次,我对径向和线性渐变重绘段进行了双重检查。使用taht值来玩我的循环正在进行不必要的重绘。我逐个传递了绘制操作中每个段的每个值。这将花费我太多时间重新改造,但结果是值得的。

setGradient :   function(p,datos,z){//<-- now i'm passing the values instead to loop
        //dos caminos o radial o linear dependiendo quien tenga datos
        a = 0;
        b = 0;
        c = 0;
        d = 0;
        //for(z in this[p]){ <-- this was the cause of the pain in the head
            if(datos[p].estClin){
                //diente enfermo
                if(datos[p].estClin == "enfermo"){
                    if(z != "boundaries" && z != "data"){
                        console.log(z,p);
                        if(this[p][z]['linearCoord'].length != 0){
                            arrCord = this[p][z]['linearCoord'];
                            grad = this[p][z].draw.createLinearGradient(arrCord[0],arrCord[1],arrCord[2],arrCord[3]);
                        }else if(this[p][z]['radialCoord'].length != 0){
                            arrCord = this[p][z]['radialCoord'];
                            grad = this[p][z].draw.createRadialGradient(arrCord[0],arrCord[1],arrCord[2],arrCord[3],arrCord[4],arrCord[5]);
                        }
                        this.setColor(this[p][z].draw,grad,"rgb(255, 136, 136)");
                    }

                }else if(datos[p].estClin == "tratado" && datos[p].externo == "no"){
                    if(z != "boundaries" && z != "data"){
                        if(this[p][z]['linearCoord'].length != 0){
                            arrCord = this[p][z]['linearCoord'];
                            grad = this[p][z].draw.createLinearGradient(arrCord[0],arrCord[1],arrCord[2],arrCord[3]);
                        }else if(this[p][z]['radialCoord'].length != 0){
                            arrCord = this[p][z]['radialCoord'];
                            grad = this[p][z].draw.createRadialGradient(arrCord[0],arrCord[1],arrCord[2],arrCord[3],arrCord[4],arrCord[5]);
                        }
                        this.setColor(this[p][z].draw,grad,"rgb(93, 138, 232)");
                    }
                //tratado externo
                }else if(datos[p].estClin == "tratado" && datos[p].externo == "si"){
                    if(z != "boundaries" && z != "data"){
                        if(this[p][z]['linearCoord'].length != 0){
                            arrCord = this[p][z]['linearCoord'];
                            grad = this[p][z].draw.createLinearGradient(arrCord[0],arrCord[1],arrCord[2],arrCord[3]);
                        }else if(this[p][z]['radialCoord'].length != 0){
                            arrCord = this[p][z]['radialCoord'];
                            grad = this[p][z].draw.createRadialGradient(arrCord[0],arrCord[1],arrCord[2],arrCord[3],arrCord[4],arrCord[5]);
                        }
                        this.setColor(this[p][z].draw,grad,"rgb(142, 108, 209)");
                    }
                }
            }else{
                if(z != "boundaries" && z != "data"){
                    if(this[p][z]['linearCoord'].length != 0){
                        arrCord = this[p][z]['linearCoord'];
                        grad = this[p][z].draw.createLinearGradient(arrCord[0],arrCord[1],arrCord[2],arrCord[3]);


                    }else if(this[p][z]['radialCoord'].length != 0){
                        arrCord = this[p][z]['radialCoord'];
                        grad = this[p][z].draw.createRadialGradient(arrCord[0],arrCord[1],arrCord[2],arrCord[3],arrCord[4],arrCord[5]);
                    }
                    this.setColor(this[p][z].draw,grad,"rgb(172, 171, 148)");

                }
            }
            //Aqui tratamos la info de los dientes a mostrar

        //}

http://jsfiddle.net/Artynok/qL79Y/9/

现在grapgh正在通过99.99%的清洁,但它完全可以接受 无论如何,谢谢大家!!