IT

SVG의 호 경로로 원 그리기

lottoking 2020. 6. 23. 07:04
반응형

SVG의 호 경로로 원 그리기


짧은 질문 : SVG 경로를 사용하면 원의 99.99 %를 그릴 수 있지만 표시되지만 원의 99.99999999 % 인 경우 원이 표시되지 않습니다. 어떻게 고칠 수 있습니까?

다음 SVG 경로는 99.99 %의 원을 그릴 수 있습니다. ( http://jsfiddle.net/DFhUF/1381/에서 시도하고 4 개의 호 또는 2 개의 호만 보이는지 확인하십시오. 그러나 IE 인 경우에는 SVG가 아닌 VML로 렌더링되지만 비슷한 문제가 있음)

M 100 100 a 50 50 0 1 0 0.00001 0

그러나 원의 99.99999999 % 일 때 아무것도 표시되지 않습니까?

M 100 100 a 50 50 0 1 0 0.00000001 0    

그리고 그것은 100 %의 원과 동일합니다 (아직도 호는 아닙니다, 아주 완전한 호입니다)

M 100 100 a 50 50 0 1 0 0 0 

어떻게 고칠 수 있습니까? 그 이유는 함수를 사용하여 호의 백분율을 그리고 원 함수를 사용하기 위해 99.9999 % 또는 100 % 호를 "특별한 경우"해야한다면 어리석은 일입니다.

다시 RaphaelJS를 사용하는 jsfiddle의 테스트 케이스는 http://jsfiddle.net/DFhUF/1381/에 있습니다
(IE 8의 VML 인 경우 두 번째 원조차 표시되지 않습니다 ...로 변경해야합니다) 0.01)


최신 정보:

우리 시스템에서 점수에 대해 호를 렌더링하기 때문에 3.3 점이 원의 1/3을 얻습니다. 0.5는 반원을 얻었고 9.9 점은 99 %의 원을 얻습니다. 하지만 시스템에 9.99 점을 받으면 어떻게해야합니까? 원의 99.999 %에 가까운 지 확인하고 그에 따라 arc함수 또는 함수를 사용해야 circle합니까? 그렇다면 9.9987 점은 어떻습니까? 어느 것을 사용해야합니까? 어떤 종류의 점수가 "너무 완전한 원"에 매핑되고 원 기능으로 전환되는지, 그리고 원의 "특정 99.9 %"또는 9.9987 점수 인 경우 아크 기능을 사용하는 것은 어리석은 일입니다 .


XAML의 아크와 동일합니다. a로 99.99 % 호를 닫으면 Z원이 생깁니다!


나는 그것이 게임에서 조금 늦었다는 것을 알고 있지만, 새로운 질문과 비슷한 딜레마가 있었을 때 부터이 질문을 기억했으며 누군가가 여전히 하나를 찾고 있다면 우연히 "올바른"해결책을 찾았습니다.

<path 
    d="
    M cx cy
    m -r, 0
    a r,r 0 1,0 (r * 2),0
    a r,r 0 1,0 -(r * 2),0
    "
/>

다시 말해, 이것은 :

<circle cx="100" cy="100" r="75" />

이 경로로 달성 할 수 있습니다 :

  <path 
        d="
        M 100, 100
        m -75, 0
        a 75,75 0 1,0 150,0
        a 75,75 0 1,0 -150,0
        "
  />

비결은 두 개의 호를 갖는 것입니다. 두 번째 호는 첫 번째가 중단 된 곳에서 집어 들고 음의 직경을 사용하여 원래의 호 시작점으로 돌아갑니다.

하나의 원호에서 완전한 원으로 할 수없는 이유는 (그리고 나는 단지 추측하고 있습니다) 당신이 그 자체에서 (150,150이라고 말합시다) 자신에게 (150,150이라고 말하면서) 호를 그리도록 지시하기 때문입니다. "아, 나는 이미 거기에 있으며, 아크가 필요하지 않습니다!".

내가 제공하는 솔루션의 장점은 다음과 같습니다.

  1. 원에서 경로로 직접 쉽게 번역 할 수 있습니다.
  2. 두 개의 호 선이 겹치지 않습니다 (마커 나 패턴 등을 사용하는 경우 문제가 발생할 수 있음). 깨끗하고 연속적인 선이지만 두 조각으로 그려져 있습니다.

텍스트 패스가 모양을 허용하도록 허용하는 경우이 중 어느 것도 중요하지 않습니다. 그러나 원과 같은 모양 요소에는 기술적으로 "시작"점이 없기 때문에 솔루션을 피하고 있다고 생각합니다.

jsfiddle 데모 : http://jsfiddle.net/crazytonyi/mNt2g/

최신 정보:

textPath참조 경로를 사용하고 호의 외부 가장자리에 텍스트를 렌더링하려는 경우 정확히 동일한 방법을 사용하지만 스위프 플래그를 0에서 1로 변경하여 외부의 외부를 처리합니다. 내부 대신 표면으로 경로를 지정하십시오 ( 1,0누군가가 중심에 앉아서 원을 그리며 1,1반경 거리에서 중심을 돌아 다니면서 옆에 분필을 끌면 도움이됩니다). 위의 코드가 있지만 변경 사항이 있습니다.

