diff --git a/dist/maidr.js b/dist/maidr.js index 4c232d33..fa22eb62 100644 --- a/dist/maidr.js +++ b/dist/maidr.js @@ -52,6 +52,8 @@ class Constants { MAX_FREQUENCY = 1000; MIN_FREQUENCY = 200; NULL_FREQUENCY = 100; + combinedVolMin = 0.25; // volume for min amplitude combined tones + combinedVolMax = 1.25; // volume for max amplitude combined tones // autoplay speed MAX_SPEED = 500; @@ -1221,9 +1223,14 @@ class Audio { /** * Plays a tone based on the current chart type and position. */ - playTone() { + playTone(params = null) { let currentDuration = constants.duration; let volume = constants.vol; + if (params != null) { + if (params.volScale != null) { + volume = params.volScale * constants.vol; + } + } let rawPanning = 0; let rawFreq = 0; @@ -1967,7 +1974,7 @@ class Display { * @param {string} txt - The text to be displayed in the announce container. */ announceText(txt) { - constants.announceContainer.innerHTML = txt; + this.displayInfo('announce', txt, constants.announceContainer); } /** @@ -2367,26 +2374,35 @@ class Display { * @param {string} textType - The type of text to be displayed. * @param {string} textValue - The value of the text to be displayed. */ - displayInfo(textType, textValue) { - if (textType) { + displayInfo(textType, textValue, elem = constants.infoDiv) { + let textToAdd = ''; + if (textType == 'announce') { + if (textValue) { + textToAdd = textValue; + } + } else if (textType) { if (textValue) { if (constants.textMode == 'terse') { - constants.infoDiv.innerHTML = '

' + textValue + '

'; + textToAdd = textValue; } else if (constants.textMode == 'verbose') { let capsTextType = textType.charAt(0).toUpperCase() + textType.slice(1); - constants.infoDiv.innerHTML = - '

' + capsTextType + ' is ' + textValue + '

'; + textToAdd = capsTextType + ' is ' + textValue; } } else { let aOrAn = ['a', 'e', 'i', 'o', 'u'].includes(textType.charAt(0)) ? 'an' : 'a'; - constants.infoDiv.innerHTML = - '

Plot does not have ' + aOrAn + ' ' + textType + '

'; + textToAdd = 'Plot does not have ' + aOrAn + ' ' + textType; } } + if (textToAdd.length > 0) { + elem.innerHTML = null; + let p = document.createElement('p'); + p.innerHTML = textToAdd; + elem.appendChild(p); + } } /** @@ -4795,7 +4811,10 @@ class ScatterPlot { element = singleMaidr.elements[0]; } let prefix = ''; - if ('element' in singleMaidr && element.tagName.toLowerCase() == 'circle') { + if ( + 'elements' in singleMaidr && + element.tagName.toLowerCase() === 'circle' + ) { prefix = 'c'; } return prefix; @@ -5877,7 +5896,13 @@ class Segmented { position.z += 1; // and kill if we're done - if (position.z + 1 > plot.plotData[position.x][position.y].length) { + if (!Array.isArray(plot.plotData[position.x][position.y])) { + constants.KillSepPlay(); + position.z = -1; + } else if ( + position.z + 1 > + plot.plotData[position.x][position.y].length + ) { constants.KillSepPlay(); position.z = -1; } @@ -5886,9 +5911,20 @@ class Segmented { ); } else { // sonifMode == 'same', so we play all at once + + // adjust these volumes by amplitude, min 50% max 125% + let volMin = Math.min(...this.plotData[position.x][position.y]); + let volMax = Math.max(...this.plotData[position.x][position.y]); for (let i = 0; i < this.plotData[position.x][position.y].length; i++) { position.z = i; - audio.playTone(); + let vol = audio.SlideBetween( + this.plotData[position.x][position.y][i], + volMin, + volMax, + constants.combinedVolMin, + constants.combinedVolMax + ); + audio.playTone({ volScale: vol }); } } } else { diff --git a/dist/maidr.min.js b/dist/maidr.min.js index 5aec5f13..3d26bdb2 100644 --- a/dist/maidr.min.js +++ b/dist/maidr.min.js @@ -1 +1 @@ -class Constants{chart_container_id="chart-container";main_container_id="maidr-container";braille_container_id="braille-div";braille_input_id="braille-input";info_id="info";announcement_container_id="announcements";end_chime_id="end_chime";container_id="container";project_id="maidr";review_id_container="review_container";review_id="review";reviewSaveSpot;reviewSaveBrailleMode;chartId="";events=[];postLoadEvents=[];constructor(){}textMode="verbose";brailleMode="off";sonifMode="on";reviewMode="off";minX=0;maxX=0;minY=0;maxY=0;plotId="";chartType="";navigation=1;MAX_FREQUENCY=1e3;MIN_FREQUENCY=200;NULL_FREQUENCY=100;MAX_SPEED=500;MIN_SPEED=50;DEFAULT_SPEED=250;INTERVAL=20;AUTOPLAY_DURATION=5e3;vol=.5;MAX_VOL=30;autoPlayRate=this.DEFAULT_SPEED;colorSelected="#03C809";brailleDisplayLength=32;showRect=1;hasRect=1;hasSmooth=1;duration=.3;outlierDuration=.06;autoPlayOutlierRate=50;autoPlayPointsRate=50;colorUnselected="#595959";isTracking=1;visualBraille=!1;globalMinMax=!0;showDisplay=1;showDisplayInBraille=1;showDisplayInAutoplay=0;outlierInterval=null;isMac=navigator.userAgent.toLowerCase().includes("mac");control=this.isMac?"Cmd":"Ctrl";alt=this.isMac?"option":"Alt";home=this.isMac?"fn + Left arrow":"Home";end=this.isMac?"fn + Right arrow":"End";keypressInterval=2e3;tabMovement=null;debugLevel=3;canPlayEndChime=!1;manualData=!0;KillAutoplay(){this.autoplayId&&(clearInterval(this.autoplayId),this.autoplayId=null)}KillSepPlay(){this.sepPlayId&&(clearInterval(this.sepPlayId),this.sepPlayId=null)}SpeedUp(){constants.autoPlayRate-this.INTERVAL>this.MIN_SPEED&&(constants.autoPlayRate-=this.INTERVAL)}SpeedDown(){constants.autoPlayRate+this.INTERVAL<=this.MAX_SPEED&&(constants.autoPlayRate+=this.INTERVAL)}SpeedReset(){constants.autoPlayRate=constants.DEFAULT_SPEED}ColorInvert(t){let e=t.replace(/[^\d,]/g,"").split(",");return"rgb("+(255-e[0])+","+(255-e[1])+","+(255-e[2])+")"}GetBetterColor(t){let e=this.ColorInvert(t),n=e.replace(/[^\d,]/g,"").split(",");return n[1]n[0]-10&&n[2]n[0]-10&&(n[0]>86||n[0]<169)&&(e=this.colorSelected),e}}class Resources{constructor(){}language="en";knowledgeLevel="basic";strings={en:{basic:{upper_outlier:"Upper Outlier",lower_outlier:"Lower Outlier",min:"Minimum",max:"Maximum",25:"25%",50:"50%",75:"75%",q1:"25%",q2:"50%",q3:"75%",son_on:"Sonification on",son_off:"Sonification off",son_des:"Sonification descrete",son_comp:"Sonification compare",son_ch:"Sonification chord",son_sep:"Sonification separate",son_same:"Sonification combined",empty:"Empty"}}};GetString(t){return this.strings[this.language][this.knowledgeLevel][t]}}class Menu{whereWasMyFocus=null;constructor(){this.CreateMenu(),this.LoadDataFromLocalStorage()}menuHtml=`\n

\n \n `;CreateMenu(){document.querySelector("body").insertAdjacentHTML("beforeend",this.menuHtml);let t=document.querySelectorAll("#close_menu, #menu .close");for(let e=0;e