JavaScriptでのベクターエディターの開発(難点とアイデア)

背景:



この名前は、ウェブサイトの開発における素晴らしい経験(約15年)であり、プログラマーとして、私はルーチン作業が本当に好きではありません。それを避けるか、何らかの方法で最適化しようとしています。 言い換えると、ある時点でサイトを埋めるコンテンツを実行する必要がある場合(そう、プログラマがサイトを埋めるのは王族の仕事ではありませんが、別のケースがあります)、約4時間よりも着信データのパーサーを書くのに数時間かかりますデータを手動で。 そして、長い間、イメージマップを作成するための便利なエディターがないという問題に悩まされていました。 もちろん、Corel Drawなどでカードを描画し、SVGにアップロードして、目的の形式にすばやく変換できますが、サードパーティのプログラムをダウンロードせずに、サイトに直接読み込んで画像を選択できるようなエディターを作成する可能性に長い間興味がありましたその上に目的のカード。 たとえば、次のように、床の輪郭を選択し、JavaScriptイベントまたは単にリンクを添付する必要がある建物の特定の画像があります。









また、オブジェクトのアウトラインを手動で選択することに加えて、PhotoshopのMagic Wandに似たツールを使用して、マウスをつついて既製のアウトラインを作成したいと思います。 数年前からさまざまなマップエディター(オンラインとオフラインの両方)に出くわしましたが、同様の機能はそれらにありませんでした。 そうでない場合は、自分で作成します。



最終的に商用製品の顧客を見つけたため、残念ながら本格的なソースコードはありませんが、開発中に生じたアイデアや困難を可能な限り詳細に説明しようとします。さらに、グラフィックとインターフェイスの開発は専門としていません。 、それで、いくつかの「啓示」はばかげているか、またはばかでさえあるように見えるかもしれません:



エディターの機能定義:



  1. 手動で輪郭を作成するだけでなく、以前に作成した輪郭を編集できます。
  2. HTML MAP-AREA-SHAPEタグは、選択された領域のいくつかのタイプの形状をサポートしますが、POLYを使用して複雑なパスを作成することにのみ焦点を当てることが決定されました。
  3. 実際、プログラマとして私にとって興味深いのは、マウスを1回クリックするだけで、同じような色の領域を選択することでした。


CANVAS-何が必要ですか?



私はすでにCANVASタグの経験があり、その機能を表明していたため、それにこだわることに決めました(結局のところ、これはかなりの時間エディタの開発を遅らせた間違いでした)。



ループトラバーサルアルゴリズムの選択:



ループトラバーサルアルゴリズムのいくつかのオプションを試した後、最終的にMoor Neighborhoodを選択しました。 私の意見では、このアルゴリズムは作業速度と実装の十分な容易さをうまく組み合わせています。



だから:





回路を操作するためのテスト画像





まっすぐな側面の輪郭選択





歪んだ輪郭の選択



ご覧のとおり、ループトラバーサルアルゴリズムは優れた仕事をし、必要なものをすべて選択しますが、比較的小さな輪郭では直線にほぼ300ポイントが必要であり、何らかの理由で輪郭が軸の周りを回転する場合は50ポイント少なくなります。



原則として、今ではこの回路を記憶して操作することができますが、小さな回路であっても大量のデータにとって非常に混乱します。



完成した回路の最適化:



輪郭を操作するための次のスキームが選択されました。最初に、点から輪郭を作成し、節点(または方向の変化点)を除き、不要な輪郭を削除します。 一方では、二重の作業があり、他方では、このスキームは不要なポイントを削除するメカニズムのデバッグを簡素化します。



節点の選択:



表面にあるソリューション:

  1. 点を取り、それを節点(等高線点ではない)の配列に追加します。
  2. 開始点から順次ポイントをバイパスし、元と現在の角距離を測定します。角距離が特定の(実験的に決定された)より大きいか小さい場合、この点は新しい開始点であり、配列に追加します。


この解決策は機能しますが、角距離の計算は、角度を操作する「重い」機能の存在によって魂を苦しめました。 したがって、既存の「自転車」を調べることにしました。ここに、学校の数学から忘れられた解決策があります。 ベクトルのスカラー積です



私たちはそれを基礎としています-アルゴリズムはうまく機能し、何倍も高速です。



結果を見てみましょう:



13ポイント-かなり満足。





61点?! しかし、なぜ?!



そして、ここに理由があります:モニター、レチンなどの高解像度にもかかわらず、実際には画面上の線は壊れた点のセットであることを忘れました(しかし、約20年前、私は舌を突き出して線を引くことを習得しましたBresenhamアルゴリズムを使用...):





理論上の線は太字でマークされており、違いが目に付きます。



問題は一時的に特定の要因を導入することで解決しました。これにより、ポイント間の距離を比例的に増加させることができ(角距離を維持しながら)、ポイント間の差を滑らかにし、計算をより正確にすることができました。その結果、直線よりも61ポイントではなく23ポイントが得られましたが、今のところ十分です。



要約すると:







エディターの準備が整い、画像のアップロード、拡大縮小、マウスの移動、新しいオブジェクトの追加、既存のオブジェクトの編集が可能になり、すべてがSVGとCanvasの奇妙な混合物で機能します。



将来的には、CANVASでの苦痛と、SVG上のオブジェクトを使用した作業の翻訳、マップ上のオブジェクトとリスト内のオブジェクトの結合、およびこれらすべてが必要な理由について説明する予定です。



UPD:

Ramer-Douglas-Peckerアルゴリズムを使用してポイント数を最小化すると、結果が大幅に改善され、ノードポイントがより正確に決定されます。 アイデアをありがとうLevshinO



UPD:

ソースへの参照を含む、エディターの作成に関するストーリーの2番目の部分がレイアウトされています。



All Articles