結局、SCADAサーバーはWindowsサービスとして実行されます。 OPCサーバーから技術データを取得します。 サーバーでhttp要求を処理するには、idhttpServerコンポーネントを使用します。 クライアント側では、ニーモニックがブラウザに表示されます。 グラフィックスのみSVG。そのため、スキーム自体がユーザーの画面の解像度に変更されます。
したがって、エディターに必要なもの:
- 単純な図形の描画:長方形、円、線、テキスト。
- 他のより高度なエディターで作成された既製のSVG画像を挿入します。
- 形状のサイズ変更、画面上でのマウスの移動、キーボードの矢印の移動。
- コピー/貼り付け/削除。
- 機器から受信したデータへのオブジェクトのバインド(IDによる)。
- ファイルに保存し、ファイルから開きます。
これはすべて、Windows用のエディターを作成することで実現できます。 ただし、小さなSVG画像をレンダリングするのは困難でした。 ニーモニックダイアグラムをブラウザに表示したら、ブラウザに描画してみませんか? 結局のところ、ブラウザは最高のSVGであり、レンダリングします。
ここでfabric.jsが見つかりましたが、これらはほとんどこれらの目的のために思いつきました。
単純な要素の追加、コピー、貼り付けは簡単に行われ、すべてドキュメントに記載されているとおりです。 ここには持っていきません。
しかし、SVG画像の挿入とコピーでは、すべてがスムーズに進みません。 次に、fabric.jsのバグを回避する方法を説明します。
完成したSVG画像をキャンバスに埋め込むには、2つの方法があります。
- SVG画像全体が全体として(グループ化されて)挿入されます
- 画像はグループ化されずにすぐに挿入されます。 各要素は個別に移動できます。
主な問題は、
<rect x="0" y="0"
SVG要素に
transform="translate(168 202)"
プロパティがある場合、SVGがキャンバスの座標
168 202
で描画され、サイズ変更のポインターが表示されることです。座標
x="0" y="0"
別の場所に表示されます。
これから判断すると、彼は生まれてからそんなに痛い。 そこで、すでにグループ化されたSVG画像を挿入します。
var addShape = function(shapeName) { fabric.loadSVGFromURL('./assets/' + shapeName + '.svg', function(objects, options) { var loadedObject = fabric.util.groupSVGElements(objects, options); loadedObject.set({ left: 0, top: 0, angle: 0 }) .setCoords(); canvas.add(loadedObject); }); };
コピー/貼り付け時に同じバグ(または機能?)が表示されます。 SVGを使用した標準のクローン方法は機能しません。 挿入するとき、サイズ変更のポインタは挿入された画像と一致しないため、最初に元の画像の座標を0にします。
canvas.getActiveGroup().setTop(0); canvas.getActiveGroup().setLeft(0);
次に、表示された画像がテキスト形式で表示され、テキストから新しい画像が作成され、元の画像の座標が復元されます。
内部バッファーにコピー:
CopyClip = function() { var activeObject = canvas.getActiveObject(), activeGroup = canvas.getActiveGroup(); if (activeGroup) { var tx_top = canvas.getActiveGroup().getTop(); var tx_left = canvas.getActiveGroup().getLeft(); var tx_Angle = canvas.getActiveGroup().getAngle(); canvas.getActiveGroup().setAngle(0); canvas.getActiveGroup().setTop(0); canvas.getActiveGroup().setLeft(0); var tx = canvas.getActiveGroup().toSVG(); tx = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">' +tx+ '</svg>'; canvas.getActiveGroup().setAngle(tx_Angle); canvas.getActiveGroup().setTop(tx_top); canvas.getActiveGroup().setLeft(tx_left); var _loadSVG = function(svg) { fabric.loadSVGFromString(svg, function(objects, options) { var obj = fabric.util.groupSVGElements(objects, options); canvas.add(obj).centerObject(obj).renderAll(); obj.setCoords(); }); } var _loadSVGWithoutGrouping = function(svg) { fabric.loadSVGFromString(svg, function(objects) { canvas.add.apply(canvas, objects); canvas.renderAll(); }); }; Buff_clipb = tx; canvas.getActiveGroup().setAngle(tx_Angle); } else if (activeObject) { var tx_top = canvas.getActiveObject().getTop(); var tx_left = canvas.getActiveObject().getLeft(); var tx_Angle = canvas.getActiveObject().getAngle(); canvas.getActiveObject().setAngle(0); canvas.getActiveObject().setTop(0); canvas.getActiveObject().setLeft(0); var tx = canvas.getActiveObject().toSVG(); tx = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">' +tx+ '</svg>'; canvas.getActiveObject().setAngle(tx_Angle); canvas.getActiveObject().setTop(tx_top); canvas.getActiveObject().setLeft(tx_left); var _loadSVG = function(svg) { fabric.loadSVGFromString(svg, function(objects, options) { var obj = fabric.util.groupSVGElements(objects, options); canvas.add(obj).centerObject(obj).renderAll(); obj.setCoords(); }); } Buff_clipb = tx; canvas.getActiveObject().setAngle(tx_Angle); }; };
内部バッファーから貼り付け:
PasteClip = function() { var _loadSVG = function(svg) { fabric.loadSVGFromString(svg, function(objects, options) { var obj = fabric.util.groupSVGElements(objects, options); canvas.add(obj).centerObject(obj).renderAll(); obj.setCoords(); }); } _loadSVG(Buff_clipb); };
線画では、物事もスムーズに進みません。 fabric.jsのラインの太さはラインの長さに依存しますが、これはかなり奇妙です。 したがって、行をSVGとして挿入します。
行挿入
function addLineGoriz(wid) { var wid2; wid2 = $("#spinner[name=Line_widht_value]").spinner("value"); console.log('Line_widht_value ', wid2); var SVGValue_txt; if (tek_Stroke_color[0] != "#") { tek_Stroke_color = "#"+tek_Stroke_color}; var Stroke_col = tek_Stroke_color; SVGValue_txt = "<Line x1=\"370\" y1=\"90\" x2=\"570\" y2=\"90\" style=\"stroke: "+Stroke_col+"; stroke-width:"+wid2 +"px;\" />"; SVGValue_txt = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">' +SVGValue_txt+ '</svg>'; var _loadSVGWithoutGrouping = function(svg) { fabric.loadSVGFromString(svg, function(objects) { canvas.add.apply(canvas, objects); canvas.renderAll(); }); }; _loadSVGWithoutGrouping(SVGValue_txt); };
矢印でキーボードを移動すると非常に便利です。
それは簡単に行われます:
$(document).keydown(function(eventObject){ var activeObject = canvas.getActiveObject(), activeGroup = canvas.getActiveGroup(); if ($("[name=Line_widht_value]").is(":focus")) { var val_width=$( "#spinner[name=Line_widht_value]" ).spinner("value"); if (activeObject) { activeObject.setStrokeWidth(val_width); } } if ($("[name=opacity_value]").is(":focus")) { var val_width=$( "[name=opacity_value]" ).spinner("value"); if (activeObject) { activeObject.set("opacity",val_width); } } if ($("[name=font_size_value]").is(":focus")) { var val_size=$( "#spinnerfont[name=font_size_value]" ).spinner("value"); if (activeObject) { activeObject.set('fontSize',val_size); } } if ((!($("[name=nameobj]").is(":focus")))&& (!($("[name=Line_widht_value]").is(":focus")))&& (!($("[name=opacity_value]").is(":focus")))&&(!($("[name=nametxt]").is(":focus")))&& (!($("[name=font_size_value]").is(":focus"))) ) { if (activeGroup) { if (eventObject.which == 37) { activeGroup.setLeft(activeGroup.getLeft()-1); } if (eventObject.which == 39) { activeGroup.setLeft(activeGroup.getLeft()+1); } if (eventObject.which == 38) { activeGroup.setTop(activeGroup.getTop()-1); } if (eventObject.which == 40) { activeGroup.setTop(activeGroup.getTop()+1); } if (eventObject.which == 46) { var objectsInGroup = activeGroup.getObjects(); canvas.discardActiveGroup(); objectsInGroup.forEach(function(object) { canvas.remove(object); }); } if (eventObject.which == 67) { CopyClip(); } if (eventObject.which == 86) { PasteClip(); } } else if (activeObject) { if (eventObject.which == 37) { activeObject.setLeft(activeObject.getLeft()-1); } if (eventObject.which == 39) { activeObject.setLeft(activeObject.getLeft()+1); } if (eventObject.which == 38) { activeObject.setTop(activeObject.getTop()-1); } if (eventObject.which == 40) { activeObject.setTop(activeObject.getTop()+1); } if (eventObject.which == 46) { canvas.remove(activeObject); } if (eventObject.which == 67) { CopyClip(); } if (eventObject.which == 86) { PasteClip(); } } } });
SCADAシステムのタグへのバインドは、要素のIDを介して実行されます。
function setIDObj() { var activeObject = canvas.getActiveObject(); if (activeObject) { activeObject.set({ id : $("input[name=nameobj]").val() }); } };
SCADAでは、テキストテキストフィールドを使用して、任意の画像のアナログ値を表示します。 画像は色または透明度を変更します。 つまり 2つのイメージを作成し、1つをオン状態に、もう1つを無効に添付します。 状態がオンの場合、最初の画像を透明度1、2番目の画像を0に設定します。
保存中。 SVG形式で保存します。
canvas.toSVG().
は
canvas.toSVG().
使用します
canvas.toSVG().
新しいタブで模倣物を開く:
rasterizeSVG = function() { window.open( 'data:image/svg+xml;utf8,' + encodeURIComponent(canvas.toSVG())); };
ファイルから開く:
var Loadfromfile = function(shapeName) { fabric.loadSVGFromURL(shapeName + '.svg', function(objects, options) { canvas.add.apply(canvas, objects); canvas.renderAll(); }); };
完全にグループ化されていないファイルからSVGを読み込みます。 そして、プロパティ
transform="translate(XY)"
要素には、左上隅にサイズ変更のためのポインターがあり、画像自体はX Y座標にあることがわかります。
Webサーバーは、
translate
座標をリセットし、それらを
x="X" y="Y"
translate
する松葉杖を作成する必要があります。
エディターのWebサーバーでは、ニーモニックはPOSTメソッドを使用して保存されます。
第二部の継続。