Up-down arrows buttons (Mobile)

Creates up-down arrows buttons on chart

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name          Up-down arrows buttons (Mobile)
// @description   Creates up-down arrows buttons on chart
// @author        Konf
// @namespace     https://greasyfork.org/users/424058
// @icon          https://www.google.com/s2/favicons?sz=64&domain=tradingview.com
// @version       2.0.1
// @match         https://www.tradingview.com/chart/*
// @run-at        document-body
// @grant         GM_addStyle
// @noframes
// ==/UserScript==

/* jshint esversion: 8 */
/* eslint no-multi-spaces: 'off' */

(function() {
  'use strict';

  // The script creates an arrows inside of a buttons. Buttons represent the arrows hitboxes

  // Set to true to show a red outlines representing buttons hitboxes, or false to hide them
  const DEBUG_OUTLINE = false;

  // For a buttons/arrows sizes use these values:
  // '50px' to set 50 pixels or '50vw' to set 50% of view width or '50vh' for a view height.
  // Percents are not recommended because they're always based on width of a parent element

  const X_GAP_SIDE = 'right';    // 'left' or 'right'
  const Y_GAP_SIDE = 'bottom';   // 'top' or 'bottom'
  const BUTTONS_X_GAP = '0px';   // x gap size
  const BUTTONS_Y_GAP = '100px';  // y gap size

  const BUTTONS_WIDTH = '60px';
  const BUTTONS_HEIGHT = '55px';

  // This is useful when you're editing the arrows size related to the buttons hitboxes.
  // Fractional values like 1.4 or 0.7 are allowed too
  const ARROWS_SCALE = 0.85;

  // This is useful when you're editing the arrows position related to the buttons hitboxes.
  // Represents individual inner gaps of the buttons. 4 values representing the sides where
  // first value is the top gap, and the other three are right, bottom, left sides respectively.
  const UP_BUTTON_PADDING   = '5px 5px 0px 5px'; // top right bottom left
  const DOWN_BUTTON_PADDING = '0px 5px 5px 5px';
  const ARROWS_OPACITY = 0.8; // 1 is fully visible, 0.5 is half visible

  const ARROW_UP_ROTATE = 0; // clockwise, may take negative values
  const ARROW_DOWN_ROTATE = 180;

  const ARROW_UP_SRC   = 'https://img.icons8.com/fluency-systems-filled/2962ff/128/triangle.png';
  const ARROW_DOWN_SRC = 'https://img.icons8.com/fluency-systems-filled/2962ff/128/triangle.png';

  const btnsContainer = document.createElement('div');
  const btnUp = document.createElement('button');
  const btnDown = document.createElement('button');

  btnsContainer.classList.add('up-down-arrows');

  GM_addStyle(`
    div.up-down-arrows {
      position: fixed;
      user-select: none;
      z-index: 3;
      ${X_GAP_SIDE}: ${BUTTONS_X_GAP};
      ${Y_GAP_SIDE}: ${BUTTONS_Y_GAP};
    }

    div.up-down-arrows button {
      width: ${BUTTONS_WIDTH};
      height: ${BUTTONS_HEIGHT};
      display: block;
      padding: 0;
      box-sizing: border-box;
      cursor: pointer;
      overflow: hidden;
      background: none;
      border: ${DEBUG_OUTLINE ? '1px solid red' : 'none'};
    }

    div.up-down-arrows img {
      scale: ${ARROWS_SCALE};
      width: 100%;
      opacity: ${ARROWS_OPACITY};
      height: -moz-available;
      height: -webkit-fill-available;
      height: fill-available;
    }
  `);

  btnUp.append(document.createElement('img'));
  btnUp.addEventListener('click', () => pressKey('ArrowUp', 38));
  btnUp.style.padding = UP_BUTTON_PADDING;
  btnUp.firstChild.src = ARROW_UP_SRC;

  if (ARROW_UP_ROTATE) {
    btnUp.firstChild.style.transform = `rotate(${ARROW_UP_ROTATE}deg)`;
  }

  btnDown.append(document.createElement('img'));
  btnDown.addEventListener('click', () => pressKey('ArrowDown', 40));
  btnDown.style.padding = DOWN_BUTTON_PADDING;
  btnDown.firstChild.src = ARROW_DOWN_SRC;

  if (ARROW_DOWN_ROTATE) {
    btnDown.firstChild.style.transform = `rotate(${ARROW_DOWN_ROTATE}deg)`;
  }

  for (const el of [
    btnsContainer, btnUp, btnDown, btnUp.firstChild, btnDown.firstChild,
  ]) {
    el.setAttribute('draggable', 'false');
    el.addEventListener('dragstart', (ev) => {
      ev.preventDefault();
      ev.stopImmediatePropagation();
    });
  }

  btnsContainer.append(btnUp, btnDown);
  document.body.append(btnsContainer);

  // utils ----------------------------------------------------------------------

  function pressKey(key, code) {
    const event = new KeyboardEvent('keydown', {
      key,
      code,
      keyCode: code,
      which: code,
      bubbles: true,
    });

    document.body.dispatchEvent(event);
  }

  // ---------------------------------------------------------------------- utils
}());