Controlled number scale visualization

I am currently working on mapping a rotation angle scale in degrees to a light intensity scale representing the movement of a rotating sun, with values ranging from 0.0 to 0.9. To accomplish this, I have implemented a custom mapping function as shown below:

function map (num, in_min, in_max, out_min, out_max)
{
    return (num - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

//(degree, degree in min, degree in max, light intensity out min, light intensity out max
var fade = map(30, 180, 360, 0.0, 0.9);

Despite this functionality, I find that the fading effect is too slow, resulting in a limited duration where the light intensity reaches its maximum value. I seek for more versatility in defining the scale mapping process – how can I achieve this customization?

Answer №1

The response given by @Manuel Otto above is accurate for a scale that goes from one number to a higher number, which was the initial request. However, I required more versatility as I am currently making adhoc adjustments to my sun's position while testing. The function I have developed allows for movement from a number to a lower number as well (since it deals with degrees, resetting at 360 back to 0). For example, going from 180 to 60 involves transitioning from 180 to 360 and then from 0 to 60, resulting in a total of 240 degrees:

// Function to map input degree within range to desired scale with fading speed
function map(num, in_min, in_max, out_min, out_max, factor)
{
    // If input degree is equal to or greater than minimum possible degree
    if (num >= in_min)
    {
        // Simple subtraction
        var delta = Math.max(0, num - in_min);
    } else {
        // Subtract from 360 and add the input degree
        var delta = Math.max(0, ((360 - in_min) + num));
    }

    // If maximum possible degree is equal to or greater than minimum possible degree
    if (in_max >= in_min)
    {
        // Simple subtraction
        var scale = delta / (in_max - in_min);
    } else {
        // Subtract from 360 and add the maximum possible degree
        var scale = delta / ((360 - in_min) + in_max);
    }

    return Math.pow(Math.min(1, scale * 2) - Math.max(0, scale * 2 - 1), factor);
}

I'm sharing this code here in case it may be helpful to others.

Answer №2

If you want to create a quick initial change followed by a long period of minimal change, you can use the formula Math.pow(x,<1).

To achieve a fading in and out effect, you can adjust the value by multiplying it by 2 and then subtracting values above 1 from the result.

function map(num, in_min, in_max, out_min, out_max, factor)
{
  var delta = Math.max(0,num-in_min)
  var scale = delta/(in_max-in_min)

  return Math.pow(Math.min(1,scale*2)-Math.max(0,scale*2-1),factor)
}

When the factor is set to 1, the progression is linear. Lower values will introduce polynomial behavior.

Refer to the demonstration below:

function map(num, in_min, in_max, out_min, out_max, factor)
{
  var delta = Math.max(0,num-in_min)
  var scale = delta/(in_max-in_min)
  
  return Math.pow(Math.min(1,scale*2)-Math.max(0,scale*2-1),factor)
}

// User Interface

var degrees_slider = document.getElementById('degrees')
var factor_slider = document.getElementById('factor')
var degrees_disp = document.getElementById('degrees_disp')
var factor_disp = document.getElementById('factor_disp')
var intensity_disp = document.getElementById('intensity_disp')

degrees_slider.oninput = factor_slider.oninput = update

function update(){
  var num = degrees_slider.value
  var fact = factor_slider.value
  
  degrees_disp.innerHTML = num
  factor_disp.innerHTML = fact
  intensity_disp.innerHTML = toPercent(map(num, 180, 360, 0.0, 0.9, fact))
  
}

function toPercent(val){
  return Math.round(val*100)+'%'
}

update()
#intensity_disp{
  font-size: 32pt;
  margin-top: 25px;
}
<label for="degrees">Degrees</label>
<br>
<input type="range" id="degrees" min="0" max="360" step="1"/>
<span id="degrees_disp"></span>

<br><br>

<label for="degrees">Linearity</label>
<br>
<input type="range" id="factor" min="0" max="1" step="0.01"/>
<span id="factor_disp"></span>

<div id="intensity_disp"></div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Delay in loading Jquery accordion due to value binding

I've noticed that my jquery accordion takes a significant amount of time to collapse when the page initially loads. After some investigation, I realized that the issue lies in the fact that there are numerous multiselect listboxes within the accordio ...

Error: The requested collection# cannot be found in the Node.js Express routing system

Recently, I have started learning nodejs and implemented a simple API that allows users to log in with passport and then redirects them to the /collections route. While this part is functioning correctly, I am encountering issues with POST requests which a ...

Two-way binding with Angular2's NgModel can encounter issues

After executing a GET XMLHttpRequest against a service, I received the following JSON payload as a response : {_id: "5aa1358d32eba9e34dd9f280", source: "Avengers", target: "Iron Man", enemies: "Actor"} Within my src/app directory, I have defined the obje ...

Handling onclick events in Scrapy Splash: A comprehensive guide

I am attempting to extract data from the following website I have managed to receive a response, but I am unsure how to access the inner data of the items below for scraping: It seems that accessing the items requires handling JavaScript and pagination. ...

Guide to implementing a random number generator within a Jquery conditional statement

I am experimenting with if statements, but I'm encountering some difficulties. My goal is to assign random numbers to a variable and then trigger different actions based on a click event. Here's what I've tried so far, but it seems to be fa ...

A common inquiry: how can one pinpoint a location within an irregular figure?

I have been studying Html5 Canvas for a few weeks now, and the challenge mentioned above has puzzled me for quite some time. An irregular shape could be a circle, rectangle, ellipse, polygon, or a path constructed by various lines and bezier curves... I ...

Currently I am developing a Minimax Algorithm implementation for my reversi game using react.js, however I am encountering a RangeError

I've been implementing a Minimax Algorithm for my reversi game to create a strong AI opponent for players. However, I ran into the following error message: "RangeError: Maximum call stack size exceeded" How can I go about resolving this issue? Here ...

Django Ajax filter displaying issue on HTML page

I'm uncertain about the correctness of my Ajax implementation. When using Django's built-in tags, the objects I pass through Ajax are not appearing on my template HTML page. view_results.html <div> <input id="search" name="search" t ...

Utilizing setColumns() function within Google Charts for JSON data tables

Is there a feature in the Google Charts API that functions similar to setColumns() for working with JSON data? I'm aiming to reduce PHP calls by consolidating my data into a single array and then specifying which columns Google Charts should utilize. ...

Validate Email and Phone Number using Javascript

How can I create a Javascript function to validate an HTML form? Currently, my form validation only checks if a field is empty. I want to enhance it to also validate the email format and ensure the phone number is numeric. Currently, the form displays a po ...

Trying to access properties of undefined

I am having trouble adding the form control class to my select statement. The issue arises when props become undefined. Here's the code snippet: const useStyles = makeStyles({ root: { width: "100%", maxWidth: 500 } }); const cl ...

When clicking on HTML input fields, they do not receive focus

I am facing a puzzling issue where I am unable to access the input fields and textareas on my HTML form. The JS, HTML, and CSS files are too large for me to share here. Could someone provide guidance on what steps to take when troubleshooting this unusual ...

Is it possible to pass additional arguments to setState other than prevState and props?

I'm currently facing an issue with my component that involves calling a function called addOption, which is defined on its parent component. This function takes a parameter 'option' from a form field and concatenates it with an array of opti ...

Using TypeScript and the `this` keyword in SharePoint Framework with Vue

I'm currently developing a SharePoint Framework web part with Vue.js. Check out this code snippet: export default class MyWorkspaceTestWebPart extends BaseClientSideWebPart<IMyWorkspaceTestWebPartProps> { public uol_app; public render(): ...

Difficulty arises when collapsed text in Bootstrap clashes with the footer design

Hey there! I'm working on this website using Bootstrap, and I've encountered a problem. When you click the "See Wikipedia" button, the content expands and overlaps the footer in a strange way without changing the page height. I've tried adju ...

What is the process for executing code on a server by clicking a button?

In my Next.js application, there is a file named dummy.js with the following content: class Dummy extends React.Component{ static async getInitialProps(ctx){ return { dummy : 'abc'}; } displayHelloWorld(params) { cons ...

Implementing the Jssor slider

Recently, I've been using the jssor slider on multiple pages without any issues. However, I am now facing some challenges. Ideally, I want the slider to be hidden initially and then displayed with another script. While I have managed to achieve this v ...

Finding the location of a file within a published web component

I am currently working on a webcomponent where I need to include a link tag in the head section and set the href attribute to a folder within a node module. At this stage, during the development of my component, my project structure looks like this: http ...

A guide to accessing the innerHTML of a div using React

My current setup involves creating an editable-content field as shown below const Input = () => { const Enter = () => { ... } const Editable = () => ( <div className={"editable"} contentEditable={"true"}> This i ...

What could potentially be the reason behind the incapability of the next.js Image component to transform the svg into a

Unique Context I recently developed a minimalist Hero + Navbar using Next.js. The site utilizes the powerful next.js Image component to display images. Surprisingly, all three images on the website, which are in .webp format, load instantly with a size of ...