うしブログ

うしブログ

趣味で運営する、GeoGebraの専門ブログ。

(作業メモ)StartPoint要検証(2行の場合;テキスト変更時未定義問題)

(要修復)ToggleButton・RollPolygonWithoutSlipping・貯金時計・直感力トレーニング

テキストの幅に応じて自動改行する

テキストの幅に応じて自動改行する – GeoGebra

 

上記リンク先のアプレットは、下図のように、テキストの幅を指定して、それに応じてテキストを自動的に改行します。

f:id:usiblog:20190321020531g:plain

 

(参考)グローバルJavaスクリプト
//指定したテキストの、現在の設定のもとでの幅ピクセル数を取得
function getTextWidth(textToMeasure){
  ggbApplet.evalCommand('USITEXT=\"'+textToMeasure+'\"');
  var actualWidth = ggbApplet.getValue('x(Corner[USITEXT, 2]) - x(Corner[USITEXT, 1])');
  var ratio = ggbApplet.getValue('(x(Corner[5]) + 2) / (x(Corner[2]) - x(Corner[1]))');
  var textWidth = Math.round(actualWidth*ratio);
  ggbApplet.deleteObject('USITEXT');
  return textWidth;
}

//既存のテキストオブジェクトの幅ピクセル数を取得
function getTextObjWidth(textObjName){
  var actualWidth = ggbApplet.getValue('x(Corner['+textObjName+', 2]) - x(Corner['+textObjName+', 1])');
  //console.log(actualWidth);
  var ratio = ggbApplet.getValue('(x(Corner[5]) + 2) / (x(Corner[2]) - x(Corner[1]))');
  //console.log(ratio);
  var textWidth = Math.round(actualWidth*ratio);
  return textWidth;
}


//幅の上限に応じて自動改行したテキストオブジェクトを生成
function widthCappedText(textObjName, maxWidth){

  //アウトプットオブジェクトを作成
  ggbApplet.deleteObject(textObjName+'Capped');
  ggbApplet.evalCommand(textObjName+'Capped=CopyFreeObject['+textObjName+']');
  
  //文字列データを取得
  var currentData = ggbApplet.getValueString(textObjName+'Capped');
  //console.log('currentData = '+currentData);

  //1文字ずつ改行した場合の幅(幅の最小値)を取得、フェイルセーフ
  //var textSimplified = currentData.replace(/\r?\n/g,"");
  var textSimplified = currentData;
  var arr = textSimplified.split('');
  var textVert = arr.join('\n');
  //console.log('textVert = '+textVert);
  //console.log('textVert.length = '+textVert.length);
  ggbApplet.setTextValue(textObjName+'Capped', textVert);
  var minWidth = getTextObjWidth(textObjName+'Capped');
  if(minWidth > maxWidth){return 'これ以上幅を狭く出来ませんので、処理を停止しました。';}
  ggbApplet.setTextValue(textObjName+'Capped', currentData);

  //幅を測定
  var totalWidth = getTextObjWidth(textObjName+'Capped');
  //console.log('totalWidth = '+totalWidth);
  if(totalWidth <= maxWidth){return 'テキスト幅が指定の値を下回っているので、処理を停止しました。';}  //短くて改行不要のとき

  //maxWidthを超えないギリギリの文字数を測定
  var sliceIndex = 0;
  var currentWidth = totalWidth;
  do{
    do{
      sliceIndex++;
      if(sliceIndex > textVert.length){return 'ループを終了しました。現在のsliceIndexは、'+sliceIndex+'です。';}
      ggbApplet.setTextValue(textObjName+'Capped', currentData.slice(0,sliceIndex));
      currentWidth = getTextObjWidth(textObjName+'Capped');
    }while (currentWidth <= maxWidth);
    //console.log('sliceIndex = '+sliceIndex);
    currentData = currentData.slice(0,sliceIndex-1)+'\n'+currentData.slice(sliceIndex-1);
    ggbApplet.setTextValue(textObjName+'Capped', currentData);
    totalWidth = getTextObjWidth(textObjName+'Capped');
    //console.log('totalWidth = '+totalWidth);
  }while (totalWidth >= maxWidth);
  return true;
}