うしブログ

GeoGebraの使い方、応用など

(ひとことコメント)「基本的な使い方」更新作業中(2018.7.7)

(パンくずリスト整備状況)011解答まで済(2018.5.29)

「生徒向けワークシート」のアプレットに使われているオブジェクトの概要を取得するブックマーク

ブックマークレットによってJavaScriptを実行する方法(下記リンク先参照)により、「生徒向けワークシート」のアプレットに使われているオブジェクトの概要を取得する方法。

ブラウザのアドレスバーからJavaScriptのコードを実行する方法 (JavaScript疑似プロトコル)

 

ブックマークのURLには、下記をコピペする。

javascript:var thisApplet = window[document.getElementsByClassName("notranslate")[0].id];var beforeTag = document.getElementsByClassName("container")[0];var objList = thisApplet.getAllObjectNames();for (i = 0; i < objList.length; i++) {var objType = thisApplet.getObjectType(objList[i]);var objDef = thisApplet.getCommandString(objList[i],true);var objVal = thisApplet.getValueString(objList[i]);objList[i] = objType + '.' + objVal + ', definition: ' + objDef;} var stockList = '';for (var i=0;i<objList.length;i++){stockList += '<li>'+ objList[i] + '</li>';} beforeTag.insertAdjacentHTML('afterend','<div id="objprop">default</div>');document.getElementById("objprop").innerHTML = stockList;

 

動作例

f:id:usiblog:20180521090953g:plain

 

関数版

function writeProperty(){
  var thisApplet = window[document.getElementsByClassName("notranslate")[0].id];  // 対象アプレットを取得
  var beforeTag = document.getElementsByClassName("container")[0];  // アプレット格納用の要素を取得
  var objList = thisApplet.getAllObjectNames();  // アプレットの全オブジェクト名のリスト
  for (i = 0; i < objList.length; i++) {
    var objType = thisApplet.getObjectType(objList[i]);
    var objDef = thisApplet.getCommandString(objList[i],true);
    var objVal = thisApplet.getValueString(objList[i]);
    objList[i] = objType + '.' + objVal + ', definition: ' + objDef;
  }  // objListにオブジェクトタイプ・定義・値の情報を追加
  var stockList = '';
  for (var i=0; i<objList.length;i++){
    stockList += '<li>'+ objList[i] + '</li>';
  }  // objListの要素をHTMLリスト化
  beforeTag.insertAdjacentHTML('afterend','<div id="objprop">default</div>');  // アプレット格納用の要素の直後にdiv要素を追加
  document.getElementById("objprop").innerHTML = stockList;
}

カラースポイト_タッチデバイス対応版

(参考)グローバルJavaスクリプト記載内容

// グラフィックスビュー(canvas)を取得
var canvas = document.getElementsByTagName('canvas')[0];

// グラデーション描画の回数カウント用
var count;

function ggbOnInit() {
  // タップorクリック
  var clickOrTouchStart = window.ontouchstart===null?'touchstart':'click';

  // タップorマウスムーブ
  var mouseMoveOrTouchStart = window.ontouchstart===null?'touchstart':'mousemove';

  // イベントリスナー追加
  eventListenerAdder(clickOrTouchStart);
  eventListenerAdder(mouseMoveOrTouchStart);

  // 起動時に描画を実行
  Executor();
}

// イベントリスナー追加メソッドをまとめている
function eventListenerAdder(event){
  // ピクセルポイント描画を実行する用
  window.addEventListener(event, pixelPicker);
  canvas.addEventListener(event, pixelPicker);

  // グラデーションを描画する用
  window.addEventListener(event, Executor);
  canvas.addEventListener(event, Executor);

  //カラースポイト用
  window.addEventListener(event, Spuit);
  canvas.addEventListener(event, Spuit);
}

// 各種イベントプロパティ(x,y)を取得し、ピクセル点PixelPoint[x,y]を描画
function pixelPicker(event){
  // pageX, Yプロパティを取得
  var canvasPageX = event.pageX;
  var canvasPageY = event.pageY;

  // グラフィックスビュー左上隅の、ページ全体における位置を取得
  var clientRect = canvas.getBoundingClientRect();
  var rectX = window.pageXOffset + clientRect.left;  // スクロールした分+今表示されているウインドウからの距離
  var rectY = window.pageYOffset + clientRect.top;

  // グラフィックスビューの縮尺を取得
  var transformText = document.getElementsByClassName('applet_scaler')[0].style.transform;

  // 取得した変数の値をアプレット内のオブジェクトに書き込む
  ggbApplet.setValue('pageX', canvasPageX);
  ggbApplet.setValue('pageY', canvasPageY);
  ggbApplet.setValue('rectX', rectX);
  ggbApplet.setValue('rectY', rectY);
  ggbApplet.setTextValue('transformText', transformText);
  if(transformText == "none"){
    ggbApplet.evalCommand('SetValue[Ratio,(1,1)]');
  }  // 縮尺1のとき
  else{
    var editedText = transformText.slice(5);
    ggbApplet.evalCommand('SetValue[Ratio,'+editedText+']');
  }
}

