svg的行程质量/抗锯齿

时间:2014-09-29 00:42:12

标签: javascript jquery svg snap.svg

我试图使用svgs制作一个动画语音泡泡,但我注意到笔画上的抗锯齿缺乏清晰度并且有明显的污点。我试图通过舍入计算来解决这个问题,但这只会使污点变得更糟 - 我该怎样做才能获得1px厚的黑色硬线?

HTML:

<div id="inset">
    <svg id="svg" width="100%" height="100%"></svg>
</div>

CSS:

body, html {
    width: 100%;
    height: 100%;
    border: 0;
    padding: 0;
    margin: 0;
}

#inset {
 width: 20%;
 height: 50%;
 position: absolute;
 bottom: 0;
 left: 50%;
}

#svg {
}

javascipt的:

$(function() {

    var sponsorBubble = function(el, html, cornerRad) {
        this.html = html,
        this.width = el.parent().width(),
        this.x_center = (el.parent().width()/2),
        this.height = el.parent().height(),
        this.arrowWidth = (el.parent().width()/4),
        this.arrowHeight = (el.parent().height()/8),
        this.cornerRad = cornerRad,
        this.arrowRad = this.cornerRad/3,
        this.arrowControlRatio = this.arrowRad * ((this.arrowWidth/2 - (this.arrowRad*2)) / (this.arrowHeight - (this.arrowRad*2)));

        var bubble = s.path(
            "M" +
            Math.round(this.x_center)
            + ", " +
            Math.round(this.height)
            + ", Q" +
            Math.round(this.x_center - this.arrowRad)
            + ", " +
            Math.round(this.height)
            + ", " +
            Math.round(this.x_center - this.arrowRad)
            + ", " +
            Math.round(this.height - this.arrowRad)
            + ", Q" +
            Math.round(this.x_center - this.arrowRad)
            + ", " +
            Math.round(this.height - (this.arrowRad*2))
            + ", " +
            Math.round(this.x_center)
            + ", " +
            Math.round(this.height - (this.arrowRad*2))
            + ", Q" +
            Math.round(this.x_center + this.arrowRad)
            + ", " +
            Math.round(this.height - (this.arrowRad*2))
            + ", " +
            Math.round(this.x_center + this.arrowRad)
            + ", " +
            Math.round(this.height - this.arrowRad)
            + ", Q" +
            Math.round(this.x_center + this.arrowRad)
            + ", " +
            Math.round(this.height)
            + ", " +
            Math.round(this.x_center)
            + ", " +
            Math.round(this.height)
            + ", Z"
        );

        bubble.attr({ 
            stroke: 'black',
            fill: 'none'
        });

        bubble.animate({
            d:
                "M" + 
                Math.round(this.x_center)
                + ", " +
                Math.round(this.height)
                + ", Q" +
                Math.round(this.x_center - this.arrowRad + this.arrowControlRatio)
                + ", " +
                Math.round(this.height)
                + ", " +
                Math.round(this.x_center - this.arrowRad)
                + ", " +
                Math.round(this.height - this.arrowRad)
                + ", L" +
                Math.round(this.x_center - (this.arrowWidth/2) + this.arrowRad)
                + ", " +
                Math.round(this.height - this.arrowHeight + this.arrowRad)
                + ", Q" +
                Math.round(this.x_center - (this.arrowWidth/2) + this.arrowRad - this.arrowControlRatio)
                + ", " +
                Math.round(this.height - this.arrowHeight)
                + ", " +
                Math.round(this.x_center - (this.arrowWidth/2))
                + ", " +
                Math.round(this.height - this.arrowHeight)
                + ", L" +
                Math.round(this.cornerRad)
                + ", " +
                Math.round(this.height - this.arrowHeight)
                + ", Q" +
                0
                + ", " +
                Math.round(this.height - this.arrowHeight)
                + ", " +
                0
                + ", " +
                Math.round(this.height - this.arrowHeight - this.cornerRad)
                + ", L" +
                0
                + ", " +
                Math.round(this.cornerRad)
                + ", Q" +
                0
                + ", " +
                0
                + ", " +
                Math.round(this.cornerRad)
                + ", " +
                0
                + ", L" +
                Math.round(this.width - this.cornerRad)
                + ", " +
                0
                + ", Q" +
                Math.round(this.width)
                + ", " +
                0
                + ", " +
                Math.round(this.width)
                + ", " +
                Math.round(this.cornerRad)
                + ", L" +
                Math.round(this.width)
                + ", " +
                Math.round(this.height - this.arrowHeight - this.cornerRad)
                + ", Q" +
                Math.round(this.width)
                + ", " +
                Math.round(this.height - this.arrowHeight)
                + ", " +
                Math.round(this.width - this.cornerRad)
                + ", " +
                Math.round(this.height - this.arrowHeight)
                + ", L" +
                Math.round(this.x_center + (this.arrowWidth/2))
                + ", " +
                Math.round(this.height - this.arrowHeight)
                + ", Q" +
                Math.round(this.x_center + (this.arrowWidth/2) - this.arrowRad + this.arrowControlRatio)
                + ", " +
                Math.round(this.height - this.arrowHeight)
                + ", " +
                Math.round(this.x_center + (this.arrowWidth/2) - this.arrowRad)
                + ", " +
                Math.round(this.height - this.arrowHeight + this.arrowRad)
                + ", L" +
                Math.round(this.x_center + this.arrowRad)
                + ", " +
                Math.round(this.height - this.arrowRad)
                + ", Q" +
                Math.round(this.x_center + this.arrowRad - this.arrowControlRatio)
                + ", " +
                Math.round(this.height)
                + ", " +
                Math.round(this.x_center)
                + ", " +
                Math.round(this.height)
                + ", Z"
            }, 
            100
        );

    };


s = Snap('#svg');

var bubble_obj = new sponsorBubble($('#svg'), "test_content", 15);
});

