You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
4.3 KiB

  1. import React, { useState } from "react";
  2. import { Tabs, Tab } from "react-tabs-scrollable";
  3. import "react-tabs-scrollable/dist/rts.css";
  4. import { getHeatmapData } from "./webpage_container/StudySite";
  5. import { pushToMouseLog } from "../core/log/SensorLogger";
  6. import {
  7. playTabEarconSonification,
  8. playTabModelSonification,
  9. } from "../core/audio/AudioHandler";
  10. import { Divider } from "@geist-ui/core";
  11. var reachedEndValue = false;
  12. var rightSideEnd = true;
  13. var endElement = 0;
  14. var type = "";
  15. function ScrollableTab({ onActiveTabChange, sonificationType, children }) {
  16. const [activeTab, setActiveTab] = useState(0);
  17. const [amountTabs, setAmountTabs] = useState(children.length);
  18. endElement = amountTabs;
  19. type = sonificationType;
  20. const saveMouseLog = function () {
  21. pushToMouseLog(getHeatmapData());
  22. };
  23. // define a onClick function to bind the value on tab click
  24. const onTabClick = (e, index) => {
  25. const buttonAttributes = e.target.attributes;
  26. const actionType = buttonAttributes["actionType"]
  27. ? buttonAttributes.getNamedItem("actionType").value
  28. : "";
  29. const redirectLoc = buttonAttributes["redirectLoc"]
  30. ? buttonAttributes.getNamedItem("redirectLoc").value
  31. : "";
  32. if (actionType === "button") {
  33. saveMouseLog();
  34. window.location.href = redirectLoc;
  35. }
  36. setActiveTab(index);
  37. onActiveTabChange(index);
  38. };
  39. const onHoverElement = () => {};
  40. const onHoverTab = (key) => {
  41. const clamp = (num, min, max) => Math.min(Math.max(num, min), max);
  42. const panVal = rightSideEnd
  43. ? clamp(3 * ((-1 / amountTabs) * key + 1) - 2, -1, 1)
  44. : clamp(2 * ((-1 / amountTabs) * -1 * key + 1) - 4, -1, 1); // ((-1 / amountTabs) * key + 1);
  45. const frequencyVal = rightSideEnd
  46. ? Math.round((key / amountTabs) * key + 6)
  47. : Math.round(((key - amountTabs) / amountTabs) * (key - amountTabs) + 6);
  48. var endValueVisible = isVisible(document.getElementById(endElement));
  49. if (endValueVisible) {
  50. reachedEndValue = true;
  51. }
  52. if (type === "model") {
  53. playTabModelSonification(panVal, frequencyVal, !rightSideEnd);
  54. } else if (type === "earcon") {
  55. playTabEarconSonification(!rightSideEnd, key, amountTabs);
  56. }
  57. if (reachedEndValue && endValueVisible) {
  58. // Chord End sound play... :)
  59. if (rightSideEnd) {
  60. endElement = 1;
  61. rightSideEnd = false;
  62. } else {
  63. endElement = amountTabs;
  64. rightSideEnd = true;
  65. }
  66. } else if (!endValueVisible) {
  67. //this.playChordSound(panVal, frequencyVal);
  68. //this.playPitchSound(panVal, 200 + 10*key);
  69. }
  70. };
  71. // didReachEnd is bad... That is why, I have my own function... :)
  72. // This sets it to "visible", if at least some part is visible... But maybe I want to have a percentage-based thing...
  73. // If whole viewport is necessary, this makes it also bad, since a scroll all the way is required...
  74. // Not really necessary, since the user already "knows", that this is the end...
  75. const isVisible = (el) => {
  76. var rect = el.getBoundingClientRect();
  77. return (
  78. rect.bottom > 0 &&
  79. rect.right > 0 &&
  80. rect.left < (window.innerWidth || document.documentElement.clientWidth) &&
  81. rect.top < (window.innerHeight || document.documentElement.clientHeight)
  82. );
  83. };
  84. //var keys = Array.from({ length: amountTabs }, (_, i) => i + 1);
  85. // onFocus as an additional thingy?
  86. var tabId = 0;
  87. var tabs = children.map((k) => {
  88. tabId += 1;
  89. return (
  90. <Tab
  91. id={tabId}
  92. //onTouchMove={() => onHoverTab(tabId)}
  93. //onMouseOver={() => onHoverTab(tabId)}
  94. key={tabId}
  95. actionType={k.props.actionType}
  96. redirectLoc={k.props.redirectLoc}
  97. >
  98. {k.props.children}
  99. </Tab>
  100. );
  101. });
  102. const tabsStyle = {
  103. position: "fixed",
  104. bottom: "0",
  105. width: "100vw",
  106. zIndex: "998",
  107. backgroundColor: "white",
  108. };
  109. return (
  110. <div
  111. style={tabsStyle}
  112. onClick={() => {}}
  113. onTouchStart={(event) => {
  114. const eventElement = event.target;
  115. if (eventElement.nodeName === "BUTTON") {
  116. onHoverTab(eventElement.id);
  117. }
  118. }}
  119. >
  120. <Divider />
  121. <Tabs
  122. onMouseOver={() => onHoverElement()}
  123. activeTab={activeTab}
  124. onTabClick={(e, index) => onTabClick(e, index)}
  125. >
  126. {tabs}
  127. </Tabs>
  128. </div>
  129. );
  130. }
  131. export default ScrollableTab;