function Executor(){
  count = 0;

// グラデーションを描きたい場合はコメントインしてください。

//  var ID = setInterval(function Drawer(){
//    count++;
//    var context = canvas.getContext('2d');
//    context.beginPath();
    // グラデーション領域をセット
//    var grad  = context.createLinearGradient(0,0,255,0);
    // 色をセット
//    grad.addColorStop(0,'rgb(255, 255, 255)');  // 白
//    grad.addColorStop(1,'rgb(0, 0, 0)');  // 黒
    // グラデーションをfillStyleプロパティにセット
//    context.fillStyle = grad;
    // 矩形を描画
//    context.rect(0,0,255,255);
//    context.fill();
    // 何回目の実行かをログに書き出す
//    console.log("イベント発生後"+count+"回目のグラデーション描画です。");
//    if(count > 100){
//      clearInterval(ID);
//    }
//  },1);
}

function Spuit(){
  var spuitX = ggbApplet.getValue('spuitX');
  var spuitY = ggbApplet.getValue('spuitY');
  var context = canvas.getContext('2d');

  // デバイスごとに調整用数値を設定
  var dRatioX = ggbApplet.getValue('ratioX');
  var dRatioY = ggbApplet.getValue('ratioY');
  var touchX = window.ontouchstart===null?dRatioX*2:dRatioX;  //なぜタッチデバイスのみ計数2が必要なのかは不明だが、とりあえずこれで揃う。
  var touchY = window.ontouchstart===null?dRatioY*2:dRatioY;

  var spuitImage = context.getImageData(spuitX*touchX, spuitY*touchY, 1, 1); 
  var r = spuitImage.data[0];
  var g = spuitImage.data[1];
  var b = spuitImage.data[2];
  console.log('spuitcolor is'+r+','+g+','+b+'.');
  ggbApplet.setValue('r',r);
  ggbApplet.setValue('g',g);
  ggbApplet.setValue('b',b);
  ggbApplet.evalCommand('SetBackgroundColor[text2,r/255,g/255,b/255]');
}

pageX / Yの値とマウス位置

はじめに

GeoGebraアプレットの描画を行っているcanvas要素

document.getElementsByTagName('canvas')[0]

にイベントリスナーを追加した場合における、mouseevent.pageXおよびmouseevent.pageYの値は、当該イベント発生時のマウスの、グラフィックスビューの左上隅からのピクセル座標の値とは、必ずしも一致しない。

これは、グラフィックスビューの左上隅と、当該グラフィックスビューが描画されているページの左上隅とが一致しないこと(生徒向けワークシートのページでは一致しない)や、グラフィックスビューが拡大・縮小されて表示されていること(ページの大きさがグラフィックスビューの大きさより小さい場合や、iframeによる埋め込みを利用する場合に起こりうる)が原因である。

そこで、pageX / Yのズレを解消するにはどうすれば良いかを検証したので、検証結果のアプレットを下記に示す。

なお、event.offsetXYには、上記のようなズレは生じないが、これはタッチデバイスには使えないので、検証対象外とする。

 

 検証結果のアプレット

「生徒向けワークシート」のページ:

https://www.geogebra.org/m/e7DXQ6Bp

 

グローバルJavaスクリプトの内容(参考)

// グラフィックスビュー(canvas)を取得
var canvas = document.getElementsByTagName('canvas')[0];

function ggbOnInit() {
  // タッチデバイスのときはタップ、マウスでバイスのときはクリックをリッスン
  var clickOrTouchStart = window.ontouchstart===null?'touchstart':'click';
  canvas.addEventListener(clickOrTouchStart, pixelPicker);
}

function pixelPicker(event){
  // pageX, Yプロパティを取得
  var canvasPageX = event.pageX;
  var canvasPageY = event.pageY;

  // グラフィックスビュー左上隅の、ページ全体における位置を取得
  var clientRect = canvas.getBoundingClientRect();
  var rectX = window.pageXOffset + clientRect.left;  // スクロールした分+今表示されているウインドウからの距離
  var rectY = window.pageYOffset + clientRect.top;

  // グラフィックスビューの縮尺を取得
  var transformText = document.getElementsByClassName("applet_scaler")[0].style.transform;

  // 取得した変数の値をアプレット内のオブジェクトに書き込む
  ggbApplet.setValue('pageX', canvasPageX);
  ggbApplet.setValue('pageY', canvasPageY);
  ggbApplet.setValue('rectX', rectX);
  ggbApplet.setValue('rectY', rectY);
  ggbApplet.setTextValue('transformText', transformText);
  if(transformText == "none"){
    ggbApplet.evalCommand('SetValue[Ratio,(1,1)]');
  }  // 縮尺1のとき
  else{
    var editedText = transformText.slice(5);
    ggbApplet.evalCommand('SetValue[Ratio,'+editedText+']');
  }
}