⌈⌋ ⎇ branch:  Bitrhythm


Artifact Content

Artifact 3b11b075f703170122fcc54f3e802ab418b59d779aeab2d238e94489d55de1aa:


'use strict';

let math = require('../util/math');
let svg = require('../util/svg');
let Interface = require('../core/interface');

/**
* Tilt
*
* @description Device tilt sensor with 2 or 3 axes (depending on your device and browser).
*
* @demo <span nexus-ui='tilt'></span>
*
* @example
* var tilt = new Nexus.Tilt('#target')
*
* @output
* change
* Fires at a regular interval, as long as this interface is active (see the interface's <i>.active</i> property)<br>
* The event data is an <i>object</i> containing x (number) and y (number) properties which represent the current tilt state of the device.
*
* @outputexample
* tilt.on('change',function(v) {
*   console.log(v);
* })
*
*
*/

export default class Tilt extends Interface {

  constructor() {

    let options = ['value'];

    let defaults = {
      'size': [80,80]
    };

    super(arguments,options,defaults);

    this._active = true;

    this.init();

    // add event listener for device orientation

  	this.boundUpdate = this.update.bind(this);
  //	this.boundMozTilt = this.mozTilt.bind(this)

  	if (window.DeviceOrientationEvent) {
  		this.orientationListener = window.addEventListener('deviceorientation', this.boundUpdate, false);
  	} else {
      this._active = false;
      this.colorInterface();
    }



      /*else if (window.OrientationEvent) {
  //	  	window.addEventListener('MozOrientation', this.boundMozTilt, false);
  	} else {
  	  	console.log('Not supported on your device or browser.');
  	} */


  }


  buildInterface() {

    this.title = svg.create('text');
    this.circleX = svg.create('circle');
    this.circleY = svg.create('circle');
    this.circleZ = svg.create('circle');

    this.barX = svg.create('path');
    this.barY = svg.create('path');
    this.barZ = svg.create('path');

    this.barX2 = svg.create('path');
    this.barY2 = svg.create('path');
    this.barZ2 = svg.create('path');

    this.barX.setAttribute('opacity','0.8');
    this.barY.setAttribute('opacity','0.8');
    this.barZ.setAttribute('opacity','0.8');
    this.barX2.setAttribute('opacity','0.8');
    this.barY2.setAttribute('opacity','0.8');
    this.barZ2.setAttribute('opacity','0.8');

    this.circleX.setAttribute('cx',this.width*3/12);
    this.circleX.setAttribute('cy',this.height*3/4);
    this.circleX.setAttribute('r',this.height/10);
    this.circleX.setAttribute('opacity','0.4');

    this.circleY.setAttribute('cx',this.width*6/12);
    this.circleY.setAttribute('cy',this.height*3/4);
    this.circleY.setAttribute('r',this.height/10);
    this.circleY.setAttribute('opacity','0.4');

    this.circleZ.setAttribute('cx',this.width*9/12);
    this.circleZ.setAttribute('cy',this.height*3/4);
    this.circleZ.setAttribute('r',this.height/10);
    this.circleZ.setAttribute('opacity','0.4');


    this.barX.setAttribute('stroke-width',Math.round(this.height/30));
    this.barY.setAttribute('stroke-width',Math.round(this.height/30));
    this.barZ.setAttribute('stroke-width',Math.round(this.height/30));

    this.barX.setAttribute('fill', 'none');
    this.barY.setAttribute('fill', 'none');
    this.barZ.setAttribute('fill', 'none');

    this.barX2.setAttribute('stroke-width',Math.round(this.height/30));
    this.barY2.setAttribute('stroke-width',Math.round(this.height/30));
    this.barZ2.setAttribute('stroke-width',Math.round(this.height/30));

    this.barX2.setAttribute('fill', 'none');
    this.barY2.setAttribute('fill', 'none');
    this.barZ2.setAttribute('fill', 'none');


    this.title.setAttribute('x',this.width/2);
    this.title.setAttribute('y',this.height/3+7);
    this.title.setAttribute('font-size','15px');
    this.title.setAttribute('font-weight','bold');
    this.title.setAttribute('letter-spacing','2px');
    this.title.setAttribute('opacity','0.7');
    this.title.setAttribute('text-anchor','middle');
    this.title.textContent = 'TILT';


    this.element.appendChild(this.circleX);
    this.element.appendChild(this.circleY);
    this.element.appendChild(this.circleZ);

    this.element.appendChild(this.barX);
    this.element.appendChild(this.barY);
    this.element.appendChild(this.barZ);

    this.element.appendChild(this.barX2);
    this.element.appendChild(this.barY2);
    this.element.appendChild(this.barZ2);

    this.element.appendChild(this.title);

  }

