質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.74%

  • JavaScript

    15231questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

オブジェクトの座標変更

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 91

telwin

score 2

前回の質問の続きとなるのですが、
リンク内容
以下のようなオブジェクト(mParts_copy)のデータの、
M172,422l-1,の部分をMxxx,yyyl-1,に変えたいと思っております。
xxxとyyyの部分は画面をクリックした時のクリックした座標の値になります。
(M100,200l-1, や M150,300l-1,などクリック位置により変わる)

この場合、xxxの変数名がPoint_x、yyyの変数名がPoint_yとした時、
どのようにコーディングしたらオブジェクトmParts_copyの座標に反映させることができるのでしょうか?
前回の質問でいただいた回答によりますと、{obj}.attr.dの部分は文字列とのことでした。

mParts_copyをconsole.logで表示した値

{"type":"path","attr":{"d":"M172,422l-1,0l-5,0l-3,0l-10,0l-7,0l-6,0l-8,0l-5,-4l-11,-6l-6,-4l-5,-10l-3,-5l-1,-16l0,-11l0,-23l0,-12l1,-3l3,-3l5,0l5,0l16,-1l14,0l20,0l17,0l21,0l13,6l10,6l7,8l8,9l4,8l3,7l0,5l0,5l0,2l0,3l-2,0l-5,2z","id":"id154","partstype":"Closed","stroke":"#000000","fill":"rgba(0,0,0,0.3)","style":"stroke-width: 2px; stroke-linecap: round; stroke-linejoin: round;"}} 

前回の質問時は以下のようにしようと考えていましたが、
記載の通りエラーとなっておりました。

var serchIndex = mParts_copy.attr.d.indexOf("l");
var front_str = targetString.substring(0,29);
var back_str = targetString.slice(serchIndex);
var data = front_str + Point_x + "," + Point_y + back_str;
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

0

座標データのフォーマットが正しく理解できていないような気がします。
ぱっと見、こういうデータのように見えます。

  • 基本的には x,y を指定していて、それらを l でつないでいる
  • 先頭が M の場合は絶対座標を、M がついていない場合は直前からの相対座標を表している
  • y 座標の後に z がついたらそこでパス終了

上の例で言えば、座標(172,422)を基点として、以下(171,422), (166,422), ... とつないで、最後が(241,385)になるようです。

正しくやるのであれば、このフォーマットを解析して座標の配列を作るべきでしょう。

文字列としてみたとき、各座標は l で区切られますから、d.split('l') で各々x,y の形の文字列の配列に分割できます。
その先頭が変更したい座標になりますから、そこに新しい座標を表す文字列を入れ直し、最後にこの配列から元の文字列に戻す(Array.join)ことで、正しく修正できるでしょう。

参考:MDN JavaScript
String.split
Array.join

サンプルソース

var mParts_copy = {
"type":"path",
"attr":{
  "d":"M172,422l-1,0l-5,0l-3,0l-10,0l-7,0l-6,0l-8,0l-5,-4l-11,-6l-6,-4l-5,-10l-3,-5l-1,-16l0,-11l0,-23l0,-12l1,-3l3,-3l5,0l5,0l16,-1l14,0l20,0l17,0l21,0l13,6l10,6l7,8l8,9l4,8l3,7l0,5l0,5l0,2l0,3l-2,0l-5,2z",
  "id":"id154",
  "partstype":"Closed",
  "stroke":"#000000",
  "fill":"rgba(0,0,0,0.3)",
  "style":"stroke-width: 2px; stroke-linecap: round; stroke-linejoin: round;"
  }
};

var positions = mParts_copy.attr.d.split('l');
positions[0] = 'M' + Point_x + ',' + Point_y;
mParts_copy.attr.d = positions.join('l');

これで普通に mParts_copy(の中の attr.d) が更新されてますが……

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/14 15:58

    わかりやすい説明ありがとうございます。
    リンクについても確認させていただきました。
    コードにd.split('l');をいれてみるとCan't find variable: dとエラーが出ました。
    指定の仕方が間違っているのでしょうか。
    ちなみに、とりあえず先頭の配列のM172,422l-1,の部分だけでも先に書き変えて動かしてみたいのですが、その場合の指定の方法はどういたらよいでしょうか?
    調べてみましたがわかりませんでした。

    キャンセル

  • 2018/05/14 16:00

    d は当然この元のオブジェクトの attr.d ですから、ただ d と書いてもそんな変数はありませんよ。
    mParts_copy.attr.d.split('l') になります。

    キャンセル

  • 2018/05/14 16:04

    そうですよね。
    そのように指定しても「'undefined' is not an object (evaluating 'mParts_copy.attr.d.split')」とエラーとなったのでd.split('l');を試してみました。
    何か間違いがあるのか、調べてみます。

    キャンセル

  • 2018/05/14 16:31 編集

    「'undefined' is not an object (evaluating 'mParts_copy.attr.d.split')」のエラーが解決できませんでした。
    mParts_copy.attr.dを表示するとundefinedとなりました。
    しかし、mParts_copy.attrを表示するとfunction (a,c){var d=this,f=d.node;if(!a){if(1!=f.nodeType)return{text:f.nodeValue};for(var g=f.attributes,h={},i=0,j=g.length;j>i;i++)h[g[i].nodeName]=g[i].nodeValue;return h}if(e(a,"string")){if(!(arguments.length>1))return b("snap.util.getattr."+a,d).firstDefined();var k={};k[a]=c,a=k}for(var l in a)a[z](l)&&b("snap.util.attr."+l,d,a[l]);return d}
    2018-05-14 16:28:44.644406+0900 Burner[78946:2904940] fncClickEventOn inとでるのですが、何かわかりますでしょうか?

    キャンセル

  • 2018/05/14 16:55

    追記ありがとうございます。
    内容確認しました。
    わたしはmacでxcodeを使用して修正し,確認はxcodeのシミュレータのiPad(5th generation)を使用しているからなにか影響があるのでしょうか?

    キャンセル

  • 2018/05/14 17:00

    当問題も解決しましたのでこれで閉じたいと思います。
    エラーの件は別途質問したいと思います。
    ありがとうございました。

    キャンセル

  • 2018/05/14 17:22 編集

    すみません。
    わかったら教えてほしいのですが、記載していただいたサンプルコードの15行目までの内容と、私がここの質問で記載している「mParts_copyをconsole.logで表示した値 」はおなじですが、変数にオブジェクトの情報を仮に入れた時と、実際のオブジェクトの情報とでは動きが違ってくることはないでしょうか?

    キャンセル

  • 2018/05/14 17:44

    mParts_copy.attr を表示したときの挙動からして、実際には何らかのソフトを使っていて、その中で mCopy_attr というオブジェクトが定義されているはずです。
    であれば、やりたかったことを処理できるようなメソッドが定義されている可能性があります。

    通常、一般的なオブジェクトは表示しようとしたときに [object object] としか出ません。それが普通に出るということは、このオブジェクトが toString() メソッドを持っていて、その中で自身の情報を文字列化していると考えられます。

    キャンセル

  • 2018/05/14 18:48

    通常の動きではないのですね。
    教えていただき助かります。
    そのあたりは調査してみます。
    ありがとうございました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.74%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    15231questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。