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

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

新規登録して質問してみよう
ただいま回答率
85.48%
JavaScript

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

Q&A

解決済

1回答

1011閲覧

オブジェクトの座標変更

telwin

総合スコア8

JavaScript

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

0グッド

0クリップ

投稿2018/05/14 05:47

前回の質問の続きとなるのですが、
リンク内容
以下のようなオブジェクト(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;

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

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

サンプルソース

JavaScript

1var mParts_copy = { 2"type":"path", 3"attr":{ 4 "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", 5 "id":"id154", 6 "partstype":"Closed", 7 "stroke":"#000000", 8 "fill":"rgba(0,0,0,0.3)", 9 "style":"stroke-width: 2px; stroke-linecap: round; stroke-linejoin: round;" 10 } 11}; 12 13var positions = mParts_copy.attr.d.split('l'); 14positions[0] = 'M' + Point_x + ',' + Point_y; 15mParts_copy.attr.d = positions.join('l');

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

投稿2018/05/14 06:09

編集2018/05/14 07:18
tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

telwin

2018/05/14 06:58

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

2018/05/14 07:00

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

2018/05/14 07:04

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

2018/05/14 07: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とでるのですが、何かわかりますでしょうか?
telwin

2018/05/14 07:55

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

2018/05/14 08:00

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

2018/05/14 08:25 編集

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

2018/05/14 08:44

mParts_copy.attr を表示したときの挙動からして、実際には何らかのソフトを使っていて、その中で mCopy_attr というオブジェクトが定義されているはずです。 であれば、やりたかったことを処理できるようなメソッドが定義されている可能性があります。 通常、一般的なオブジェクトは表示しようとしたときに [object object] としか出ません。それが普通に出るということは、このオブジェクトが toString() メソッドを持っていて、その中で自身の情報を文字列化していると考えられます。
telwin

2018/05/14 09:48

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問