Advertisement
Guest User

Meiguro's 3DS Touch Code

a guest
Jul 25th, 2014
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @id twitch-plays-control@meiguro.com
  3. // @name Twitch Plays Pokémon Touch Controller
  4. // @version 0.3.2
  5. // @author Meiguro <meiguro@meiguro.com> http://meiguro.com/
  6. // @namespace https://github.com/Meiguro/twitch-plays-control
  7. // @description Add Touch controls to Twitch Plays Pokemon touch-enabled games.
  8. // @include /^https?://(www|beta)?\.?twitch.tv/twitch_?plays.*$/
  9. // @grant unsafeWindow, GM_addStyle, GM_info
  10. // @run-at document-start
  11. // @updateURL https://raw.githubusercontent.com/Meiguro/twitch-plays-control/master/twitch-plays-control.meta.js
  12. // @installURL https://raw.githubusercontent.com/Meiguro/twitch-plays-control/master/twitch-plays-control.user.js
  13. // @downloadURL https://raw.githubusercontent.com/Meiguro/twitch-plays-control/master/twitch-plays-control.user.js
  14. // ==/UserScript==
  15.  
  16. /**
  17. * v0.3.2 CHANGELOG ༼ つ ◕_◕ ༽つ
  18. *
  19. * - Fixed the coordinate range to be 1,1 - 319,239.
  20. *
  21. * v0.3.1
  22. *
  23. * - Updated to the new 3DS layout. Reset your controller settings if the
  24. * touch input box is in the wrong location.
  25. *
  26. * - The logic has been separated into components for maintainability. There
  27. * should be no break in functionality.
  28. *
  29. * Enjoy!
  30. *
  31. * - Meiguro
  32. */
  33.  
  34. (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  35. /* globals GM_addStyle, GM_info */
  36.  
  37. var util2 = require('util2');
  38.  
  39. var dd = require('dd');
  40. dd.ui = require('dd-ui');
  41.  
  42. var Entity = require('entity');
  43. var Touch = require('touch');
  44. var Chat = require('chat');
  45. var Settings = require('settings');
  46. var mywindow = require('window');
  47.  
  48. require('gm-shims');
  49.  
  50. var Control = function(def) {
  51. Entity.call(this, def);
  52. this.config = {};
  53. };
  54.  
  55. util2.inherit(Control, Entity, Control.prototype);
  56.  
  57. Control.DefaultConfig = {
  58. delay: 50,
  59. screen: {
  60. aspect: 1280 / 720,
  61. position: [0.997, 0.977],
  62. scale: 0.392,
  63. size: [320, 240],
  64. barHeight: 30
  65. },
  66. enabled: true,
  67. showBorder: true,
  68. showCoordTooltip: true,
  69. showCross: true,
  70. autoSend: true,
  71. showDroplets: true,
  72. streamDelay: 15,
  73. };
  74.  
  75. Control.PlayerSelector = '.dynamic-player, .player-container';
  76.  
  77. Control.prototype.updateLoad = function() {
  78. if (this.loaded) { return; }
  79. if (!this.loadable()) { return; }
  80.  
  81. this.onload();
  82. };
  83.  
  84. Control.prototype.update = function(force) {
  85. this.updateLoad();
  86.  
  87. Entity.prototype.update.call(this, force);
  88. };
  89.  
  90. Control.prototype.onClick = function(e) {
  91. this.component('touch').onClick(e);
  92. };
  93.  
  94. Control.prototype.onMove = function(e) {
  95. this.component('touch').onMove(e);
  96. };
  97.  
  98. Control.prototype.onPressReset = function(e) {
  99. $.extend(true, this.config, Control.DefaultConfig);
  100.  
  101. this.eachComponent(function(component) {
  102. for (var k in component) {
  103. var $elem = component[k];
  104. if ($elem.$change) {
  105. $elem.$change();
  106. }
  107. }
  108. });
  109.  
  110. this.update(true);
  111. this.saveConfig();
  112. };
  113.  
  114. Control.prototype.onPressChangeChatServer = function(e) {
  115. this.component('chat').onPressChangeChatServer(e);
  116. };
  117.  
  118. Control.prototype.saveConfig = function() {
  119. localStorage.TPControl = JSON.stringify(this.config);
  120. };
  121.  
  122. Control.prototype.loadConfig = function() {
  123. if (!localStorage.TPControl) {
  124. localStorage.TPControl = this.config;
  125. } else {
  126. try {
  127. var lastConfig = JSON.parse(localStorage.TPControl);
  128. for (var k in lastConfig) {
  129. this.config[k] = lastConfig[k];
  130. }
  131. } catch(e) {
  132. console.log(e);
  133. }
  134. }
  135. };
  136.  
  137. Control.prototype.init = function() {
  138. var self = this;
  139.  
  140. window.$ = mywindow.jQuery;
  141.  
  142. $.extend(true, this.config, Control.DefaultConfig);
  143.  
  144. this.loadConfig();
  145. this.saveConfig();
  146.  
  147. dd.onChange = this.saveConfig.bind(this);
  148.  
  149. if (this.config.screen.size[0] != Control.DefaultConfig.screen.size[0]) {
  150. $.extend(true, this.config.screen, Control.DefaultConfig.screen);
  151. }
  152.  
  153. $('.tpc-mouse-box').remove();
  154. $('.tpc-control-settings').remove();
  155.  
  156. var touch = new Touch();
  157. var chat = new Chat();
  158. var settings = new Settings();
  159.  
  160. this.addComponent(touch);
  161. this.addComponent(chat);
  162. this.addComponent(settings);
  163.  
  164. var $player = touch.$player = $(Control.PlayerSelector);
  165. var $mouseBox = touch.$mouseBox = $('<div/>').addClass('tpc-mouse-box');
  166. var $coordTooltip = touch.$coordTooltip = $('<div/>').addClass('tpc-coord-tooltip');
  167.  
  168. var $chatSettings = settings.$chatSettings = $(Settings.ChatSelector);
  169. var $controlSettings = settings.$controlSettings = $('<div/>').addClass('tpc-control-settings');
  170.  
  171. $player.css({ position: 'relative' });
  172. $chatSettings.css({ position: 'absolute' });
  173.  
  174. $mouseBox.css({
  175. cursor: 'pointer',
  176. border: '2px solid rgba(150, 150, 150, 0.2)',
  177. borderRadius: '5px'
  178. });
  179.  
  180. GM_addStyle(
  181. '.tpc-mouse-box .tpc-coord-tooltip { display: none; color: #444; font-weight: normal } ' +
  182. '.tpc-mouse-box:hover .tpc-coord-tooltip { display: block }');
  183.  
  184. $coordTooltip.css({
  185. padding: '0px 5px',
  186. background: 'rgba(255, 255, 255, 0.8)',
  187. borderRadius: '2px'
  188. });
  189.  
  190. $mouseBox.empty();
  191. $mouseBox.append($coordTooltip);
  192.  
  193. $controlSettings.empty();
  194. $controlSettings.append(
  195. '<div class="chat-menu tpc-touch-menu">' +
  196. '<div class="chat-menu-header">Touch Control Settings</div>' +
  197. '<div class="chat-menu-content tpc-control-sliders"></div>' +
  198. '<div class="chat-menu-content tpc-control-checkboxes"></div>' +
  199. '<div class="chat-menu-content tpc-control-last"></div>' +
  200. '</div>' +
  201. '<div class="chat-menu tpc-chat-menu">' +
  202. '<div class="chat-menu-header">Chat Server</div>' +
  203. '<div class="chat-menu-content tpc-control-chat"></div>' +
  204. '</div>');
  205.  
  206. $controlSettings.find('.tpc-control-sliders')
  207. .append(touch.xSlider = dd.ui.slider(
  208. 'tpc-x-slider tpc-slider', 'Touch-box x-position', { min: 0, max: 1, step: 0.0005 },
  209. this.config, 'screen.position.0', function() { touch.updateMouseBox(true); }))
  210. .append(touch.ySlider = dd.ui.slider(
  211. 'tpc-y-slider tpc-slider', 'Touch-box y-position', { min: 0, max: 1, step: 0.0005 },
  212. this.config, 'screen.position.1', function() { touch.updateMouseBox(true); }))
  213. .append(touch.scaleSlider = dd.ui.slider(
  214. 'tpc-scale-slider tpc-slider', 'Touch-box scale', { min: 0, max: 1, step: 0.0005 },
  215. this.config, 'screen.scale', function() { touch.updateMouseBox(true); }));
  216.  
  217. $controlSettings.find('.tpc-control-checkboxes')
  218. .append(touch.enabledCheckbox = dd.ui.checkbox(
  219. 'tpc-enabled-checkbox', 'Enable touch control', this.config, 'enabled',
  220. function() {
  221. touch.$mouseBox.css({ display: self.config.enabled ? 'block' : 'none' });
  222. }))
  223. .append(touch.borderCheckbox = dd.ui.checkbox(
  224. 'tpc-border-checkbox', 'Show border box', this.config, 'showBorder',
  225. function() {
  226. touch.$mouseBox.css({ border: self.config.showBorder ? '2px solid rgba(255, 255, 255, 0.5)' : 'none' });
  227. }))
  228. .append(touch.coordTooltipCheckbox = dd.ui.checkbox(
  229. 'tpc-tooltip-checkbox', 'Show coord tooltip', this.config, 'showCoordTooltip',
  230. function() {
  231. if (self.config.showCoordTooltip) {
  232. touch.$mouseBox.append(touch.$coordTooltip);
  233. } else {
  234. touch.$coordTooltip.remove();
  235. }
  236. }))
  237. .append(touch.crossCheckbox = dd.ui.checkbox(
  238. 'tpc-cross-checkbox', 'Use cross pointer', this.config, 'showCross',
  239. function() {
  240. touch.$mouseBox.css({ cursor: self.config.showCross ? 'crosshair' : 'default' });
  241. }))
  242. .append(touch.autoSendCheckbox = dd.ui.checkbox(
  243. 'tpc-auto-send-checkbox', 'Auto-send touches', this.config, 'autoSend'))
  244. .append(touch.dropletsCheckbox = dd.ui.checkbox(
  245. 'tpc-droplet-checkbox', 'Show touch droplets', this.config, 'showDroplets'));
  246.  
  247. $controlSettings.find('.tpc-control-last')
  248. .append(touch.resetButton = dd.ui.button(
  249. 'tpc-reset-button', 'Reset controller settings', this.onPressReset.bind(this)));
  250.  
  251. $controlSettings.find('.tpc-control-chat')
  252. .append('<p><label>Current <span class="tpc-chat-server"></span></label></p>')
  253. .append(chat.chatServerButton = dd.ui.button(
  254. 'tpc-chat-server-button', 'Change chat server', this.onPressChangeChatServer.bind(this)));
  255.  
  256. $player.append($mouseBox);
  257. $chatSettings.append($controlSettings);
  258.  
  259. $mouseBox.on('click', this.onClick.bind(this));
  260. $mouseBox.on('mousemove', this.onMove.bind(this));
  261.  
  262. settings.update(true);
  263.  
  264. this.loaded = true;
  265.  
  266. this.start();
  267.  
  268. setTimeout(function() {
  269. $('.chat-room .loading-mask').remove();
  270. }, 5000);
  271. };
  272.  
  273. Control.prototype.loadable = function() {
  274. var $ = mywindow.jQuery;
  275. if (typeof $ !== 'function') { return false; }
  276.  
  277. var hasPlayer = $(Control.PlayerSelector).length;
  278. var hasChatSettings = $(Settings.ChatSelector).length;
  279. return hasPlayer || hasChatSettings;
  280. };
  281.  
  282. Control.prototype.onload = function() {
  283. this.init();
  284. if (typeof GM_info === 'object') {
  285. console.log(GM_info.script.name + ' v' + GM_info.script.version + ' loaded!');
  286. } else {
  287. console.log('Twitch Plays Control loaded!');
  288. }
  289. };
  290.  
  291. var control = new Control();
  292.  
  293. setInterval(control.update.bind(control), Control.DefaultConfig.delay);
  294.  
  295. control.update();
  296.  
  297. mywindow.TPControl = control;
  298.  
  299. },{"chat":2,"dd":5,"dd-ui":4,"entity":6,"gm-shims":7,"settings":8,"touch":9,"util2":10,"window":11}],2:[function(require,module,exports){
  300. var util2 = require('util2');
  301. var Component = require('component');
  302.  
  303. var mywindow = require('window');
  304.  
  305. var Chat = function(def) {
  306. Component.call(this, def);
  307. };
  308.  
  309. util2.inherit(Chat, Component, Chat.prototype);
  310.  
  311. Chat.InputSelector = '.ember-text-area';
  312. Chat.ButtonSelector = '.send-chat-button button';
  313. Chat.HiddenSelector = '.chat-hidden-overlay';
  314. Chat.LogSelector = '.chat-messages .tse-content';
  315. Chat.ServerAddress = '199.9.252.26:6667';
  316.  
  317. Chat.prototype.name = 'chat';
  318.  
  319. Chat.prototype.start = function() {
  320. };
  321.  
  322. Chat.prototype.getChatSession = function() {
  323. if (this.chatSession) {
  324. return this.chatSession;
  325. }
  326.  
  327. var App = mywindow.App;
  328. if (App && App.Room) {
  329. return (this.chatSession = App.Room._getTmiSession().fulfillmentValue);
  330. }
  331. };
  332.  
  333. Chat.prototype.getChatConnection = function() {
  334. var chatSession = this.getChatSession();
  335. var connections = chatSession._connections;
  336. var cluster = connections.prod || connections.event;
  337. if (cluster) { return cluster; }
  338. for (var k in connections) {
  339. return connections[k];
  340. }
  341. };
  342.  
  343. Chat.prototype.getCurrentChatAddress = function() {
  344. var chatSession = this.getChatSession();
  345. if (!chatSession) { return; }
  346. var connection = this.getChatConnection();
  347. if (!connection) { return; }
  348. var addr = connection._addrs[connection._currentAddressIndex];
  349. if (!addr) { return; }
  350. return addr.host + ':' + addr.port;
  351. };
  352.  
  353. Chat.prototype.connectServer = function(address) {
  354. var addr = address.split(':');
  355. var chatSession = this.getChatSession();
  356. var connection = this.getChatConnection();
  357. if (!connection) {
  358. window.alert('TPC: Couldn\'t obtain a chat connection to manipulate!');
  359. return;
  360. }
  361.  
  362. connection.close();
  363. connection._addrs = [{ host: addr[0], port: addr[1] }];
  364. connection._currentAddressIndex = 0;
  365. connection._numSocketConnectAttempts = 0;
  366. connection.open();
  367.  
  368. var msg = 'connecting to chat server ' + address + '...';
  369. $(Chat.LogSelector + ' .ember-view:last')
  370. .before('<div class="chat-line admin"><span class="message">' + msg + '</span></div>');
  371. };
  372.  
  373. Chat.prototype.isChatVisible = function() {
  374. return $(Chat.InputSelector).length && !$(Chat.HiddenSelector).is(':visible');
  375. };
  376.  
  377. Chat.prototype.setInput = function(input, broadcast) {
  378. $(Chat.InputSelector).val(input).focus().change().blur();
  379. if (this.config.autoSend) {
  380. $(Chat.ButtonSelector).click();
  381. }
  382. if (!this.isChatVisible() && broadcast !== false) {
  383. localStorage.TPCInput = input;
  384. }
  385. };
  386.  
  387. Chat.prototype.updateInput = function() {
  388. if (!this.entity.loaded) { return; }
  389. if (!this.config.enabled) { return; }
  390.  
  391. if (!this.isChatVisible()) { return; }
  392.  
  393. var input = localStorage.TPCInput;
  394. delete localStorage.TPCInput;
  395. if (typeof input === 'string' && input.length > 0) {
  396. this.setInput(input, false);
  397. }
  398. };
  399.  
  400. Chat.prototype.updateChatSession = function() {
  401. if (this.chatSession) { return; }
  402.  
  403. var TMI = mywindow.TMI;
  404. if (!TMI) { return; }
  405.  
  406. if (this.entity.loaded) {
  407. this.getChatSession();
  408. }
  409. };
  410.  
  411. Chat.prototype.update = function() {
  412. this.updateChatSession();
  413. this.updateInput();
  414. };
  415.  
  416. Chat.prototype.onPressChangeChatServer = function(e) {
  417. var defaultAddress = Chat.ServerAddress;
  418. var currentAddress = this.getCurrentChatAddress();
  419. var address = window.prompt(
  420. 'Enter chat server address:' +
  421. (currentAddress ?
  422. '\nCurrent ' + currentAddress :
  423. '\nExample ' + defaultAddress),
  424. defaultAddress) || '';
  425. address = address.replace(/\s/, '');
  426. if (address.length === 0) {
  427. return;
  428. }
  429. if (!address.match(':')) {
  430. address += ':6667';
  431. }
  432. this.connectServer(address);
  433. };
  434.  
  435. module.exports = Chat;
  436.  
  437. },{"component":3,"util2":10,"window":11}],3:[function(require,module,exports){
  438. var Component = function(def) {
  439. this.state = def || {};
  440. };
  441.  
  442. Component.prototype.component = function(name) {
  443. return this.entity.component(name);
  444. };
  445.  
  446. Component.prototype.start = function() {};
  447.  
  448. Component.prototype.update = function() {};
  449.  
  450. module.exports = Component;
  451.  
  452. },{}],4:[function(require,module,exports){
  453. var dd = require('dd');
  454.  
  455. dd.ui = dd.ui || {};
  456.  
  457. dd.ui.checkbox = function(id, label, obj, ref, onChange) {
  458. var $elem = $('<p><label for="'+id+'"><input id="'+id+'" type="checkbox"> '+label+'</label></p>');
  459. var $input = $elem.find('input');
  460. dd.bindGetSet($elem, $input.prop.bind($input, 'checked'));
  461. $input.on('change', dd.bindElement($elem, obj, ref, onChange));
  462. return $elem;
  463. };
  464.  
  465. dd.ui.slider = function(klass, label, options, obj, ref, onChange) {
  466. var $elem = $('<p><label>'+label+'</label></p>');
  467. var $slider = $('<div class="'+klass+'"></div>');
  468. $slider.slider(options);
  469. $elem.prepend($slider);
  470. dd.bindGetSet($elem, $slider.slider.bind($slider, 'value'));
  471. $slider.slider({ slide: dd.bindElement($elem, obj, ref, onChange) });
  472. return $elem;
  473. };
  474.  
  475. dd.ui.button = function(klass, label, onPress) {
  476. var $elem = $('<button class="'+klass+'">'+label+'</button>');
  477. $elem.on('click', onPress);
  478. return $elem;
  479. };
  480.  
  481. module.exports = dd.ui;
  482.  
  483. },{"dd":5}],5:[function(require,module,exports){
  484. var dd = {};
  485.  
  486. dd.last = function(a) {
  487. return a[a.length - 1];
  488. };
  489.  
  490. dd.toKey = function(obj, key) {
  491. return obj instanceof Array ? parseInt(key) : key;
  492. };
  493.  
  494. dd.getByKeys = function(obj, keys, offset) {
  495. for (var i = 0, ii = keys.length - (offset || 0); i < ii; ++i) {
  496. obj = obj[dd.toKey(obj, keys[i])];
  497. }
  498. return obj;
  499. };
  500.  
  501. dd.setByKey = function(obj, key, value) {
  502. obj[dd.toKey(obj, key)] = value;
  503. };
  504.  
  505. dd.set = function(obj, ref, value) {
  506. var keys = ref.split('.');
  507. dd.setByKey(dd.getByKeys(obj, keys, 1), dd.last(keys), value);
  508. };
  509.  
  510. dd.get = function(obj, ref) {
  511. return dd.getByKeys(obj, ref.split('.'));
  512. };
  513.  
  514. dd.bindGetSet = function($elem, get, set) {
  515. $elem.$get = get;
  516. $elem.$set = set || get;
  517. };
  518.  
  519. dd.bindElement = function($elem, obj, ref, onChange) {
  520. $elem.$obj = obj;
  521. $elem.$ref = ref;
  522. $elem.$change = function(e) {
  523. if (e) {
  524. dd.set(obj, ref, $elem.$get());
  525. } else {
  526. $elem.$set(dd.get(obj, ref));
  527. }
  528. if (onChange) { onChange(e); }
  529. if (dd.onChange) { dd.onChange(e); }
  530. };
  531. $elem.$change();
  532. return $elem.$change;
  533. };
  534.  
  535. module.exports = dd;
  536.  
  537. },{}],6:[function(require,module,exports){
  538. var Entity = function(def) {
  539. this.state = def || {};
  540. this._components = [];
  541. this._componentsByName = {};
  542. };
  543.  
  544. Entity.prototype.component = function(name) {
  545. return this._componentsByName[name];
  546. };
  547.  
  548. Entity.prototype.eachComponent = function(callback) {
  549. this._components.forEach(callback.bind(this));
  550. };
  551.  
  552. Entity.prototype.addComponent = function(component) {
  553. if (component.entity) {
  554. component.entity.removeComponent(component);
  555. }
  556. this._componentsByName[component.name] = component;
  557. this._components.push(component);
  558. component.entity = this;
  559. component.config = this.config;
  560. };
  561.  
  562. Entity.prototype.removeComponent = function(component) {
  563. var index = this._components.indexOf(component);
  564. if (index === -1) { return; }
  565. this._components.splice(index, 1);
  566. delete this._componentsByName[component.name];
  567. delete component.entity;
  568. delete component.config;
  569. };
  570.  
  571. Entity.prototype.start = function() {
  572. for (var i = 0, ii = this._components.length; i < ii; ++i) {
  573. this._components[i].start();
  574. }
  575. };
  576.  
  577. Entity.prototype.update = function(force) {
  578. for (var i = 0, ii = this._components.length; i < ii; ++i) {
  579. this._components[i].update(force);
  580. }
  581. };
  582.  
  583. module.exports = Entity;
  584.  
  585. },{}],7:[function(require,module,exports){
  586. (function (global){
  587.  
  588. if (typeof GM_addStyle === 'undefined') {
  589. global.GM_addStyle = function(style) {
  590. $('head:first').append($('<style>').text(style));
  591. };
  592. }
  593.  
  594. }).call(this,typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  595. },{}],8:[function(require,module,exports){
  596. var util2 = require('util2');
  597. var Component = require('component');
  598.  
  599. var Settings = function(def) {
  600. Component.call(this, def);
  601. };
  602.  
  603. util2.inherit(Settings, Component, Settings.prototype);
  604.  
  605. Settings.ChatSelector = '.js-chat-settings';
  606. Settings.ButtonSelector = '.settings.button';
  607.  
  608. Settings.prototype.name = 'settings';
  609.  
  610. Settings.prototype.start = function() {
  611. };
  612.  
  613. Settings.prototype.updateServerLabel = function() {
  614. var $chatServer = this.$chatSettings.find('.tpc-chat-server');
  615.  
  616. var labelAddress = $chatServer.text();
  617. var currentAddress = this.component('chat').getCurrentChatAddress();
  618. if (currentAddress !== labelAddress) {
  619. $chatServer.text(currentAddress);
  620. }
  621. };
  622.  
  623. Settings.prototype.updatePosition = function(force) {
  624. var overflow = this.$chatSettings.css('overflowY') || '';
  625.  
  626. if (overflow.match(/(auto|scroll)/)) {
  627. this.$controlSettings.css({ position: 'static', left: 'none', top: 'none' });
  628. return;
  629. }
  630.  
  631. var minWidth = Math.max(200, this.$chatSettings.width());
  632. var position = { left: 0, top: 0 };
  633. var offset = this.$chatSettings.offset();
  634. var isSlim = offset.left > 0 && offset.left < minWidth;
  635.  
  636. this.$controlSettings.css({
  637. position: 'absolute',
  638. minWidth: minWidth,
  639. left: position.left + (minWidth + 5) * (isSlim ? 1 : -1),
  640. top: position.top + this.$chatSettings.height() - this.$controlSettings.height()
  641. });
  642. };
  643.  
  644. Settings.prototype.update = function(force) {
  645. if (!this.entity.loaded) { return; }
  646.  
  647. if (!this.$chatSettings.length) { return; }
  648. if (!this.$chatSettings.is(':visible') && force !== true) { return; }
  649.  
  650. this.updateServerLabel();
  651. this.updatePosition();
  652. };
  653.  
  654. module.exports = Settings;
  655.  
  656. },{"component":3,"util2":10}],9:[function(require,module,exports){
  657. var util2 = require('util2');
  658. var Component = require('component');
  659.  
  660. var Touch = function(def) {
  661. Component.call(this, def);
  662. };
  663.  
  664. util2.inherit(Touch, Component, Touch.prototype);
  665.  
  666. Touch.SizeEdge = [false, false];
  667.  
  668. Touch.prototype.name = 'touch';
  669.  
  670. Touch.prototype.start = function() {
  671. };
  672.  
  673. Touch.prototype.getBorderSize = function() {
  674. return parseInt(this.$mouseBox.css('borderTopWidth'));
  675. };
  676.  
  677. Touch.prototype.getTouchPosition = function(e) {
  678. var offset = this.$mouseBox.offset();
  679. var borderSize = this.getBorderSize();
  680. var x = e.clientX - offset.left - 2 * borderSize;
  681. var y = e.clientY - offset.top - 2 * borderSize;
  682.  
  683. var minX = 0 + (Touch.SizeEdge[0] ? 0 : 1);
  684. var minY = 0 + (Touch.SizeEdge[1] ? 0 : 1);
  685. var maxX = this.config.screen.size[0] - (Touch.SizeEdge[0] ? 0 : 1);
  686. var maxY = this.config.screen.size[1] - (Touch.SizeEdge[1] ? 0 : 1);
  687.  
  688. var touchX = Math.ceil(x / this.scale);
  689. var touchY = Math.ceil(y / this.scale);
  690. var valid = (touchX >= minX && touchX <= maxX) &&
  691. (touchY >= minY && touchY <= maxY);
  692. return {
  693. mouse: [x, y],
  694. position: [touchX, touchY],
  695. input: touchX + ',' + touchY,
  696. valid: valid
  697. };
  698. };
  699.  
  700. Touch.prototype.spawnDroplet = function(position) {
  701. var $drop = $('<div/>').addClass('tpc-droplet');
  702. var size = 10;
  703. $drop.css({
  704. background: 'rgba(255, 255, 255, 0.8)',
  705. borderRadius: size,
  706. position: 'absolute',
  707. left: position[0] - size / 2,
  708. top: position[1] - size / 2,
  709. width: size,
  710. height: size
  711. });
  712. this.$mouseBox.append($drop);
  713. $drop
  714. .animate({
  715. left: position[0],
  716. top: position[1],
  717. width: 0,
  718. height: 0
  719. }, this.config.streamDelay * 1000)
  720. .queue(function() {
  721. $drop.remove();
  722. $drop.dequeue();
  723. });
  724. };
  725.  
  726. Touch.prototype.updateMouseBox = function(force) {
  727. var playerWidth = this.$player.width();
  728. var playerHeight = this.$player.height() - this.config.screen.barHeight;
  729.  
  730. if ((this.playerWidth === playerWidth &&
  731. this.playerHeight === playerHeight) && force !== true) {
  732. return;
  733. }
  734.  
  735. this.playerWidth = playerWidth;
  736. this.playerHeight = playerHeight;
  737.  
  738. var aspect = playerWidth / playerHeight;
  739.  
  740. var excessWidth = 0;
  741. if (aspect > this.config.screen.aspect) {
  742. excessWidth = playerWidth - playerHeight * this.config.screen.aspect;
  743. }
  744.  
  745. this.scale = this.config.screen.scale * playerHeight / this.config.screen.size[1];
  746.  
  747. var borderSize = this.getBorderSize();
  748. var width = this.scale * this.config.screen.size[0];
  749. var height = this.scale * this.config.screen.size[1];
  750.  
  751. this.$mouseBox.css({
  752. position: 'absolute',
  753. left: excessWidth / 2 + (playerWidth - width - excessWidth) * this.config.screen.position[0] - borderSize,
  754. top: (playerHeight - height) * this.config.screen.position[1] - borderSize,
  755. width: width,
  756. height: height
  757. });
  758.  
  759. if (!this.component('settings').$chatSettings.is(':visible')) {
  760. this.$mouseBox.stop(true, true).css({ background: 'transparent' });
  761. return;
  762. }
  763.  
  764. this.$mouseBox
  765. .stop(true, true)
  766. .animate({ backgroundColor: 'rgba(255, 255, 255, 0.5)' }, 100)
  767. .delay(1000)
  768. .animate({ backgroundColor: 'rgba(255, 255, 255, 0)' })
  769. .animate({ background: 'transparent' }, 0);
  770. };
  771.  
  772. Touch.prototype.update = function(force) {
  773. if (!this.entity.loaded) { return; }
  774. if (!this.config.enabled) { return; }
  775.  
  776. this.updateMouseBox(force);
  777. };
  778.  
  779. Touch.prototype.onClick = function(e) {
  780. var touch = this.getTouchPosition(e);
  781. if (!touch.valid) { return; }
  782. this.component('chat').setInput(touch.input);
  783. if (this.config.showDroplets) {
  784. this.spawnDroplet(touch.mouse);
  785. }
  786. };
  787.  
  788. Touch.prototype.onMove = function(e) {
  789. if (!this.config.showCoordTooltip) { return; }
  790. var touch = this.getTouchPosition(e);
  791. var borderSize = this.getBorderSize();
  792. this.$coordTooltip
  793. .text(touch.valid ? touch.input : '')
  794. .css({
  795. position: 'absolute',
  796. left: touch.mouse[0] + borderSize + 15,
  797. top: touch.mouse[1] + borderSize - this.$coordTooltip.outerHeight() / 2
  798. });
  799. };
  800.  
  801. module.exports = Touch;
  802.  
  803. },{"component":3,"util2":10}],10:[function(require,module,exports){
  804. /*
  805. * util2.js by Meiguro - MIT License
  806. */
  807.  
  808. var util2 = (function(){
  809.  
  810. var util2 = {};
  811.  
  812. util2.noop = function() {};
  813.  
  814. util2.copy = function(a, b) {
  815. b = b || (a instanceof Array ? [] : {});
  816. for (var k in a) { b[k] = a[k]; }
  817. return b;
  818. };
  819.  
  820. util2.inherit = function(child, parent, proto) {
  821. child.prototype = Object.create(parent.prototype);
  822. child.prototype.constructor = child;
  823. if (proto) {
  824. util2.copy(proto, child.prototype);
  825. }
  826. return child.prototype;
  827. };
  828.  
  829. if (typeof module !== 'undefined') {
  830. module.exports = util2;
  831. }
  832.  
  833. return util2;
  834.  
  835. })();
  836.  
  837. },{}],11:[function(require,module,exports){
  838. /* global unsafeWindow */
  839. module.exports = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
  840.  
  841. },{}]},{},[1])
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement