meter.ts 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. Macro.add('meter', {
  2. skipArgs : false,
  3. handler : function () {
  4. try{
  5. const current = this.args[0];
  6. const min = this.args[1] ?? 0;
  7. const max = this.args[2] ?? 100;
  8. const options = this.args[3] ?? {};
  9. let colors:{start: number; color: string;}[] = options.colors ?? [];
  10. if(colors.length < 2)
  11. colors = [{start:0,color:'red'},{start:1,color:'green'}];
  12. const colorMode = options.colorMode ?? 'gradient';
  13. colors.sort((a,b)=>a.start-b.start);
  14. const currentPercentage = (current - min) / (max - min);
  15. let currentColor = 'black';
  16. if(currentPercentage < 0)
  17. currentColor = colors.first().color;
  18. else if(currentPercentage >= 1)
  19. currentColor = colors.last().color;
  20. else{
  21. switch (colorMode) {
  22. case 'gradient':
  23. const lower = colors.toReversed().find(element=>element.start<=currentPercentage) ?? {start:min, color: 'black'};
  24. const higher = colors.find(element=>element.start>currentPercentage) ?? {start: max, color: 'black'};
  25. const colorPercentage = (currentPercentage - lower.start) / (higher.start - lower.start);
  26. currentColor = `color-mix(in hsl, ${higher.color} ${Math.floor(colorPercentage*100)}%, ${lower.color})`;
  27. default:
  28. break;
  29. }
  30. }
  31. $(this.output).wiki(`<div class="meter" style="--percentage:${currentPercentage}"><div class="bar" style="background:${currentColor};"></div></div>`);
  32. }
  33. catch (ex) {
  34. return this.error('ERROR in meter-widget: ' + ex.message);
  35. }
  36. }
  37. });