No edit summary Tag: Manual revert |
No edit summary |
||
| Line 1: | Line 1: | ||
<noinclude>__NOTOC__ | <noinclude>__NOTOC__ | ||
This | This widget converts with one neutral slider N and two editable fields. | ||
=Usage= | =Usage= | ||
{{#widget: | {{#widget:ConvertCalc | ||
| id=cc1 | | id=cc1 | ||
| TopLabel= | | TopLabel=years | ||
| TopFactor=1.3125 | | TopFactor=1.3125 | ||
| BottomLabel=Cycles | | BottomLabel=Cycles | ||
| Line 12: | Line 12: | ||
| SliderMax=100 | | SliderMax=100 | ||
| SliderStep=0.1 | | SliderStep=0.1 | ||
| Decimals=1 | |||
| NumStep=0.1 | |||
}} | }} | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
! param !! meaning !! default | ! param !! meaning !! default | ||
|- | |- | ||
| TopLabel || | | TopLabel || label for the top unit || years | ||
|- | |- | ||
| TopFactor || | | TopFactor || multiplier for top value (Top = N * TopFactor) || 1.3125 | ||
|- | |- | ||
| BottomLabel || | | BottomLabel || label for the bottom unit || Cycles | ||
|- | |- | ||
| BottomFactor || | | BottomFactor || multiplier for bottom value (Bottom = N * BottomFactor) || 1 | ||
|- | |- | ||
| SliderMin || | | SliderMin / SliderMax / SliderStep || slider range & step for N || 1 / 100 / 0.1 | ||
|- | |- | ||
| | | Decimals || fixed decimals to display || 1 | ||
|- | |- | ||
| | | NumStep || step on the number inputs || 0.1 | ||
|} | |} | ||
</noinclude><includeonly> | </noinclude><includeonly> | ||
<div class="wh-convert" style="max-width:32rem;margin:1rem 0;"> | |||
<!-- Top label --> | |||
<div style="font-weight:700;margin-bottom:.25rem;" id="<!--{$id|default:'cc'|escape:'html'}-->-topLbl"> | |||
<!--{$TopLabel|default:'years'|escape:'html'}--> | |||
</div> | |||
<div | <!-- Top value (editable) --> | ||
<div style="text-align:center;margin-bottom:.4rem;"> | |||
<input id="<!--{$id|default:'cc'|escape:'html'}-->-topVal" type="number" | |||
step="<!--{$NumStep|default:0.1|escape:'html'}-->" inputmode="decimal" | |||
style="font:600 1.4rem/1 system-ui, -apple-system, Segoe UI, Roboto, sans-serif; | |||
width:12ch;padding:.15rem .35rem;text-align:right;"> | |||
<span id="<!--{$id|default:'cc'|escape:'html'}-->-topUnit" | |||
style="font-weight:600;margin-left:.25rem;"> | |||
<!--{$TopLabel|default:'years'|escape:'html'}--> | |||
</span> | |||
</div> | |||
<div id="<!--{$id|default:'cc'|escape:'html'}-->- | <!-- Slider row --> | ||
<div style="display:flex;align-items:center;gap:.5rem;margin:.25rem 0;"> | |||
<input id="<!--{$id|default:'cc'|escape:'html'}-->-N" type="range" | |||
min="<!--{$SliderMin|default:1|escape:'html'}-->" | |||
max="<!--{$SliderMax|default:100|escape:'html'}-->" | |||
step="<!--{$SliderStep|default:0.1|escape:'html'}-->" | |||
value="<!--{$SliderMin|default:1|escape:'html'}-->" | |||
style="flex:1;"> | |||
<button id="<!--{$id|default:'cc'|escape:'html'}-->-swap" | |||
title="Swap units" | |||
style="font-size:.95rem;padding:.2rem .5rem;cursor:pointer;">⇅</button> | |||
</div> | </div> | ||
<input id="<!--{$id|default:'cc'|escape:'html'}-->- | <!-- Bottom value (editable) --> | ||
<div style="text-align:center;margin:.4rem 0;"> | |||
<input id="<!--{$id|default:'cc'|escape:'html'}-->-botVal" type="number" | |||
step="<!--{$NumStep|default:0.1|escape:'html'}-->" inputmode="decimal" | |||
style="font:600 1.4rem/1 system-ui, -apple-system, Segoe UI, Roboto, sans-serif; | |||
width:12ch;padding:.15rem .35rem;text-align:right;"> | |||
<span id="<!--{$id|default:'cc'|escape:'html'}-->-botUnit" | |||
style="font-weight:600;margin-left:.25rem;"> | |||
<!--{$BottomLabel|default:'Cycles'|escape:'html'}--> | |||
</span> | |||
</div> | |||
<div id="<!--{$id|default:'cc'|escape:'html'}-->- | <!-- Bottom label --> | ||
<div style="font-weight:700;margin-top:.25rem;" id="<!--{$id|default:'cc'|escape:'html'}-->-botLbl"> | |||
<!--{$BottomLabel|default:'Cycles'|escape:'html'}--> | |||
</div> | </div> | ||
</div> | </div> | ||
| Line 62: | Line 89: | ||
function ge(s){ return document.getElementById(ID + s); } | function ge(s){ return document.getElementById(ID + s); } | ||
var TopLabel | // Params | ||
var TopFactor | var TopLabel = "<!--{$TopLabel|default:'years'|escape:'js'}-->"; | ||
var | var BottomLabel = "<!--{$BottomLabel|default:'Cycles'|escape:'js'}-->"; | ||
var | var TopFactor = parseFloat("<!--{$TopFactor|default:1.3125|escape:'js'}-->") || 1.3125; | ||
var BottomFactor = parseFloat("<!--{$BottomFactor|default:1|escape:'js'}-->") || 1; | |||
var MIN = parseFloat("<!--{$SliderMin|default:1|escape:'js'}-->") || 1; | |||
var MAX = parseFloat("<!--{$SliderMax|default:100|escape:'js'}-->") || 100; | |||
var STEP = parseFloat("<!--{$SliderStep|default:0.1|escape:'js'}-->") || 0.1; | |||
var DEC = parseInt("<!--{$Decimals|default:1|escape:'js'}-->") || 1; | |||
// Elements | |||
var el = { | |||
topLbl: ge("-topLbl"), | |||
botLbl: ge("-botLbl"), | |||
topUnit: ge("-topUnit"), | |||
botUnit: ge("-botUnit"), | |||
topVal: ge("-topVal"), | |||
botVal: ge("-botVal"), | |||
N: ge("-N"), | |||
swap: ge("-swap") | |||
}; | |||
// Format helpers | |||
function clamp(v,min,max){ return Math.max(min, Math.min(max, v)); } | |||
function fix(v){ return Number(v).toFixed(DEC); } | |||
// Core updates (N drives both) | |||
function setFromN(n){ | |||
n = clamp(n, MIN, MAX); | |||
el.N.value = n; | |||
el.topVal.value = fix(n * TopFactor); | |||
el.botVal.value = fix(n * BottomFactor); | |||
} | } | ||
function | // When top changes, derive N from top | ||
function setFromTop(x){ | |||
var n = x / TopFactor; | |||
setFromN(n); | |||
} | |||
// When bottom changes, derive N from bottom | |||
function setFromBot(x){ | |||
var n = x / BottomFactor; | |||
setFromN(n); | |||
} | } | ||
// Bind events (with light debouncing via rAF) | |||
var raf = null; | |||
function queue(fn){ if(raf) return; raf = requestAnimationFrame(function(){ raf=null; fn(); }); } | |||
el.N.addEventListener("input", function(){ queue(function(){ setFromN(parseFloat(el.N.value)); }); }); | |||
el.topVal.addEventListener("input", function(){ queue(function(){ setFromTop(parseFloat(el.topVal.value)); }); }); | |||
el.botVal.addEventListener("input", function(){ queue(function(){ setFromBot(parseFloat(el.botVal.value)); }); }); | |||
// Swap labels & factors but preserve the visible numbers by keeping N constant | |||
el.swap.addEventListener("click", function(){ | |||
// swap labels | |||
var tl = TopLabel, bl = BottomLabel; | |||
TopLabel = bl; BottomLabel = tl; | |||
el.topLbl.textContent = TopLabel; | |||
el.topUnit.textContent = TopLabel; | |||
el.botLbl.textContent = BottomLabel; | |||
el.botUnit.textContent = BottomLabel; | |||
// swap factors | |||
var tf = TopFactor; TopFactor = BottomFactor; BottomFactor = tf; | |||
// recompute from current N | |||
setFromN(parseFloat(el.N.value)); | |||
}); | }); | ||
// Init starting state | |||
setFromN(MIN); | |||
})(); | })(); | ||
</script> | </script> | ||
</includeonly> | </includeonly> | ||
Revision as of 22:59, 11 November 2025
This widget converts with one neutral slider N and two editable fields.
Usage
| param | meaning | default |
|---|---|---|
| TopLabel | label for the top unit | years |
| TopFactor | multiplier for top value (Top = N * TopFactor) | 1.3125 |
| BottomLabel | label for the bottom unit | Cycles |
| BottomFactor | multiplier for bottom value (Bottom = N * BottomFactor) | 1 |
| SliderMin / SliderMax / SliderStep | slider range & step for N | 1 / 100 / 0.1 |
| Decimals | fixed decimals to display | 1 |
| NumStep | step on the number inputs | 0.1 |