うしブログ

うしブログ

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

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

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

マウス/指位置の真下の描画をワイプ表示する

 

wipe – GeoGebra

タッチデバイスで、指の真下の描画を確認できるよう、ワイプ表示する実験です。

 

グローバルJavaScript

function ggbOnInit() {
  insertCanvasOnlyCanvasTag();

  //usicanvasのイベントリスナを設定
  var usicanvas = document.getElementsByClassName('usicanvas')[0];
  var evt = window.ontouchstart===null?'touchmove':'mousemove';
  usicanvas.addEventListener(evt, scanImage);

//  document.getElementsByClassName('usicanvas')[0].hidden = true;  //usicanvasを非表示(GeoGebraオブジェクトをクリックできない問題を回避。

}

//マウス・指位置周辺のGV1ピクセルデータをusicanvasにコピー
function scanImage(evt){
  evt.preventDefault();

  //取得
  var canvas = document.getElementsByTagName('canvas')[0];
  var context = canvas.getContext('2d');
  var centerX = getEventData(evt)[0];
  var centerY = getEventData(evt)[1];
  var gv1ImageData = context.getImageData(centerX-40, centerY-40, 80, 80);

  //クリア
  var usicanvas = document.getElementsByClassName('usicanvas')[0];
  clearCanvas(usicanvas);

  //描画
  var usiContext = usicanvas.getContext('2d');
  usiContext.putImageData(gv1ImageData, 0, 0);

  //枠線
  usiContext.strokeStyle="blue";  //線の色を青に指定
  usiContext.strokeRect(0, 0, 80, 80);

}

//canvasを指定して、描画をクリア
function clearCanvas(canvas){
  if (canvas.getContext) {
    var context = canvas.getContext('2d');
    //描画をクリア
    context.clearRect(0, 0, canvas.width, canvas.height);
  }
}

function insertCanvasOnlyCanvasTag(){
  // 既存のcanvas要素を取得
  var preCanvas = document.getElementsByTagName('canvas')[0];

  // 既存のcanvasの(縮小前の)サイズを取得
  var canvasWidth = preCanvas.style.width;  //スタイルから取得。最初はテキスト+pxの形になっている。
  canvasWidth = eval( canvasWidth.slice( 0, canvasWidth.indexOf('px') ) );  //数字のみに加工
  var canvasHeight = preCanvas.style.height;
  canvasHeight = eval( canvasHeight.slice( 0, canvasHeight.indexOf('px') ) );

  // objListの要素をHTMLリスト化
  preCanvas.insertAdjacentHTML('afterend','<canvas height=\"'+canvasHeight+'\" width=\"'+canvasWidth+'\" dir=\"ltr\" tabindex=\"10000\" class=\"usicanvas\" style=\"position: absolute; right: 0px; bottom: 0px;\">UsiCanvas</canvas>');

}

//[現在のwidth, 本来のwidth, 現在のheight, 本来のheight]。GV1のcanvasに使用することを想定している。
function getCanvasSize(){
  var canvas = document.getElementsByTagName('canvas')[0];
  var canvasWidth = canvas.width;
  var styleWidth = canvas.style.width;  // '1234px'
  styleWidth = eval( styleWidth.slice( 0, styleWidth.indexOf('px') ) );  // 1234
  var canvasHeight = canvas.height;
  var styleHeight = canvas.style.height;  // '5678px'
  styleHeight = eval( styleHeight.slice( 0, styleHeight.indexOf('px') ) );  // 5678
  return [canvasWidth, styleWidth, canvasHeight, styleHeight];
}

//イベント発生位置を取得
function getEventData(evt){
  evt.preventDefault();

  //発生したイベントのタイプをログに吐き出す
  console.log('eventType = '+evt.type);

  var result;  //結果格納用

  var canvas = document.getElementsByTagName('canvas')[0];  //グラフィックスビュー1を表示しているcanvasを取得
  var deviceType = window.ontouchstart===null?'touchDevice':'mouseDevice';  //タッチデバイスか、マウスデバイスかを判定

  //スケール調整用
  var canvasWidth = canvas.width;  //e.g. 1000
  var styleWidth = canvas.style.width;  //e.g. '1234px'
  styleWidth = eval( styleWidth.slice( 0, styleWidth.indexOf('px') ) );  //e.g. 1234
  var styleHeight = canvas.style.height;  //e.g. '1234px'
  styleHeight = eval( styleHeight.slice( 0, styleHeight.indexOf('px') ) );  //e.g. 1234

  var ratio = canvasWidth / styleWidth;

  //タッチデバイス用演算(マウスデバイスと違い、offsetXYプロパティが取れないため、やや計算が複雑)
  if(deviceType == 'touchDevice'){
    //pageXY
    var touchX = evt.changedTouches[0].pageX;
    var touchY = evt.changedTouches[0].pageY;

    //canvasの位置
    var clientRect = canvas.getBoundingClientRect();
    var positionX = clientRect.left + window.pageXOffset;
    var positionY = clientRect.top + window.pageYOffset;

    //加減
    var calcX = touchX - positionX;
    var calcY = touchY - positionY;

    //スケール調整(オフセット値にそろえる)
    calcX = calcX * styleWidth / clientRect.width;
    calcY = calcY * styleHeight / clientRect.height;

    result = [calcX, calcY];
  }

  //マウスデバイス用演算
  if(deviceType == 'mouseDevice'){
    result = [evt.offsetX, evt.offsetY];
  }

  //スケール調整前、かつ、丸め前の値をログに吐き出す
  console.log('roughData = '+result);

  //スケール調整(現在のcanvasの大きさに合わせる)
  result[0] = ratio * result[0];
  result[1] = ratio * result[1];

  //丸め
  result[0] = Math.round( result[0] );
  result[1] = Math.round( result[1] );

  //スケール調整後、かつ、丸め後の値をログに吐き出す
  console.log('shapedData = '+result);

  return result;
}