<path 
    d="
    M cx cy
    m -r, 0
    a r,r 0 1,1 (r * 2),0
    a r,r 0 1,1 -(r * 2),0
    "
/>

Anthony의 솔루션과 관련하여 경로를 얻는 함수는 다음과 같습니다.

function circlePath(cx, cy, r){
    return 'M '+cx+' '+cy+' m -'+r+', 0 a '+r+','+r+' 0 1,0 '+(r*2)+',0 a '+r+','+r+' 0 1,0 -'+(r*2)+',0';
}

완전히 다른 접근법 :

svg에서 호를 지정하기 위해 경로를 모으는 대신 의사 코드로 원 요소를 사용하고 획-타자 레이를 지정할 수도 있습니다.

with $score between 0..1, and pi = 3.141592653589793238

$length = $score * 2 * pi * $r
$max = 7 * $r  (i.e. well above 2*pi*r)

<circle r="$r" stroke-dasharray="$length $max" />

Its simplicity is the main advantage over the multiple-arc-path method (e.g. when scripting you only plug in one value and you're done for any arc length)

The arc starts at the rightmost point, and can be shifted around using a rotate transform.

Note: Firefox has an odd bug where rotations over 90 degrees or more are ignored. So to start the arc from the top, use:

<circle r="$r" transform="rotate(-89.9)" stroke-dasharray="$length $max" />

Adobe Illustrator uses bezier curves like SVG, and for circles it creates four points. You can create a circle with two elliptical arc commands...but then for a circle in SVG I would use a <circle /> :)


It's a good idea that using two arc command to draw a full circle.

usually, I use ellipse or circle element to draw a full circle.


Building upon Anthony and Anton's answers I incorporated the ability to rotate the generated circle without affecting it's overall appearance. This is useful if you're using the path for an animation and you need to control where it begins.

function(cx, cy, r, deg){
    var theta = deg*Math.PI/180,
        dx = r*Math.cos(theta),
        dy = -r*Math.sin(theta);
    return "M "+cx+" "+cy+"m "+dx+","+dy+"a "+r+","+r+" 0 1,0 "+-2*dx+","+-2*dy+"a "+r+","+r+" 0 1,0 "+2*dx+","+2*dy;
}

Written as a function, it looks like this:

function getPath(cx,cy,r){
  return "M" + cx + "," + cy + "m" + (-r) + ",0a" + r + "," + r + " 0 1,0 " + (r * 2) + ",0a" + r + "," + r + " 0 1,0 " + (-r * 2) + ",0";
}

These answers are much too complicated.

A simpler way to do this without creating two arcs or convert to different coordinate systems..

This assumes your canvas area has width w and height h.

`M${w*0.5 + radius},${h*0.5}
 A${radius} ${radius} 0 1 0 ${w*0.5 + radius} ${h*0.5001}`

Just use the "long arc" flag, so the full flag is filled. Then make the arcs 99.9999% the full circle. Visually it is the same. Avoid the sweep flag by just starting the circle at the rightmost point in the circle (one radius directly horizontal from the center).


For those like me who were looking for an ellipse attributes to path conversion:

const ellipseAttrsToPath = (rx,cx,ry,cy) =>
`M${cx-rx},${cy}a${rx},${ry} 0 1,0 ${rx*2},0a${rx},${ry} 0 1,0 -${rx*2},0`

Another way would be to use two Cubic Bezier Curves. That's for iOS folks using pocketSVG which doesn't recognize svg arc parameter.

C x1 y1, x2 y2, x y (or c dx1 dy1, dx2 dy2, dx dy)

Cubic Bezier curve

The last set of coordinates here (x,y) are where you want the line to end. The other two are control points. (x1,y1) is the control point for the start of your curve, and (x2,y2) for the end point of your curve.

<path d="M25,0 C60,0, 60,50, 25,50 C-10,50, -10,0, 25,0" />

i made a jsfiddle to do it in here:

function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0;

return {
x: centerX + (radius * Math.cos(angleInRadians)),
y: centerY + (radius * Math.sin(angleInRadians))
};
}

function describeArc(x, y, radius, startAngle, endAngle){

var start = polarToCartesian(x, y, radius, endAngle);
var end = polarToCartesian(x, y, radius, startAngle);

var largeArcFlag = endAngle - startAngle <= 180 ? "0" : "1";

var d = [
    "M", start.x, start.y, 
    "A", radius, radius, 0, largeArcFlag, 0, end.x, end.y
].join(" ");

return d;       
}
console.log(describeArc(255,255,220,134,136))

link

all you need to do is to change the input of console.log and get the result in console

참고URL : https://stackoverflow.com/questions/5737975/circle-drawing-with-svgs-arc-path

반응형