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
149 lines
4.3 KiB
import React, { useState } from "react";
|
|
import { Tabs, Tab } from "react-tabs-scrollable";
|
|
import "react-tabs-scrollable/dist/rts.css";
|
|
import { getHeatmapData } from "./webpage_container/StudySite";
|
|
import { pushToMouseLog } from "../core/log/SensorLogger";
|
|
import {
|
|
playTabEarconSonification,
|
|
playTabModelSonification,
|
|
} from "../core/audio/AudioHandler";
|
|
import { Divider } from "@geist-ui/core";
|
|
|
|
var reachedEndValue = false;
|
|
var rightSideEnd = true;
|
|
var endElement = 0;
|
|
var type = "";
|
|
|
|
function ScrollableTab({ onActiveTabChange, sonificationType, children }) {
|
|
const [activeTab, setActiveTab] = useState(0);
|
|
const [amountTabs, setAmountTabs] = useState(children.length);
|
|
endElement = amountTabs;
|
|
type = sonificationType;
|
|
|
|
const saveMouseLog = function () {
|
|
pushToMouseLog(getHeatmapData());
|
|
};
|
|
|
|
// define a onClick function to bind the value on tab click
|
|
const onTabClick = (e, index) => {
|
|
const buttonAttributes = e.target.attributes;
|
|
const actionType = buttonAttributes["actionType"]
|
|
? buttonAttributes.getNamedItem("actionType").value
|
|
: "";
|
|
const redirectLoc = buttonAttributes["redirectLoc"]
|
|
? buttonAttributes.getNamedItem("redirectLoc").value
|
|
: "";
|
|
|
|
if (actionType === "button") {
|
|
saveMouseLog();
|
|
window.location.href = redirectLoc;
|
|
}
|
|
setActiveTab(index);
|
|
onActiveTabChange(index);
|
|
};
|
|
|
|
const onHoverElement = () => {};
|
|
|
|
const onHoverTab = (key) => {
|
|
const clamp = (num, min, max) => Math.min(Math.max(num, min), max);
|
|
const panVal = rightSideEnd
|
|
? clamp(3 * ((-1 / amountTabs) * key + 1) - 2, -1, 1)
|
|
: clamp(2 * ((-1 / amountTabs) * -1 * key + 1) - 4, -1, 1); // ((-1 / amountTabs) * key + 1);
|
|
const frequencyVal = rightSideEnd
|
|
? Math.round((key / amountTabs) * key + 6)
|
|
: Math.round(((key - amountTabs) / amountTabs) * (key - amountTabs) + 6);
|
|
var endValueVisible = isVisible(document.getElementById(endElement));
|
|
|
|
if (endValueVisible) {
|
|
reachedEndValue = true;
|
|
}
|
|
|
|
if (type === "model") {
|
|
playTabModelSonification(panVal, frequencyVal, !rightSideEnd);
|
|
} else if (type === "earcon") {
|
|
playTabEarconSonification(!rightSideEnd, key, amountTabs);
|
|
}
|
|
|
|
if (reachedEndValue && endValueVisible) {
|
|
// Chord End sound play... :)
|
|
if (rightSideEnd) {
|
|
endElement = 1;
|
|
rightSideEnd = false;
|
|
} else {
|
|
endElement = amountTabs;
|
|
rightSideEnd = true;
|
|
}
|
|
} else if (!endValueVisible) {
|
|
//this.playChordSound(panVal, frequencyVal);
|
|
//this.playPitchSound(panVal, 200 + 10*key);
|
|
}
|
|
};
|
|
|
|
// didReachEnd is bad... That is why, I have my own function... :)
|
|
// This sets it to "visible", if at least some part is visible... But maybe I want to have a percentage-based thing...
|
|
// If whole viewport is necessary, this makes it also bad, since a scroll all the way is required...
|
|
// Not really necessary, since the user already "knows", that this is the end...
|
|
const isVisible = (el) => {
|
|
var rect = el.getBoundingClientRect();
|
|
|
|
return (
|
|
rect.bottom > 0 &&
|
|
rect.right > 0 &&
|
|
rect.left < (window.innerWidth || document.documentElement.clientWidth) &&
|
|
rect.top < (window.innerHeight || document.documentElement.clientHeight)
|
|
);
|
|
};
|
|
|
|
//var keys = Array.from({ length: amountTabs }, (_, i) => i + 1);
|
|
// onFocus as an additional thingy?
|
|
var tabId = 0;
|
|
|
|
var tabs = children.map((k) => {
|
|
tabId += 1;
|
|
return (
|
|
<Tab
|
|
id={tabId}
|
|
//onTouchMove={() => onHoverTab(tabId)}
|
|
//onMouseOver={() => onHoverTab(tabId)}
|
|
key={tabId}
|
|
actionType={k.props.actionType}
|
|
redirectLoc={k.props.redirectLoc}
|
|
>
|
|
{k.props.children}
|
|
</Tab>
|
|
);
|
|
});
|
|
|
|
const tabsStyle = {
|
|
position: "fixed",
|
|
bottom: "0",
|
|
width: "100vw",
|
|
zIndex: "998",
|
|
backgroundColor: "white",
|
|
};
|
|
|
|
return (
|
|
<div
|
|
style={tabsStyle}
|
|
onClick={() => {}}
|
|
onTouchStart={(event) => {
|
|
const eventElement = event.target;
|
|
|
|
if (eventElement.nodeName === "BUTTON") {
|
|
onHoverTab(eventElement.id);
|
|
}
|
|
}}
|
|
>
|
|
<Divider />
|
|
<Tabs
|
|
onMouseOver={() => onHoverElement()}
|
|
activeTab={activeTab}
|
|
onTabClick={(e, index) => onTabClick(e, index)}
|
|
>
|
|
{tabs}
|
|
</Tabs>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default ScrollableTab;
|