簡単な質問: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%の円弧を「特殊な場合」に使用してcircle関数を使用する必要がある場合、それは一種のばかげたことです。
繰り返しますが、RaphaelJSを使用したjsfiddleのテストケースは http://jsfiddle.net/DFhUF/1381/ にあります。
(およびIE 8のVMLの場合、2番目の円も表示されません... 0.01に変更する必要があります)
更新:
これは、システムでスコアの円弧をレンダリングしているため、3.3ポイントが円の3分の1を取得するためです。 0.5は円の半分を取得し、9.9ポイントは円の99%を取得します。しかし、システムに9.99のスコアがある場合はどうでしょうか?円の99.999%に近いかどうかを確認し、それに応じてarc
関数またはcircle
関数を使用する必要がありますか?それでは、9.9987のスコアはどうですか?どちらを使用しますか?どのような種類のスコアが「完全な円」にマッピングされ、円関数に切り替わり、それが円の「特定の99.9%」または9.9987スコアの場合、アーク関数を使用する必要があるのはばかげている。
XAMLのアークでも同じです。 Z
で99.99%の円弧を閉じると、円ができます!
ゲームが少し遅れていることは知っていますが、この質問を覚えたのは、それが新しくて、同様のディレンマがあったときのことです。誰かがまだ探しているなら、誤って「正しい」解決策を見つけました。
<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
"
/>
トリックは、2つのアークを使用することです。2番目のアークは最初のアークが中断したところからピックアップし、負の直径を使用して元のアーク開始点に戻ります。
1つの円弧で完全な円として行うことができない理由は(そして私は推測しているだけです)それはあなたがそれ自身(例えば150,150)からそれ自体(150,150)に円弧を描くようにそれを伝えるためです「ああ、私はすでにそこにいます、アークは必要ありません!」.
私が提供しているソリューションの利点は次のとおりです。
テキストパスが図形を受け入れることを許可するだけであれば、これは問題になりません。しかし、円のような形状要素には技術的に「開始」点がないため、彼らはその解決策を避けていると思います。
jsfiddleデモ: http://jsfiddle.net/crazytonyi/mNt2g/
textPath
参照のパスを使用しており、テキストを円弧の外側のエッジにレンダリングする場合は、まったく同じ方法を使用しますが、sweep-flagを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
"
/>
アンソニーのソリューションに関して、パスを取得する関数は次のとおりです。
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でアークを指定する代わりに、擬似コードでcircle要素を取得してstroke-dasharrayを指定することもできます。
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" />
そのシンプルさは、複数のアークパス方式に対する主な利点です(たとえば、スクリプトを作成するときに、1つの値のみをプラグインし、アークの長さについては完了です)
円弧は右端のポイントから始まり、回転変換を使用して移動できます。
注:Firefoxには、90度以上の回転が無視されるという奇妙なバグがあります。したがって、上からアークを開始するには、次を使用します。
<circle r="$r" transform="rotate(-89.9)" stroke-dasharray="$length $max" />
Adobe IllustratorはSVGのようなベジェ曲線を使用し、円の場合は4つのポイントを作成します。 2つの 楕円弧コマンド ...で円を作成できますが、SVGの円では<circle />
を使用します:)
アンソニーとアントンの答えに基づいて、生成された円を全体的な外観に影響を与えずに回転させる機能を組み込みました。これは、アニメーションのパスを使用していて、アニメーションの開始位置を制御する必要がある場合に便利です。
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;
}
2つのarcコマンドを使用して完全な円を描くことをお勧めします。
通常、楕円または円要素を使用して完全な円を描きます。
関数として書かれており、次のようになります。
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";
}
これらの答えは非常に複雑です。
2つの円弧を作成したり、異なる座標系に変換したりせずにこれを行う簡単な方法。
これは、キャンバス領域の幅がw
および高さh
であることを前提としています。
`M${w*0.5 + radius},${h*0.5}
A${radius} ${radius} 0 1 0 ${w*0.5 + radius} ${h*0.5001}`
「長い円弧」フラグを使用するだけで、完全なフラグが埋められます。次に、円弧を99.9999%の完全な円にします。視覚的には同じです。スイープフラグを避けるには、円の右端のポイント(中心から直接水平に1つの半径)で円を開始するだけです。
パス変換の楕円属性を探していた私のような人のために:
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`
別の方法は、2つの立方ベジェ曲線を使用することです。これは、svg arcパラメーターを認識しない pocketSVG を使用するiOSユーザー向けです。
C x1 y1、x2 y2、x y(またはc dx1 dy1、dx2 dy2、dx dy)
ここの最後の座標セット(x、y)は、ラインを終了する場所です。他の2つはコントロールポイントです。 (x1、y1)は曲線の開始点の制御点であり、(x2、y2)は曲線の終点の制御点です。
<path d="M25,0 C60,0, 60,50, 25,50 C-10,50, -10,0, 25,0" />
ここでそれを行うためにjsfiddleを作成しました:
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))
あなたがする必要があるのは、console.logの入力を変更し、コンソールで結果を取得することです