gaugeit.js 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- /*! Gaugeit.js v0.1.0 | MIT License | https://github.com/kasperikoski/gaugeit.js#readme */
1
+ /*! Gaugeit.js v0.1.1 | MIT License | https://github.com/kasperikoski/gaugeit.js#readme */
2
2
  (function (root, factory) {
3
3
  if (typeof define === "function" && define.amd) define([], factory);
4
4
  else if (typeof module === "object" && module.exports) module.exports = factory();
@@ -882,7 +882,13 @@ var Gaugeit = (() => {
882
882
  if (!(light == null ? void 0 : light.visible)) return;
883
883
  const point = resolveLightPosition(light, options);
884
884
  const radius = Math.max(1, finiteNumber(light.radius, 8));
885
- const halo = light.glow ? radius * 2.96 : radius;
885
+ const glowRadius = Math.max(0, finiteNumber(light.glowRadius, radius * 1.82));
886
+ const flickerGlowRadius = light.flicker ? Math.min(1, Math.max(0, finiteNumber(light.flickerGlowRadius, 0))) : 0;
887
+ const maximumGlowRadius = glowRadius * (1 + flickerGlowRadius);
888
+ const glowSharpness = Math.min(1, Math.max(0, finiteNumber(light.glowSharpness, 0)));
889
+ const maximumBlur = glowRadius > 0 ? Math.max(1.4, glowRadius * 0.38) : 0;
890
+ const glowBlur = maximumBlur * (1 - glowSharpness);
891
+ const halo = light.glow ? maximumGlowRadius + glowBlur * 3 + (maximumGlowRadius > 0 ? 1e-9 : 0) : radius;
886
892
  const bezel = radius + Math.max(1.5, radius * 0.18);
887
893
  const extent = Math.max(halo, bezel);
888
894
  includeRect(bounds, point.x - extent, point.y - extent, extent * 2, extent * 2);
@@ -1328,28 +1334,36 @@ var Gaugeit = (() => {
1328
1334
  },
1329
1335
  light: {
1330
1336
  visible: false,
1331
- x: 160,
1337
+ x: 93,
1332
1338
  y: 110,
1333
1339
  radius: 8,
1334
- color: "amber",
1340
+ glowRadius: 20,
1341
+ glowSharpness: 0,
1342
+ color: "red",
1335
1343
  customColor: "",
1336
1344
  offColor: "#f3ead6",
1337
1345
  offEdgeColor: "#817768",
1338
1346
  bezelColor: "#4b5563",
1339
1347
  bezelHighlightColor: "#f8fafc",
1340
1348
  opacity: 1,
1349
+ glowOpacity: 0.15,
1341
1350
  on: false,
1342
1351
  glow: true,
1343
- pulse: true,
1352
+ pulse: false,
1344
1353
  pulseInterval: 2600,
1345
1354
  blink: false,
1346
1355
  blinkInterval: 1e3,
1356
+ flicker: true,
1357
+ flickerIntensity: 0.1,
1358
+ flickerGlowRadius: 0.1,
1359
+ flickerMinInterval: 45,
1360
+ flickerMaxInterval: 140,
1347
1361
  trigger: {
1348
- mode: "manual",
1362
+ mode: "below",
1349
1363
  source: "target",
1350
- value: 0,
1364
+ value: 15,
1351
1365
  min: 0,
1352
- max: 0
1366
+ max: 15
1353
1367
  }
1354
1368
  },
1355
1369
  readout: {
@@ -1652,27 +1666,63 @@ var Gaugeit = (() => {
1652
1666
  tape.colorByZone = tape.colorByZone === true;
1653
1667
  }
1654
1668
  function validateLight(light) {
1669
+ const defaults2 = BASE_DEFAULTS.light;
1655
1670
  light.visible = light.visible === true;
1656
- light.x = finiteNumber(light.x, 160);
1657
- light.y = finiteNumber(light.y, 110);
1658
- light.radius = Math.max(1, finiteNumber(light.radius, 8));
1659
- light.color = VALID_LIGHT_COLORS.has(light.color) ? light.color : "amber";
1660
- light.customColor = light.customColor === null || light.customColor === void 0 ? "" : String(light.customColor).trim();
1661
- light.offColor = normalizeColor(light.offColor, "#f3ead6");
1662
- light.offEdgeColor = normalizeColor(light.offEdgeColor, "#817768");
1663
- light.bezelColor = normalizeColor(light.bezelColor, "#4b5563");
1664
- light.bezelHighlightColor = normalizeColor(light.bezelHighlightColor, "#f8fafc");
1665
- light.opacity = Math.min(1, Math.max(0, finiteNumber(light.opacity, 1)));
1671
+ light.x = finiteNumber(light.x, defaults2.x);
1672
+ light.y = finiteNumber(light.y, defaults2.y);
1673
+ light.radius = Math.max(1, finiteNumber(light.radius, defaults2.radius));
1674
+ light.glowRadius = light.glowRadius === null || light.glowRadius === void 0 ? light.radius * 1.82 : Math.max(0, finiteNumber(light.glowRadius, defaults2.glowRadius));
1675
+ light.glowSharpness = Math.min(
1676
+ 1,
1677
+ Math.max(0, finiteNumber(light.glowSharpness, defaults2.glowSharpness))
1678
+ );
1679
+ light.color = VALID_LIGHT_COLORS.has(light.color) ? light.color : defaults2.color;
1680
+ light.customColor = light.customColor === null || light.customColor === void 0 ? defaults2.customColor : String(light.customColor).trim();
1681
+ light.offColor = normalizeColor(light.offColor, defaults2.offColor);
1682
+ light.offEdgeColor = normalizeColor(light.offEdgeColor, defaults2.offEdgeColor);
1683
+ light.bezelColor = normalizeColor(light.bezelColor, defaults2.bezelColor);
1684
+ light.bezelHighlightColor = normalizeColor(
1685
+ light.bezelHighlightColor,
1686
+ defaults2.bezelHighlightColor
1687
+ );
1688
+ light.opacity = Math.min(1, Math.max(0, finiteNumber(light.opacity, defaults2.opacity)));
1689
+ light.glowOpacity = Math.min(
1690
+ 1,
1691
+ Math.max(0, finiteNumber(light.glowOpacity, defaults2.glowOpacity))
1692
+ );
1666
1693
  light.on = light.on === true;
1667
1694
  light.glow = light.glow !== false;
1668
- light.pulse = light.pulse !== false;
1669
- light.pulseInterval = Math.max(400, finiteNumber(light.pulseInterval, 2600));
1695
+ light.pulse = light.pulse === true;
1696
+ light.pulseInterval = Math.max(400, finiteNumber(light.pulseInterval, defaults2.pulseInterval));
1670
1697
  light.blink = light.blink === true;
1671
- light.blinkInterval = Math.max(100, finiteNumber(light.blinkInterval, 1e3));
1698
+ light.blinkInterval = Math.max(100, finiteNumber(light.blinkInterval, defaults2.blinkInterval));
1699
+ light.flicker = light.flicker === true;
1700
+ light.flickerIntensity = Math.min(
1701
+ 1,
1702
+ Math.max(0, finiteNumber(light.flickerIntensity, defaults2.flickerIntensity))
1703
+ );
1704
+ light.flickerGlowRadius = Math.min(
1705
+ 1,
1706
+ Math.max(0, finiteNumber(light.flickerGlowRadius, defaults2.flickerGlowRadius))
1707
+ );
1708
+ light.flickerMinInterval = Math.max(
1709
+ 16,
1710
+ finiteNumber(light.flickerMinInterval, defaults2.flickerMinInterval)
1711
+ );
1712
+ light.flickerMaxInterval = Math.max(
1713
+ 16,
1714
+ finiteNumber(light.flickerMaxInterval, defaults2.flickerMaxInterval)
1715
+ );
1716
+ if (light.flickerMaxInterval < light.flickerMinInterval) {
1717
+ [light.flickerMinInterval, light.flickerMaxInterval] = [
1718
+ light.flickerMaxInterval,
1719
+ light.flickerMinInterval
1720
+ ];
1721
+ }
1672
1722
  light.trigger = isPlainObject(light.trigger) ? light.trigger : {};
1673
- light.trigger.mode = VALID_LIGHT_TRIGGER_MODES.has(light.trigger.mode) ? light.trigger.mode : "manual";
1674
- light.trigger.source = VALID_LIGHT_TRIGGER_SOURCES.has(light.trigger.source) ? light.trigger.source : "target";
1675
- light.trigger.value = finiteNumber(light.trigger.value, 0);
1723
+ light.trigger.mode = VALID_LIGHT_TRIGGER_MODES.has(light.trigger.mode) ? light.trigger.mode : defaults2.trigger.mode;
1724
+ light.trigger.source = VALID_LIGHT_TRIGGER_SOURCES.has(light.trigger.source) ? light.trigger.source : defaults2.trigger.source;
1725
+ light.trigger.value = finiteNumber(light.trigger.value, defaults2.trigger.value);
1676
1726
  light.trigger.min = finiteNumber(light.trigger.min, light.trigger.value);
1677
1727
  light.trigger.max = finiteNumber(light.trigger.max, light.trigger.value);
1678
1728
  if (light.trigger.max < light.trigger.min) {
@@ -2793,17 +2843,17 @@ var Gaugeit = (() => {
2793
2843
  if (!(light == null ? void 0 : light.visible)) return null;
2794
2844
  const { x, y } = resolveLightPosition(light, options);
2795
2845
  const palette = resolvePalette(light);
2796
- const colorName = Object.prototype.hasOwnProperty.call(LIGHT_PALETTES, light.color) ? light.color : "amber";
2846
+ const colorName = Object.prototype.hasOwnProperty.call(LIGHT_PALETTES, light.color) ? light.color : "red";
2797
2847
  const glowFilterId = `${renderer.id}-light-glow`;
2798
2848
  const onGradientId = `${renderer.id}-light-on`;
2799
2849
  const offGradientId = `${renderer.id}-light-off`;
2800
2850
  const bezelGradientId = `${renderer.id}-light-bezel`;
2801
2851
  const defs = svgElement("defs");
2802
2852
  defs.append(
2803
- createGlowFilter(glowFilterId, light.radius),
2853
+ createGlowFilter(glowFilterId, light.glowRadius, light.glowSharpness),
2804
2854
  createBulbGradient(onGradientId, {
2805
- center: "#ffffff",
2806
- highlight: palette.highlight,
2855
+ center: palette.highlight,
2856
+ highlight: palette.core,
2807
2857
  middle: palette.core,
2808
2858
  edge: palette.rim
2809
2859
  }),
@@ -2826,6 +2876,8 @@ var Gaugeit = (() => {
2826
2876
  lamp.style.setProperty("--gaugeit-light-blink-duration", `${light.blinkInterval}ms`);
2827
2877
  lamp.style.setProperty("--gaugeit-light-pulse-duration", `${light.pulseInterval}ms`);
2828
2878
  lamp.style.setProperty("--gaugeit-light-opacity", String(light.opacity));
2879
+ lamp.style.setProperty("--gaugeit-light-on-opacity", String(light.opacity));
2880
+ lamp.style.setProperty("--gaugeit-light-glow-opacity", String(light.glowOpacity));
2829
2881
  const bezel = svgElement("circle", {
2830
2882
  class: "gaugeit__light-bezel",
2831
2883
  cx: 0,
@@ -2848,9 +2900,7 @@ var Gaugeit = (() => {
2848
2900
  radius: light.radius,
2849
2901
  gradientId: offGradientId,
2850
2902
  edgeColor: light.offEdgeColor,
2851
- glowColor: null,
2852
- glowFilterId: null,
2853
- sparkleOpacity: 0.58,
2903
+ sparkleOpacity: 0.24,
2854
2904
  shadeOpacity: 0.14
2855
2905
  });
2856
2906
  const onVisual = createLampVisual({
@@ -2858,13 +2908,18 @@ var Gaugeit = (() => {
2858
2908
  radius: light.radius,
2859
2909
  gradientId: onGradientId,
2860
2910
  edgeColor: palette.rim,
2861
- glowColor: palette.glow,
2862
- glowFilterId,
2863
- sparkleOpacity: 0.72,
2911
+ sparkleOpacity: 0.26,
2864
2912
  shadeOpacity: 0.1
2865
2913
  });
2866
- lamp.append(bezel, bezelHighlight, offVisual, onVisual);
2914
+ const glowVisual = createGlowVisual({
2915
+ radius: light.glowRadius,
2916
+ color: palette.glow,
2917
+ filterId: glowFilterId
2918
+ });
2919
+ lamp.append(glowVisual, bezel, bezelHighlight, offVisual, onVisual);
2867
2920
  group.append(lamp);
2921
+ const glowElement = glowVisual.querySelector(".gaugeit__light-glow");
2922
+ let flickerTimer = null;
2868
2923
  return {
2869
2924
  update(value, state = {}) {
2870
2925
  var _a;
@@ -2872,13 +2927,54 @@ var Gaugeit = (() => {
2872
2927
  const active = lightIsActive(light, sample);
2873
2928
  const blinking = active && light.blink;
2874
2929
  const pulsing = active && light.pulse && !blinking;
2930
+ const flickering = active && light.flicker && (light.flickerIntensity > 0 || light.flickerGlowRadius > 0) && !prefersReducedMotion();
2875
2931
  lamp.classList.toggle("is-on", active);
2876
2932
  lamp.classList.toggle("is-blinking", blinking);
2877
2933
  lamp.classList.toggle("is-pulsing", pulsing);
2934
+ lamp.classList.toggle("is-flickering", flickering);
2878
2935
  lamp.classList.toggle("has-glow", light.glow);
2879
2936
  lamp.setAttribute("data-gaugeit-light-state", active ? "on" : "off");
2937
+ setFlickerRunning(flickering);
2938
+ },
2939
+ destroy() {
2940
+ stopFlicker();
2880
2941
  }
2881
2942
  };
2943
+ function setFlickerRunning(enabled) {
2944
+ if (!enabled) {
2945
+ stopFlicker();
2946
+ return;
2947
+ }
2948
+ if (flickerTimer !== null) return;
2949
+ updateFlicker();
2950
+ scheduleFlicker();
2951
+ }
2952
+ function scheduleFlicker() {
2953
+ const delay = randomBetween(light.flickerMinInterval, light.flickerMaxInterval);
2954
+ flickerTimer = setTimeout(() => {
2955
+ flickerTimer = null;
2956
+ updateFlicker();
2957
+ scheduleFlicker();
2958
+ }, delay);
2959
+ }
2960
+ function updateFlicker() {
2961
+ const lightLevel = 1 - Math.random() * light.flickerIntensity;
2962
+ const onOpacity = light.opacity * lightLevel;
2963
+ const glowOpacity = light.glowOpacity * lightLevel;
2964
+ lamp.style.setProperty("--gaugeit-light-on-opacity", onOpacity.toFixed(3));
2965
+ lamp.style.setProperty("--gaugeit-light-glow-opacity", glowOpacity.toFixed(3));
2966
+ if (glowElement) {
2967
+ const variation = randomBetween(-light.flickerGlowRadius, light.flickerGlowRadius);
2968
+ glowElement.setAttribute("r", String(light.glowRadius * (1 + variation)));
2969
+ }
2970
+ }
2971
+ function stopFlicker() {
2972
+ if (flickerTimer !== null) clearTimeout(flickerTimer);
2973
+ flickerTimer = null;
2974
+ lamp.style.setProperty("--gaugeit-light-on-opacity", String(light.opacity));
2975
+ lamp.style.setProperty("--gaugeit-light-glow-opacity", String(light.glowOpacity));
2976
+ if (glowElement) glowElement.setAttribute("r", String(light.glowRadius));
2977
+ }
2882
2978
  }
2883
2979
  };
2884
2980
  function createLampVisual({
@@ -2886,8 +2982,6 @@ var Gaugeit = (() => {
2886
2982
  radius,
2887
2983
  gradientId,
2888
2984
  edgeColor,
2889
- glowColor,
2890
- glowFilterId,
2891
2985
  sparkleOpacity,
2892
2986
  shadeOpacity
2893
2987
  }) {
@@ -2895,16 +2989,6 @@ var Gaugeit = (() => {
2895
2989
  class: `gaugeit__light-emission gaugeit__light-emission--${state}`,
2896
2990
  "data-gaugeit-light-visual": state
2897
2991
  });
2898
- if (glowColor && glowFilterId) {
2899
- visual.append(svgElement("circle", {
2900
- class: "gaugeit__light-glow",
2901
- cx: 0,
2902
- cy: 0,
2903
- r: radius * 1.82,
2904
- fill: glowColor,
2905
- filter: `url(#${glowFilterId})`
2906
- }));
2907
- }
2908
2992
  visual.append(
2909
2993
  svgElement("circle", {
2910
2994
  class: `gaugeit__light-bulb gaugeit__light-bulb--${state}`,
@@ -2933,18 +3017,33 @@ var Gaugeit = (() => {
2933
3017
  );
2934
3018
  return visual;
2935
3019
  }
3020
+ function createGlowVisual({ radius, color, filterId }) {
3021
+ const visual = svgElement("g", {
3022
+ class: "gaugeit__light-glow-emission",
3023
+ "data-gaugeit-light-visual": "glow"
3024
+ });
3025
+ visual.append(svgElement("circle", {
3026
+ class: "gaugeit__light-glow",
3027
+ cx: 0,
3028
+ cy: 0,
3029
+ r: radius,
3030
+ fill: color,
3031
+ filter: `url(#${filterId})`
3032
+ }));
3033
+ return visual;
3034
+ }
2936
3035
  function resolvePalette(light) {
2937
- const named = LIGHT_PALETTES[light.color] || LIGHT_PALETTES.amber;
3036
+ const named = LIGHT_PALETTES[light.color] || LIGHT_PALETTES.red;
2938
3037
  const custom = String(light.customColor || "").trim();
2939
3038
  if (!custom) return named;
2940
3039
  return {
2941
3040
  core: custom,
2942
- highlight: "#ffffff",
3041
+ highlight: custom,
2943
3042
  glow: custom,
2944
3043
  rim: custom
2945
3044
  };
2946
3045
  }
2947
- function createGlowFilter(id, radius) {
3046
+ function createGlowFilter(id, glowRadius, sharpness) {
2948
3047
  const filter = svgElement("filter", {
2949
3048
  id,
2950
3049
  x: "-120%",
@@ -2952,11 +3051,18 @@ var Gaugeit = (() => {
2952
3051
  width: "340%",
2953
3052
  height: "340%"
2954
3053
  });
3054
+ const maximumBlur = Math.max(1.4, glowRadius * 0.38);
2955
3055
  filter.append(svgElement("feGaussianBlur", {
2956
- stdDeviation: Math.max(1.4, radius * 0.38)
3056
+ stdDeviation: maximumBlur * (1 - sharpness)
2957
3057
  }));
2958
3058
  return filter;
2959
3059
  }
3060
+ function randomBetween(min, max) {
3061
+ return min + Math.random() * (max - min);
3062
+ }
3063
+ function prefersReducedMotion() {
3064
+ return typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
3065
+ }
2960
3066
  function createBulbGradient(id, colors) {
2961
3067
  const gradient = svgElement("radialGradient", {
2962
3068
  id,
@@ -3044,13 +3150,6 @@ var Gaugeit = (() => {
3044
3150
  width: 8,
3045
3151
  cap: { radius: 7, stackOrder: "above" }
3046
3152
  },
3047
- light: {
3048
- visible: false,
3049
- x: 160,
3050
- y: 142,
3051
- radius: 7,
3052
- color: "amber"
3053
- },
3054
3153
  readout: {
3055
3154
  title: { visible: false, x: "auto", y: 35 },
3056
3155
  value: { visible: false, x: 160, y: 130, fontSize: 30 },
@@ -3139,13 +3238,6 @@ var Gaugeit = (() => {
3139
3238
  strokeWidth: 2
3140
3239
  }
3141
3240
  },
3142
- light: {
3143
- visible: false,
3144
- x: 112,
3145
- y: 112,
3146
- radius: 8,
3147
- color: "amber"
3148
- },
3149
3241
  readout: {
3150
3242
  title: {
3151
3243
  visible: true,
@@ -3237,13 +3329,6 @@ var Gaugeit = (() => {
3237
3329
  strokeWidth: 2
3238
3330
  }
3239
3331
  },
3240
- light: {
3241
- visible: false,
3242
- x: 160,
3243
- y: 151,
3244
- radius: 7,
3245
- color: "amber"
3246
- },
3247
3332
  readout: {
3248
3333
  title: { visible: false, x: "auto", y: 140 },
3249
3334
  value: { visible: false, x: 160, y: 220, fontSize: 33 },
@@ -3330,16 +3415,6 @@ var Gaugeit = (() => {
3330
3415
  strokeWidth: 2
3331
3416
  }
3332
3417
  },
3333
- light: {
3334
- visible: false,
3335
- x: 108,
3336
- y: 110,
3337
- radius: 10,
3338
- color: "amber",
3339
- blink: false,
3340
- blinkInterval: 1e3,
3341
- trigger: { mode: "below", source: "target", value: 15, min: 0, max: 15 }
3342
- },
3343
3418
  readout: {
3344
3419
  title: {
3345
3420
  visible: true,
@@ -3870,13 +3945,6 @@ var Gaugeit = (() => {
3870
3945
  strokeWidth: 1.2
3871
3946
  }
3872
3947
  },
3873
- light: {
3874
- visible: false,
3875
- x: 72,
3876
- y: 60,
3877
- radius: 8,
3878
- color: "amber"
3879
- },
3880
3948
  readout: {
3881
3949
  title: {
3882
3950
  visible: true,
@@ -4111,13 +4179,6 @@ var Gaugeit = (() => {
4111
4179
  strokeWidth: 2
4112
4180
  }
4113
4181
  },
4114
- light: {
4115
- visible: false,
4116
- x: 112,
4117
- y: 205,
4118
- radius: 8,
4119
- color: "amber"
4120
- },
4121
4182
  readout: {
4122
4183
  title: {
4123
4184
  visible: true,
@@ -4467,13 +4528,6 @@ var Gaugeit = (() => {
4467
4528
  { min: 20, max: 80, color: "transparent" },
4468
4529
  { min: 80, max: 100, color: "#15803d" }
4469
4530
  ],
4470
- light: {
4471
- visible: false,
4472
- x: 72,
4473
- y: 46,
4474
- radius: 8,
4475
- color: "amber"
4476
- },
4477
4531
  readout: {
4478
4532
  title: {
4479
4533
  visible: true,
@@ -4688,7 +4742,7 @@ var Gaugeit = (() => {
4688
4742
  resolveLightPosition
4689
4743
  });
4690
4744
  var types = builtInTypes;
4691
- var VERSION = "0.1.0";
4745
+ var VERSION = "0.1.1";
4692
4746
  var Gaugeit = Object.freeze({
4693
4747
  VERSION,
4694
4748
  Gauge,