jdfiddle: http://jsfiddle.net/L5k48hwm/

2 个答案:

答案 0 :(得分:1)

svg path { // or rect, circle, etc
    shape-rendering: crispEdges;
}

话虽如此,您可以尝试使用jQuery UI .animate()来创建类似于此jsfiddle示例的效果(反转此动画以匹配您的规范)。这避免了复杂的路径生成和更平滑的线条。

更新:这是代码段。

&#13;
&#13;
$('div').append('<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" x="0.00000000" y="0.00000000" width="100%" height="100%" id="svg3" viewbox="0 0 1000 600" >  <path fill="#FFFFFF" stroke="#000000" stroke-width="10" d="M916.902,397.331c14.126,0,17.344-9.739,17.344-9.739   c0-27.635,7.992-42.357,26.927-42.357c0,0,13.702,1.668,13.702-14.946c0-0.001,0.619-43.408-1.901-141.244   c-2.514-97.836-9.537-109.333-9.537-109.333c0-14.125-9.129-13.284-9.129-13.284c-24.67,0-53.406,4.151-53.406-30.893   c0,0,1.558-11.866-15.041-11.866c0,0-159.78-14.301-423.823-14.301c-264.041,0-375.12,2.352-375.12,2.352   c-14.125,0-13.284,9.136-13.284,9.136c0,22.479-13.575,42.622-30.319,42.622c0,0-13.705,0.341-13.705,16.949   c0,0-4.551,60.914-4.551,117.724c0,56.808,4.551,126.899,4.551,126.899c0,14.125,9.127,13.28,9.127,13.28   c24.9,0,29.944,10.568,29.944,30.322c0,0,1.038,15.744,25.709,15.744l248.677,5.155c0,0,46.81,25.855,64.76,39.665   c17.952,13.808,27.714,26.235,12.526,41.426c-6.669,6.666-11.966,12.474-9.571,21.187c2.277,8.256,26.797,22.168,29.903,23.746   c0.261,0.127,61.957,30.323,84.796,41.37c16.646,8.047,33.288,16.074,49.292,25.362c2.152,1.253,14.271,9.614,16.804,7.089   c2.484-2.479-11.174-12.959-12.823-14.315c-9.084-7.442-16.206-16.462-24.158-25.027c-12.481-13.465-25.133-26.788-37.746-40.133   c-7.044-7.464-13.884-15.167-21.144-22.43c-1.791-1.79-1.476-4.571,0.699-7.001c7.682-8.531,25.246-28.013,27.384-30.14   c2.739-2.731-1.814-7.121-1.814-7.121l-62.959-51.678L916.902,397.331z"/>  </svg>');

$('div').draggable({
    handle: 'rect'
});

$('div').animate({
    width: "500px",
    height: "300px",
    top: "0px",
    left: "0px"
}, 2000).animate({
    width: "100px",
    height: "60px",
    top: "240px",
    left: "230px"
}, 2000);
&#13;
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>
<div style="width:100px; height:60px; border:solid thin #888; padding:0px; border-radius:4px; background-color:yellow; top:240px; left:230px">
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

我认为要获得漂亮的弯角,你需要做两件事:

  1. 改进您的路径生成算法。这是因为当您放大SVG时,您可以看到拐角处的路径宽度变大。我没有时间或专业知识来帮助解决这个问题。
  2. 尝试为shape-rendering CSS property使用不同的值。它们可以为您提供更加清晰的渲染效果。