2017-02-09 74 views
0

一个线I需要绘制线在SVG在给定的宽度,例如20像素。图出偏移到SVG

我想才达到什么是绘制另一条线,什么线宽度为原有线路的一半,重叠原线,但不是在市中心,但左对齐/底部。

所以,如果我的x1x2为原线为30,则新行x1x2是25,因为左右宽度为5

Here is a jsFiddle我想才达到的。

UPDATE在jsfiddle上线路正常,因为x1 == x2,但是当线路不是水平或垂直时,我遇到问题。

我使用下面的代码来计算出新线xy坐标,但总是有一点差距。

棘手的部分是当我想要旋转该行。

我不明白,哪里是错误的,也许某个地方与角度的功能呢?

或者是好的,只是SVG/HTML是不够严谨?

<?php 
//Init coordinates and thick 
$x1 = 30; $y1 = 20; 
$x2 = 230; $y2 = 270; 

$lineThick = 20; 
//get the new data 
$newData = getNewPositions($x1, $y1, $x2, $y2, $lineThick); 

function getNewPositions($x1, $y1, $x2, $y2, $thick) { 
    $offset = $thick/4; 
    $new['x1'] = $x1; 
    $new['y1'] = $y1; 
    $new['x2'] = $x2; 
    $new['y2'] = $y2; 
    if ($y1 == $y2) { 
     $new['y1'] = $y1 - $offset; 
     $new['y2'] = $y2 - $offset; 
     return $new; 
    } 
    if ($x1 == $x2) { 
     $new['x1'] = $x1 - $offset; 
     $new['x2'] = $x2 - $offset; 
     return $new; 
    } 

    $a = abs($y2 - $y1); 
    $b = abs($x2 - $x1); 
    $c = sqrt(pow($a,2) + pow($b,2)); 

    $modX = sin($a/$c); 
    $modY = sin($b/$c); 

    $new['x1'] = $x1 - ($offset * $modX); 
    $new['x2'] = $x2 - ($offset * $modX); 
    $new['y1'] = $y1 + ($offset * $modY); 
    $new['y2'] = $y2 + ($offset * $modY); 

    return $new; 
} 

echo '<?xml version="1.0" encoding="UTF-8" standalone="no"?>' . "\n"; 
?> 
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
<svg width="300" height="300" viewBox="0 0 300 300" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink"> 
    <g> 
     <line x1="<?php echo $x1; ?>" y1="<?php echo $y1; ?>" x2="<?php echo $x2; ?>" y2="<?php echo $y2; ?>" style="stroke-width:<?php echo $lineThick; ?>; stroke: #000;" /> 
     <line x1="<?php echo $newData['x1']; ?>" y1="<?php echo $newData['y1']; ?>" x2="<?php echo $newData['x2']; ?>" y2="<?php echo $newData['y2']; ?>" style="stroke-width:<?php echo $lineThick/2; ?>; stroke: #0f0;" /> 
    </g> 
</svg> 
+0

似乎是好的形式,我站在哪里。我在本地复制了你的js和你的php,看起来像[this](http://i.imgur.com/8uTevGI.png) - 左边是js,右边是php。对于PHP我已经使用了以下内容:'$ x1 = 200; $ y1 = 20; $ x2 = 200; $ y2 = 270;' – Andrew

+0

是的,那好,如果你看到,当x1 = x2或y1 = y2。但试试我的'$ x1 = 30; $ y1 = 20; $ x2 = 230; $ y2 = 270;' – vaso123

+0

你是指时髦的[蓝线](http://i.imgur.com/gn0VU19.png)? – Andrew

回答

2

SVG像素完美的计算

svg { 
 
    width: 500px; 
 
}
<svg viewBox="0 0 100 100"> 
 
    <text x="10" y="8" font-size="5">Example</text> 
 
    <g> 
 
    <line x1="20" y1="10" x2="20" y2="20" stroke="green" stroke-width="20" /> 
 
    <line x1="25" y1="10" x2="25" y2="20" stroke="yellow" stroke-width="10" /> 
 
    </g> 
 
    <text x="10" y="24" font-size="5">Now if you zoom your browser</text> 
 
    <text x="10" y="28" font-size="5">the end line should change visibility!</text> 
 
    <text x="10" y="32" font-size="5">How to fix?</text> 
 
    <g> 
 
    <line x1="20" y1="35" x2="20" y2="45" stroke="green" stroke-width="20" /> 
 
    <line x1="25" y1="34.9" x2="25" y2="45.1" stroke="yellow" stroke-width="10.2" /> 
 
    </g> 
 
    <text x="10" y="50" font-size="5">Make it .2 point bigger so that</text> 
 
    <text x="10" y="55" font-size="5">there is no pixel perfect calculation</text> 
 
</svg>

至于为什么发生这种情况以及SVG在默认情况下响应于各种规模100%,所以有大量的计算为浏览器如何显示不同的形状和在这个过程中一些像素得到四舍五入至关闭可能的,如果我没有记错,有些时候是半个像素。

+0

所以这不是我的错我如何计算,但我已经达到了在HTML中呈现这个SVG的可能性? – vaso123

+0

@ vaso123它只是这个svg适合任何屏幕尺寸,所以渲染是超级灵活的,并不总是像素完美。 – Persijn

1

这是我能拿出最好的。我不确定这是否正确,但我希望它能让你走上正确的道路。

我在本地使用您的上述PHP代码,我已经来到了确切同样的结论。某些像素“关闭”。

enter image description here

唯一合乎逻辑的结论,我可以跟(比在代码中的bug等)是你在做arrhythmical操作时丢失精度。

所以我试图ceil()floor()一些值。附近有一座小涉足之后,我修改了这个:

$new['x1'] = $x1 - ($offset * $modX); 
$new['x2'] = $x2 - ($offset * $modX); 
$new['y1'] = $y1 + ($offset * $modY); 
$new['y2'] = $y2 + ($offset * $modY); 

要这样:

$new['x1'] = floor($x1 - ($offset * $modX)); 
$new['x2'] = floor($x2 - ($offset * $modX)); 
$new['y1'] = ceil($y1 + ($offset * $modY)); 
$new['y2'] = ceil($y2 + ($offset * $modY)); 

而最终的结果是:

enter image description here

虽然不完美这是非常密切的。我只能假设其他操作的精度会丢失。


这是不是一个真正的答案,但正如我所说,我希望它让你在正确的道路上。

+0

谢谢你的努力,+1,但将其从20改为100. – vaso123

+0

该死的。那么,我试过 - .- – Andrew