  colorInterface() {

    if (this._active) {
      this.element.style.backgroundColor = this.colors.accent;
      this.circleX.setAttribute('fill',this.colors.light);
      this.circleY.setAttribute('fill',this.colors.light);
      this.circleZ.setAttribute('fill',this.colors.light);
      this.circleX.setAttribute('stroke',this.colors.light);
      this.circleY.setAttribute('stroke',this.colors.light);
      this.circleZ.setAttribute('stroke',this.colors.light);
      this.barX.setAttribute('stroke',this.colors.light);
      this.barY.setAttribute('stroke',this.colors.light);
      this.barZ.setAttribute('stroke',this.colors.light);
      this.barX2.setAttribute('stroke',this.colors.light);
      this.barY2.setAttribute('stroke',this.colors.light);
      this.barZ2.setAttribute('stroke',this.colors.light);
      this.title.setAttribute('fill',this.colors.light);
    } else {
      this.element.style.backgroundColor = this.colors.fill;
      this.circleX.setAttribute('fill',this.colors.mediumLight);
      this.circleY.setAttribute('fill',this.colors.mediumLight);
      this.circleZ.setAttribute('fill',this.colors.mediumLight);
      this.circleX.setAttribute('stroke',this.colors.mediumLight);
      this.circleY.setAttribute('stroke',this.colors.mediumLight);
      this.circleZ.setAttribute('stroke',this.colors.mediumLight);
      this.barX.setAttribute('stroke',this.colors.mediumLight);
      this.barY.setAttribute('stroke',this.colors.mediumLight);
      this.barZ.setAttribute('stroke',this.colors.mediumLight);
      this.barX2.setAttribute('stroke',this.colors.mediumLight);
      this.barY2.setAttribute('stroke',this.colors.mediumLight);
      this.barZ2.setAttribute('stroke',this.colors.mediumLight);
      this.title.setAttribute('fill',this.colors.mediumLight);
    }

  }

  update(v) {
    if (this._active){

      let y = v.beta;
      let x = v.gamma;
      let z = v.alpha;

      // take the original -90 to 90 scale and normalize it 0-1
      x = math.scale(x,-90,90,0,1);
      y = math.scale(y,-90,90,0,1);
      z = math.scale(z,0,360,0,1);


      let handlePoints = {
        start: Math.PI*1.5,
        end: math.clip( math.scale(x,0,0.5,Math.PI*1.5,Math.PI*0.5) , Math.PI*0.5, Math.PI*1.5 )
      };
      let handle2Points = {
        start: Math.PI*2.5,
        end: math.clip( math.scale(x,0.5,1,Math.PI*2.5,Math.PI*1.5) , Math.PI*1.5, Math.PI*2.5 )
      };

      let handlePath = svg.arc(this.circleX.cx.baseVal.value, this.circleX.cy.baseVal.value, this.circleX.r.baseVal.value, handlePoints.start, handlePoints.end);
      let handle2Path = svg.arc(this.circleX.cx.baseVal.value, this.circleX.cy.baseVal.value, this.circleX.r.baseVal.value, handle2Points.start, handle2Points.end);

      this.barX.setAttribute('d', handlePath);
      this.barX2.setAttribute('d', handle2Path);





      handlePoints = {
        start: Math.PI*1.5,
        end: math.clip( math.scale(y,0,0.5,Math.PI*1.5,Math.PI*0.5) , Math.PI*0.5, Math.PI*1.5 )
      };
      handle2Points = {
        start: Math.PI*2.5,
        end: math.clip( math.scale(y,0.5,1,Math.PI*2.5,Math.PI*1.5) , Math.PI*1.5, Math.PI*2.5 )
      };

      handlePath = svg.arc(this.circleY.cx.baseVal.value, this.circleY.cy.baseVal.value, this.circleY.r.baseVal.value, handlePoints.start, handlePoints.end);
      handle2Path = svg.arc(this.circleY.cx.baseVal.value, this.circleY.cy.baseVal.value, this.circleY.r.baseVal.value, handle2Points.start, handle2Points.end);

      this.barY.setAttribute('d', handlePath);
      this.barY2.setAttribute('d', handle2Path);






      handlePoints = {
        start: Math.PI*1.5,
        end: math.clip( math.scale(z,0,0.5,Math.PI*1.5,Math.PI*0.5) , Math.PI*0.5, Math.PI*1.5 )
      };
      handle2Points = {
        start: Math.PI*2.5,
        end: math.clip( math.scale(z,0.5,1,Math.PI*2.5,Math.PI*1.5) , Math.PI*1.5, Math.PI*2.5 )
      };

      handlePath = svg.arc(this.circleZ.cx.baseVal.value, this.circleZ.cy.baseVal.value, this.circleZ.r.baseVal.value, handlePoints.start, handlePoints.end);
      handle2Path = svg.arc(this.circleZ.cx.baseVal.value, this.circleZ.cy.baseVal.value, this.circleZ.r.baseVal.value, handle2Points.start, handle2Points.end);

      this.barZ.setAttribute('d', handlePath);
      this.barZ2.setAttribute('d', handle2Path);


      /*

      let pointsX = {
        start: 0,
        end: math.scale( x, 0, 1, 0, Math.PI*2 )
      };

    //  console.log(this.circleX.cx.baseVal.value);

      let pathX = svg.arc(this.circleX.cx.baseVal.value, this.circleX.cy.baseVal.value, this.circleX.r.baseVal.value*2, pointsX.start, pointsX.end);

      this.barX.setAttribute('d',pathX); */

      //this.textH.textContent = math.prune(x,2);
      //this.textV.textContent = math.prune(y,2);
      //
    //  this.circleX.setAttribute('opacity',x);
    //  this.circleY.setAttribute('opacity',y);
    //  this.circleZ.setAttribute('opacity',z);

      this.emit('change', {
        x: x,
        y: y,
        z: z
      });

    }

  }

  click() {
    if (window.DeviceOrientationEvent) {
      this.active = !this.active;
    }
  }

  /**
  Whether the interface is on (emitting values) or off (paused & not emitting values). Setting this property will update it.
  @type {boolean}
  */

  get active() {
    return this._active;
  }

  set active(on) {
    this._active = on;
    this.colorInterface();
  }

  customDestroy() {
    window.removeEventListener('deviceorientation', this.boundUpdate, false);
  }

}