@innovastudio/contentbuilder 1.5.62 → 1.5.63

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.
@@ -4645,13 +4645,9 @@ class Util {
4645
4645
  // Hide other pops
4646
4646
  let elms = document.querySelectorAll('.is-pop.active');
4647
4647
  elms.forEach(otherPop => {
4648
+ // do not close parent/caller pop
4648
4649
  let close = true;
4649
- let callerPop;
4650
- if (overlay) {
4651
- // do not close parent/caller pop
4652
- callerPop = btn.closest('.is-pop');
4653
- if (callerPop === otherPop) close = false;
4654
- }
4650
+ if (otherPop.contains(btn)) close = false;
4655
4651
  if (otherPop !== pop && close) {
4656
4652
  otherPop.style.display = '';
4657
4653
  dom.removeClass(otherPop, 'active');
@@ -4677,9 +4673,9 @@ class Util {
4677
4673
  if (!pop.contains(e.target) && !btn.contains(e.target)) {
4678
4674
  // click outside
4679
4675
 
4680
- if (e.target.closest('.is-pop-overlay')) return;
4681
- let overlayExist = document.querySelector('.is-pop-overlay');
4682
- if (overlayExist) return;
4676
+ // if(e.target.closest('.is-pop-overlay')) return;
4677
+ // let overlayExist = document.querySelector('.is-pop-overlay');
4678
+ // if(overlayExist) return;
4683
4679
 
4684
4680
  // hide
4685
4681
  this.hidePop(pop);
@@ -27731,7 +27727,7 @@ function () {
27731
27727
  return EventEmitter;
27732
27728
  }();
27733
27729
 
27734
- var EventEmitter$1$1 = EventEmitter$2;
27730
+ var EventEmitter$1$2 = EventEmitter$2;
27735
27731
 
27736
27732
  /*
27737
27733
  Copyright (c) 2019 Daybrush
@@ -40242,7 +40238,7 @@ var MoveableManager$1 = /*#__PURE__*/function (_super) {
40242
40238
  "mouseEnter": null,
40243
40239
  "mouseLeave": null
40244
40240
  };
40245
- _this._emitter = new EventEmitter$1$1();
40241
+ _this._emitter = new EventEmitter$1$2();
40246
40242
  _this._prevTarget = null;
40247
40243
  _this._prevDragArea = false;
40248
40244
  _this._observer = null;
@@ -42171,7 +42167,7 @@ function __spreadArrays() {
42171
42167
  * Implement EventEmitter on object or component.
42172
42168
  */
42173
42169
 
42174
- var EventEmitter =
42170
+ var EventEmitter$1 =
42175
42171
  /*#__PURE__*/
42176
42172
  function () {
42177
42173
  function EventEmitter() {
@@ -42404,7 +42400,7 @@ function () {
42404
42400
  return EventEmitter;
42405
42401
  }();
42406
42402
 
42407
- var EventEmitter$1 = EventEmitter;
42403
+ var EventEmitter$1$1 = EventEmitter$1;
42408
42404
 
42409
42405
  /**
42410
42406
  * Moveable is Draggable! Resizable! Scalable! Rotatable!
@@ -42518,7 +42514,7 @@ function (_super) {
42518
42514
  });
42519
42515
  })], MoveableManager);
42520
42516
  return MoveableManager;
42521
- }(EventEmitter$1);
42517
+ }(EventEmitter$1$1);
42522
42518
 
42523
42519
  var Moveable$1 =
42524
42520
  /*#__PURE__*/
@@ -63807,6 +63803,418 @@ class RoundedSlider {
63807
63803
  }
63808
63804
  }
63809
63805
 
63806
+ class EventEmitter {
63807
+ constructor() {
63808
+ this.listeners = {};
63809
+ }
63810
+ on(event, listener) {
63811
+ if (!this.listeners[event]) {
63812
+ this.listeners[event] = [];
63813
+ }
63814
+ this.listeners[event].push(listener);
63815
+ }
63816
+ emit(event, ...args) {
63817
+ if (this.listeners[event]) {
63818
+ this.listeners[event].forEach(listener => {
63819
+ listener(...args);
63820
+ });
63821
+ }
63822
+ }
63823
+ }
63824
+
63825
+ /*
63826
+ // Usage example
63827
+
63828
+ const myGradientSlider = document.querySelector('.myslider');
63829
+ const slider = new GradientSlider(myGradientSlider);
63830
+ slider.draw([
63831
+ { color: 'rgba(4, 98, 183, 1)', position: 0 },
63832
+ { color: 'rgba(97, 110, 204, 1)', position: 25 },
63833
+ { color: 'rgba(246, 108, 168, 1)', position: 50 },
63834
+ { color: 'rgba(255, 211, 111, 1)', position: 75 },
63835
+ { color: 'rgba(255, 253, 193, 1)', position: 100 }
63836
+ ]
63837
+ );
63838
+
63839
+ slider.on('slideStart', (sliderPoint) => {
63840
+ console.log('Sliding started', sliderPoint);
63841
+ });
63842
+ slider.on('slideEnd', () => {
63843
+ console.log('Sliding ended');
63844
+ });
63845
+ slider.on('change', (pointsArray) => {
63846
+ console.log('Slider changed', pointsArray);
63847
+ });
63848
+ slider.on('slideChange', (pointsArray) => {
63849
+ console.log('Slider changed', pointsArray);
63850
+ });
63851
+ */
63852
+
63853
+ class GradientSlider extends EventEmitter {
63854
+ constructor(element, settings = {}) {
63855
+ super(); // Call the constructor of EventEmitter first
63856
+
63857
+ const defaults = {
63858
+ label: 'Gradient Slider'
63859
+ };
63860
+ this.opts = Object.assign(this, defaults, settings);
63861
+ this.element = element;
63862
+
63863
+ // Generate a unique ID for this slider instance
63864
+ this.uniqueId = GradientSlider.getUniqueId();
63865
+ this.drag = this.drag.bind(this);
63866
+ this.dragStop = this.dragStop.bind(this);
63867
+ this.addColorOnClick = this.addColorOnClick.bind(this);
63868
+ }
63869
+
63870
+ // Static method to generate a unique ID
63871
+ static getUniqueId() {
63872
+ if (!this.uniqueCounter) {
63873
+ this.uniqueCounter = 0; // Initialize if it doesn't exist
63874
+ }
63875
+
63876
+ this.uniqueCounter++; // Increment the counter for each new instance
63877
+ return `gradientSliderLabel${this.uniqueCounter}`; // Return a unique ID
63878
+ }
63879
+
63880
+ constructGradientString(pointsArray) {
63881
+ const gradientParts = pointsArray.map(color => `${color.color} ${color.position}%`);
63882
+ return `linear-gradient(90deg, ${gradientParts.join(', ')})`;
63883
+ }
63884
+
63885
+ /*
63886
+ pointsArray = [
63887
+ { color: 'rgba(4, 98, 183, 1)', position: 0 },
63888
+ { color: 'rgba(246, 108, 168, 1)', position: 50 },
63889
+ { color: 'rgba(255, 253, 193, 1)', position: 100 }
63890
+ ]
63891
+ */
63892
+ draw(pointsArray) {
63893
+ this.sliderPoints = [];
63894
+ let label = this.element.querySelector('.visually-hidden');
63895
+ if (!label) {
63896
+ label = document.createElement('div');
63897
+ label.className = 'visually-hidden';
63898
+ label.id = this.uniqueId;
63899
+ label.textContent = this.opts.label;
63900
+ this.element.prepend(label); // Add label to the slider element
63901
+ }
63902
+
63903
+ if (!this.sliderContainer) {
63904
+ this.sliderContainer = document.createElement('div');
63905
+ this.sliderContainer.className = 'gradient-slider-container';
63906
+ this.element.insertAdjacentElement('afterend', this.sliderContainer);
63907
+ this.shadowContainer = document.createElement('div');
63908
+ this.shadowContainer.classList.add('gradient-slider-container-shadow');
63909
+ this.sliderContainer.insertAdjacentElement('afterbegin', this.shadowContainer);
63910
+ this.setupAddColorOnClick();
63911
+ } else {
63912
+ this.clearPoints();
63913
+ }
63914
+ pointsArray.forEach(point => {
63915
+ const knob = document.createElement('div');
63916
+ knob.className = 'slider-point';
63917
+ knob.style.left = `${point.position}%`;
63918
+ knob.style.backgroundColor = point.color;
63919
+ this.sliderContainer.insertAdjacentElement('beforeend', knob);
63920
+ this.sliderPoints.push(knob); // this.sliderPoints contains list of knobs
63921
+
63922
+ // Accessibility Enhancements
63923
+ knob.setAttribute('tabindex', '0'); // Make it focusable
63924
+ knob.setAttribute('role', 'slider');
63925
+ knob.setAttribute('aria-valuemin', '0');
63926
+ knob.setAttribute('aria-valuemax', '100');
63927
+ knob.setAttribute('aria-valuenow', point.position);
63928
+ knob.setAttribute('aria-valuetext', `Color: ${point.color}, Position: ${point.position}%`);
63929
+ knob.setAttribute('aria-labelledby', this.uniqueId);
63930
+
63931
+ // Initialize drag functionality
63932
+ knob.addEventListener('mousedown', this.dragStart.bind(this, knob), {
63933
+ passive: false
63934
+ });
63935
+ knob.addEventListener('touchstart', this.dragStart.bind(this, knob), {
63936
+ passive: false
63937
+ });
63938
+
63939
+ // Keyboard interaction
63940
+ knob.addEventListener('keydown', e => this.handleKeydown(e, knob));
63941
+ });
63942
+
63943
+ // Update the slider's gradient background
63944
+ const cssGradient = this.constructGradientString(pointsArray);
63945
+ this.setContainerGradient(cssGradient);
63946
+
63947
+ // show hide container
63948
+ this.showHideContainer();
63949
+ }
63950
+ showHideContainer() {
63951
+ let hide = false;
63952
+ if (this.sliderPoints.length === 2) {
63953
+ let color1 = this.sliderPoints[0].style.backgroundColor;
63954
+ let color2 = this.sliderPoints[1].style.backgroundColor;
63955
+ if (color1 === 'rgba(255, 255, 255, 1)' && color2 === 'rgba(255, 255, 255, 1)') {
63956
+ hide = true;
63957
+ }
63958
+ if (color1 === 'rgb(255, 255, 255)' && color2 === 'rgb(255, 255, 255)') {
63959
+ hide = true;
63960
+ }
63961
+ }
63962
+ if (hide) {
63963
+ this.sliderContainer.style.display = 'none';
63964
+ } else {
63965
+ this.sliderContainer.style.display = '';
63966
+ }
63967
+ }
63968
+ updateColor(color, index) {
63969
+ // update array (this also applies to the knob, because this.sliderPoints contains list of knobs)
63970
+ this.sliderPoints[index].style.backgroundColor = color;
63971
+
63972
+ // show hide container
63973
+ this.showHideContainer();
63974
+ this.update();
63975
+ }
63976
+ removeColor(index) {
63977
+ // remove knob
63978
+ let sliderKnobs = this.sliderContainer.querySelectorAll('.slider-point');
63979
+ let knob = sliderKnobs[index];
63980
+ knob.removeEventListener('mousedown', this.dragStart);
63981
+ knob.removeEventListener('touchstart', this.dragStart);
63982
+ knob.remove();
63983
+
63984
+ // update array
63985
+ this.sliderPoints.splice(index, 1);
63986
+ this.update();
63987
+ }
63988
+ setupAddColorOnClick() {
63989
+ this.sliderContainer.addEventListener('click', this.addColorOnClick);
63990
+ // this.sliderContainer.addEventListener('touchstart', this.addColorOnClick, {passive: true});
63991
+
63992
+ // Indicate that the user can add a knob by changing the cursor
63993
+ this.sliderContainer.style.cursor = 'copy'; // Or use a custom cursor icon that indicates addition
63994
+ }
63995
+
63996
+ interpolateColor(color1) {
63997
+ //, color2, fraction
63998
+ // Iimplement color interpolation logic.
63999
+ // fraction is a value between 0 and 1 indicating the relative position of the new stop.
64000
+ return color1; // for simplicity, just return color1
64001
+ }
64002
+
64003
+ addColorOnClick(e) {
64004
+ /*
64005
+ // Prevent the event if it's a touch event to stop it from triggering click events afterwards
64006
+ e.preventDefault();
64007
+ // Determine whether this is a touch event and extract the appropriate X position
64008
+ let clientX;
64009
+ if (e.touches) {
64010
+ clientX = e.touches[0].clientX; // Use the first touch point
64011
+ } else {
64012
+ clientX = e.clientX; // Use the mouse click position
64013
+ }
64014
+ */
64015
+ let clientX = e.clientX;
64016
+
64017
+ // Ensure the action is triggered only when the container itself is touched, not its children
64018
+ if (!e.target.classList.contains('gradient-slider-container-shadow')) return;
64019
+ const rect = this.sliderContainer.getBoundingClientRect();
64020
+ const clickX = clientX - rect.left; // Click position within the sliderContainer, in pixels
64021
+ const width = rect.width;
64022
+ const positionPercentage = clickX / width * 100;
64023
+
64024
+ // Find the two closest stops surrounding the click position
64025
+ const sortedPoints = this.sliderPoints.map(knob => {
64026
+ return {
64027
+ position: parseFloat(knob.style.left),
64028
+ color: knob.style.backgroundColor
64029
+ };
64030
+ }).sort((a, b) => a.position - b.position);
64031
+
64032
+ // Find the surrounding stops
64033
+ let lowerStop = sortedPoints[0]; // Initialize with the first stop
64034
+ let upperStop = sortedPoints[sortedPoints.length - 1]; // Initialize with the last stop
64035
+ for (let i = 0; i < sortedPoints.length - 1; i++) {
64036
+ if (positionPercentage >= sortedPoints[i].position && positionPercentage <= sortedPoints[i + 1].position) {
64037
+ lowerStop = sortedPoints[i];
64038
+ upperStop = sortedPoints[i + 1];
64039
+ break;
64040
+ }
64041
+ }
64042
+
64043
+ // Calculate the fraction of the position between the lower and upper stops
64044
+ const fraction = (positionPercentage - lowerStop.position) / (upperStop.position - lowerStop.position);
64045
+
64046
+ // Interpolate the color
64047
+ const interpolatedColor = this.interpolateColor(lowerStop.color, upperStop.color, fraction);
64048
+
64049
+ // Now, add the color knob at the calculated position with the interpolated color
64050
+ this.addColor(interpolatedColor, positionPercentage);
64051
+ }
64052
+ addColor(color, position) {
64053
+ position = position - 4; // adjustment
64054
+
64055
+ // First, find the correct position to insert the new knob
64056
+ let insertAt = this.sliderPoints.findIndex(knob => {
64057
+ const knobPosition = parseFloat(knob.style.left);
64058
+ return position < knobPosition;
64059
+ });
64060
+
64061
+ // If no suitable position is found (i.e., we're inserting at the end or the array is empty), adjust insertAt accordingly
64062
+ if (insertAt === -1) insertAt = this.sliderPoints.length;
64063
+
64064
+ // Create and configure the new knob
64065
+ const knob = document.createElement('div');
64066
+ knob.className = 'slider-point';
64067
+ knob.style.left = `${position}%`;
64068
+ knob.style.backgroundColor = color;
64069
+
64070
+ // Accessibility Enhancements
64071
+ knob.setAttribute('tabindex', '0');
64072
+ knob.setAttribute('role', 'slider');
64073
+ knob.setAttribute('aria-valuemin', '0');
64074
+ knob.setAttribute('aria-valuemax', '100');
64075
+ knob.setAttribute('aria-valuenow', position);
64076
+ knob.setAttribute('aria-valuetext', `Color: ${color}, Position: ${position}%`);
64077
+ knob.setAttribute('aria-labelledby', this.uniqueId);
64078
+
64079
+ // Initialize drag functionality
64080
+ knob.addEventListener('mousedown', this.dragStart.bind(this, knob), {
64081
+ passive: false
64082
+ });
64083
+ knob.addEventListener('touchstart', this.dragStart.bind(this, knob), {
64084
+ passive: false
64085
+ });
64086
+ if (insertAt === this.sliderPoints.length) {
64087
+ // If inserting at the end, simply add the knob to the container
64088
+ this.sliderContainer.appendChild(knob);
64089
+ } else {
64090
+ // Otherwise, insert the knob before the knob currently at the insertAt position
64091
+ this.sliderContainer.insertBefore(knob, this.sliderPoints[insertAt]);
64092
+ }
64093
+
64094
+ // Update the internal representation and the displayed gradient
64095
+ this.sliderPoints.splice(insertAt, 0, knob); // Insert the knob into the internal array at the correct position
64096
+
64097
+ this.update(true); // Update the gradient and emit the change event
64098
+ }
64099
+
64100
+ update(triggerAddpoint) {
64101
+ // Generate pointsArray based on the points color & position
64102
+ const pointsArray = this.sliderPoints.map(point => {
64103
+ const position = parseFloat(point.style.left); // Assuming style.left is always in '%'
64104
+ return {
64105
+ color: point.style.backgroundColor,
64106
+ position: position
64107
+ };
64108
+ });
64109
+
64110
+ // Update the slider's gradient background
64111
+ const cssGradient = this.constructGradientString(pointsArray);
64112
+ this.setContainerGradient(cssGradient);
64113
+
64114
+ // Emit a "change" event with the pointsArray as the detail
64115
+ this.emit('change', pointsArray, cssGradient);
64116
+ if (triggerAddpoint) {
64117
+ this.emit('addpoint', pointsArray, cssGradient);
64118
+ }
64119
+ }
64120
+ dragStart(knob, e) {
64121
+ this.knob = knob;
64122
+ e.preventDefault();
64123
+ this.isDragging = true;
64124
+
64125
+ // Get the initial offset by subtracting the slider point's left position from the cursor's X position
64126
+ const startX = e.touches ? e.touches[0].clientX : e.clientX;
64127
+ const pointRect = knob.getBoundingClientRect();
64128
+ this.initialOffsetX = startX - pointRect.left;
64129
+ document.addEventListener('mousemove', this.drag);
64130
+ document.addEventListener('touchmove', this.drag);
64131
+ document.addEventListener('mouseup', this.dragStop);
64132
+ document.addEventListener('touchend', this.dragStop);
64133
+ this.emit('slideStart', knob);
64134
+ }
64135
+ drag(e) {
64136
+ if (!this.isDragging) return;
64137
+ const knob = this.knob;
64138
+
64139
+ // Update knob (left) position
64140
+ let touch = e.touches ? e.touches[0] : e;
64141
+ let rect = this.sliderContainer.getBoundingClientRect();
64142
+ let x = touch.clientX - rect.left - this.initialOffsetX; // Adjust position based on initial offset
64143
+ let percentage = Math.max(0, Math.min(100, x / rect.width * 100));
64144
+ knob.style.left = `${percentage}%`;
64145
+
64146
+ // Updating knob (left) position will also update the this.sliderPoints
64147
+ // console.log(this.sliderPoints[1].style.left); // to test
64148
+
64149
+ // this.update() //The code below is similar to update(), only that it triggers sliderChange
64150
+
64151
+ // Generate pointsArray based on the points color & position
64152
+ const pointsArray = this.sliderPoints.map(point => {
64153
+ const position = parseFloat(point.style.left); // Assuming style.left is always in '%'
64154
+ return {
64155
+ color: point.style.backgroundColor,
64156
+ position: position
64157
+ };
64158
+ });
64159
+
64160
+ // Update the slider's gradient background
64161
+ const cssGradient = this.constructGradientString(pointsArray);
64162
+ this.setContainerGradient(cssGradient);
64163
+
64164
+ // Emit a "slideChange" event with the pointsArray as the detail
64165
+ this.emit('slideChange', pointsArray, cssGradient);
64166
+ }
64167
+ dragStop() {
64168
+ this.isDragging = false;
64169
+ document.removeEventListener('mousemove', this.drag);
64170
+ document.removeEventListener('touchmove', this.drag);
64171
+ document.removeEventListener('mouseup', this.dragStop);
64172
+ document.removeEventListener('touchend', this.dragStop);
64173
+ this.emit('slideEnd');
64174
+ }
64175
+ clearPoints() {
64176
+ // Remove all child slider points from the container
64177
+ const sliderKnobs = this.sliderContainer.querySelectorAll('.slider-point');
64178
+ sliderKnobs.forEach(knob => {
64179
+ knob.removeEventListener('mousedown', this.dragStart);
64180
+ knob.removeEventListener('touchstart', this.dragStart);
64181
+ knob.remove();
64182
+ });
64183
+
64184
+ // update array
64185
+ this.sliderPoints = []; // Clear
64186
+ }
64187
+
64188
+ handleKeydown(e, sliderPoint) {
64189
+ const key = e.key;
64190
+ let newPosition = parseFloat(sliderPoint.style.left);
64191
+ if (key === 'ArrowRight' || key === 'ArrowUp') {
64192
+ newPosition = Math.min(100, newPosition + 1); // Increase position
64193
+ } else if (key === 'ArrowLeft' || key === 'ArrowDown') {
64194
+ newPosition = Math.max(0, newPosition - 1); // Decrease position
64195
+ } else {
64196
+ return; // Ignore other keys
64197
+ }
64198
+
64199
+ sliderPoint.style.left = `${newPosition}%`;
64200
+ sliderPoint.setAttribute('aria-valuenow', newPosition);
64201
+ sliderPoint.setAttribute('aria-valuetext', `Color: ${sliderPoint.style.backgroundColor}, Position: ${newPosition}%`);
64202
+
64203
+ // Update gradient and invoke onChange callback with the new positions
64204
+ this.dragStop(); // Simulate dragStop to update positions and gradient
64205
+ }
64206
+
64207
+ setContainerGradient(cssGradient) {
64208
+ this.shadowContainer.style.backgroundImage = cssGradient;
64209
+ }
64210
+ destroy() {
64211
+ if (this.element.nextElementSibling && this.element.nextElementSibling.classList.contains('gradient-slider-container')) {
64212
+ this.clearPoints();
64213
+ this.element.nextElementSibling.remove();
64214
+ }
64215
+ }
64216
+ }
64217
+
63810
64218
  class GradientPicker {
63811
64219
  constructor(builder) {
63812
64220
  this.builder = builder;
@@ -63829,9 +64237,10 @@ class GradientPicker {
63829
64237
  <div class="label-saved">${this.out('Saved')}:</div>
63830
64238
  <div class="div-saved"></div>
63831
64239
 
63832
- <div class="gradient-preview"></div>
63833
-
63834
64240
  <div class="label-saved">${this.out('Gradient Colors')}:</div>
64241
+
64242
+ <div class="gradient-slider" role="application"></div>
64243
+
63835
64244
  <div class="div-sort"></div>
63836
64245
 
63837
64246
  <div class="div-add">
@@ -63864,20 +64273,30 @@ class GradientPicker {
63864
64273
  }
63865
64274
  init() {
63866
64275
  this.renderSavedGradients();
63867
- const btnAddStop = this.pickGradient.querySelector('.btn-addstop');
63868
- if (btnAddStop) btnAddStop.addEventListener('click', () => {
63869
- this.builder.uo.saveForUndo();
63870
- let lastColor = this.colorsArray[this.colorsArray.length - 1];
63871
- this.colorsArray.push(lastColor);
63872
- this.renderColorStops();
64276
+ const divGradSlider = this.pickGradient.querySelector('.gradient-slider');
64277
+ const gradSlider = new GradientSlider(divGradSlider, {
64278
+ label: this.out('Gradient Slider')
64279
+ });
64280
+ this.gradSlider = gradSlider;
64281
+ gradSlider.on('slideStart', () => {
64282
+ this.builder.uo.saveForUndo(true);
64283
+ });
64284
+ gradSlider.on('slideEnd', () => {
64285
+ if (this.onChange) this.onChange();
64286
+ this.builder.onChange();
64287
+ });
64288
+ gradSlider.on('slideChange', pointsArray => {
64289
+ this.colorsPosArray = pointsArray;
64290
+ this.applyGradient();
64291
+ });
64292
+ gradSlider.on('change', pointsArray => {
64293
+ this.colorsPosArray = pointsArray;
63873
64294
  this.applyGradient();
63874
64295
  if (this.onChange) this.onChange();
63875
64296
  this.builder.onChange();
63876
64297
  });
63877
- const btnSave = this.pickGradient.querySelector('.btn-save');
63878
- if (btnSave) btnSave.addEventListener('click', () => {
63879
- this.saveGradient();
63880
- this.renderSavedGradients();
64298
+ gradSlider.on('addpoint', () => {
64299
+ this.renderColorStops();
63881
64300
  });
63882
64301
  const inpAngle = this.pickGradient.querySelector('.inp-angle');
63883
64302
  this.slider = new RoundedSlider(inpAngle, {
@@ -63892,14 +64311,44 @@ class GradientPicker {
63892
64311
  if (this.onChange) this.onChange();
63893
64312
  this.builder.onChange();
63894
64313
  };
64314
+ const btnAddStop = this.pickGradient.querySelector('.btn-addstop');
64315
+ if (btnAddStop) btnAddStop.addEventListener('click', () => {
64316
+ this.builder.uo.saveForUndo();
64317
+ const lastItem = this.colorsPosArray[this.colorsPosArray.length - 1];
64318
+ lastItem.position = lastItem.position - 15;
64319
+ this.colorsPosArray.push({
64320
+ color: lastItem.color,
64321
+ position: 100
64322
+ });
64323
+ this.renderColorPositions();
64324
+ this.renderColorStops();
64325
+ this.applyGradient();
64326
+ if (this.onChange) this.onChange();
64327
+ this.builder.onChange();
64328
+ });
64329
+ const btnSave = this.pickGradient.querySelector('.btn-save');
64330
+ if (btnSave) btnSave.addEventListener('click', () => {
64331
+ this.saveGradient();
64332
+ this.renderSavedGradients();
64333
+ });
63895
64334
  const btnClear = this.pickGradient.querySelector('.btn-clear');
63896
64335
  if (btnClear) btnClear.addEventListener('click', () => {
63897
64336
  this.builder.uo.saveForUndo();
63898
- this.colorsArray = [];
63899
- this.renderColorStops();
63900
64337
  this.angle = 0;
63901
64338
  this.renderAngle();
63902
- this.applyGradient();
64339
+ this.colorsPosArray = [{
64340
+ color: 'rgba(255, 255, 255, 1)',
64341
+ position: 0
64342
+ }, {
64343
+ color: 'rgba(255, 255, 255, 1)',
64344
+ position: 100
64345
+ }];
64346
+ this.renderColorPositions();
64347
+ this.renderColorStops();
64348
+
64349
+ // this.applyGradient();
64350
+ this.element.style.backgroundImage = '';
64351
+ this.btn.style.backgroundImage = '';
63903
64352
  if (this.onChange) this.onChange();
63904
64353
  this.builder.onChange();
63905
64354
  });
@@ -63911,14 +64360,14 @@ class GradientPicker {
63911
64360
  btn.addEventListener('click', () => {
63912
64361
  this.builder.uo.saveForUndo();
63913
64362
  let cssGradient = btn.getAttribute('data-value');
63914
- this.element.style.backgroundImage = cssGradient;
63915
- this.btn.style.backgroundImage = cssGradient;
63916
- const colorsArray = this.extractColors(cssGradient);
63917
- this.colorsArray = colorsArray;
63918
64363
  const angle = this.extractAngle(cssGradient);
63919
64364
  this.angle = angle;
63920
64365
  this.renderAngle();
64366
+ const colorsPosArray = this.extractColorsPos(cssGradient);
64367
+ this.colorsPosArray = colorsPosArray;
64368
+ this.renderColorPositions();
63921
64369
  this.renderColorStops();
64370
+ this.applyGradient();
63922
64371
  if (this.onChange) this.onChange();
63923
64372
  this.builder.onChange();
63924
64373
  });
@@ -63927,7 +64376,7 @@ class GradientPicker {
63927
64376
  saveGradient() {
63928
64377
  let gradient = {
63929
64378
  angle: this.angle,
63930
- colors: this.colorsArray
64379
+ colors: this.colorsPosArray
63931
64380
  };
63932
64381
  this.savedGrads.push(gradient);
63933
64382
  localStorage.setItem('_savedgrads', JSON.stringify(this.savedGrads));
@@ -63945,11 +64394,11 @@ class GradientPicker {
63945
64394
  if (localStorage.getItem('_customgradcolors') !== null) {
63946
64395
  customgradcolors = JSON.parse(localStorage.getItem('_customgradcolors'));
63947
64396
  customgradcolors.forEach(cssGradient => {
63948
- const colorsArray = this.extractColors(cssGradient);
64397
+ const colorsPosArray = this.extractColorsPos(cssGradient);
63949
64398
  const angle = this.extractAngle(cssGradient);
63950
64399
  let gradient = {
63951
64400
  angle: angle,
63952
- colors: colorsArray
64401
+ colors: colorsPosArray
63953
64402
  };
63954
64403
  oldGrads.push(gradient);
63955
64404
  });
@@ -63963,16 +64412,16 @@ class GradientPicker {
63963
64412
  const labelSaved = this.pickGradient.querySelector('.label-saved');
63964
64413
  let html = '';
63965
64414
  savedGrads.forEach((gradient, index) => {
63966
- let deg = gradient.angle;
63967
- let colorsArray = gradient.colors;
63968
- let s = this.convertColorsToGradient(colorsArray, deg);
64415
+ let angle = gradient.angle;
64416
+ let colorsPosArray = gradient.colors;
64417
+ let cssGradient = this.constructGradientString(colorsPosArray, angle); // set the angle
63969
64418
  html += `
63970
64419
  <div>
63971
64420
  <button
63972
64421
  data-index="${index}"
63973
64422
  title="${this.out('Select')}"
63974
- class="btn-graditem" data-value="${s}"
63975
- style="background-image:${s}"></button>
64423
+ class="btn-graditem" data-value="${cssGradient}"
64424
+ style="background-image:${cssGradient}"></button>
63976
64425
 
63977
64426
  <button title="${this.out('Remove')}" class="btn-remove">
63978
64427
  <svg class="is-icon-flex"><use xlink:href="#icon-minus"></use></svg>
@@ -63993,14 +64442,14 @@ class GradientPicker {
63993
64442
  btn.addEventListener('click', () => {
63994
64443
  this.builder.uo.saveForUndo();
63995
64444
  let cssGradient = btn.getAttribute('data-value');
63996
- this.element.style.backgroundImage = cssGradient;
63997
- this.btn.style.backgroundImage = cssGradient;
63998
- const colorsArray = this.extractColors(cssGradient);
63999
- this.colorsArray = colorsArray;
64000
64445
  const angle = this.extractAngle(cssGradient);
64001
64446
  this.angle = angle;
64002
64447
  this.renderAngle();
64448
+ const colorsPosArray = this.extractColorsPos(cssGradient);
64449
+ this.colorsPosArray = colorsPosArray;
64450
+ this.renderColorPositions();
64003
64451
  this.renderColorStops();
64452
+ this.applyGradient();
64004
64453
  if (this.onChange) this.onChange();
64005
64454
  this.builder.onChange();
64006
64455
  });
@@ -64024,104 +64473,42 @@ class GradientPicker {
64024
64473
  });
64025
64474
  });
64026
64475
  }
64027
- removeItemByIndex(arr, index) {
64028
- if (index > -1 && index < arr.length) {
64029
- arr.splice(index, 1);
64030
- }
64031
- return arr;
64032
- }
64033
- extractColors(gradientString) {
64034
- // Regular expression to match rgb(a) colors and hex colors (with optional alpha)
64035
- const colorRegex = /rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(,\s*\d*\.?\d+\s*)?\)|#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?/g;
64036
- // Extract all color occurrences
64037
- const colors = gradientString.match(colorRegex);
64038
- return colors || [];
64039
- }
64040
- extractAngle(gradientString) {
64041
- const anglePattern = /linear-gradient\((\d+)deg,/;
64042
- const match = anglePattern.exec(gradientString);
64043
- if (match && match[1]) {
64044
- return parseInt(match[1], 10);
64045
- } else {
64046
- return 0;
64047
- }
64048
- }
64049
- updateColorsArray() {
64050
- let arr = [];
64051
- const divSort = this.pickGradient.querySelector('.div-sort');
64052
- divSort.querySelectorAll('button[data-color]').forEach(btn => {
64053
- let s = btn.getAttribute('data-color');
64054
- arr.push(s);
64055
- });
64056
- this.colorsArray = arr;
64057
- }
64058
- allowRemoveStop() {
64059
- const divSort = this.pickGradient.querySelector('.div-sort');
64060
- const btns = divSort.querySelectorAll('button[data-color]');
64061
- if (btns.length === 2) {
64062
- return false;
64063
- } else {
64064
- return true;
64065
- }
64066
- }
64067
- convertColorsToGradient(colorsArray, deg = 0) {
64068
- let gradientString = `linear-gradient(${deg}deg, `;
64069
- colorsArray.forEach((color, index) => {
64070
- gradientString += color;
64071
- if (index < colorsArray.length - 1) {
64072
- gradientString += ', ';
64073
- }
64074
- });
64075
- gradientString += ')';
64076
- return gradientString;
64077
- }
64078
64476
  applyGradient() {
64079
64477
  let cssGradient;
64080
- if (this.colorsArray.length === 0) {
64478
+ if (this.colorsPosArray === 0) {
64081
64479
  cssGradient = '';
64082
64480
  } else {
64083
- cssGradient = this.convertColorsToGradient(this.colorsArray, this.angle);
64481
+ cssGradient = this.constructGradientString(this.colorsPosArray);
64084
64482
  }
64483
+
64484
+ // apply to element
64085
64485
  this.element.style.backgroundImage = cssGradient;
64086
64486
  this.btn.style.backgroundImage = cssGradient;
64087
- const divPreview = this.pickGradient.querySelector('.gradient-preview');
64088
- divPreview.style.backgroundImage = cssGradient;
64089
64487
  }
64090
- areArraysIdentical(arr1, arr2) {
64091
- if (arr1.length !== arr2.length) {
64092
- return false; // Arrays of different lengths cannot be identical
64093
- }
64094
-
64095
- for (let i = 0; i < arr1.length; i++) {
64096
- if (arr1[i] !== arr2[i]) {
64097
- return false; // Found elements that are not the same
64098
- }
64099
- }
64100
-
64101
- return true; // All elements are the same and in the same order
64102
- }
64103
-
64104
64488
  renderColorStops() {
64105
- let colorsArray = this.colorsArray;
64106
- if (colorsArray.length === 0) {
64107
- colorsArray = ['rgba(255, 255, 255, 1)', 'rgba(255, 255, 255, 1)'];
64489
+ if (this.colorsPosArray.length === 0) {
64490
+ this.colorsPosArray = [{
64491
+ color: 'rgba(255, 255, 255, 1)',
64492
+ position: 0
64493
+ }, {
64494
+ color: 'rgba(255, 255, 255, 1)',
64495
+ position: 100
64496
+ }];
64108
64497
  }
64109
64498
  let htmlStop = '';
64110
- let n = 0;
64111
- colorsArray.forEach(color => {
64499
+ this.colorsPosArray.forEach((item, index) => {
64112
64500
  htmlStop += `<div>
64113
- <button data-color="${color}"
64114
- data-index="${n}"
64501
+ <button data-color="${item.color}"
64502
+ data-index="${index}"
64115
64503
  title="${this.out('Select Color')}"
64116
64504
  class="btn-colorstop is-btn-color"
64117
- data-value="${color}"
64118
- style="background-color:${color}"></button>
64505
+ data-value="${item.color}"
64506
+ style="background-color:${item.color}"></button>
64119
64507
 
64120
64508
  <button title="${this.out('Remove')}" class="btn-remove">
64121
64509
  <svg class="is-icon-flex"><use xlink:href="#icon-minus"></use></svg>
64122
64510
  </button>
64123
64511
  </div>`;
64124
- n++;
64125
64512
  });
64126
64513
  const divSort = this.pickGradient.querySelector('.div-sort');
64127
64514
  divSort.innerHTML = htmlStop;
@@ -64130,25 +64517,35 @@ class GradientPicker {
64130
64517
  dragClass: 'hide-drag-class',
64131
64518
  onStart: () => {},
64132
64519
  onSort: () => {
64133
- this.updateColorsArray();
64520
+ // TODO
64521
+
64522
+ const btnPicks = this.pickGradient.querySelectorAll('.btn-colorstop');
64523
+ let colors = [];
64524
+ btnPicks.forEach(btn => {
64525
+ let color = btn.style.backgroundColor;
64526
+ colors.push(color);
64527
+ });
64528
+ this.colorsPosArray.map((item, index) => {
64529
+ item.color = colors[index];
64530
+ });
64531
+ this.gradSlider.draw(this.colorsPosArray);
64532
+ this.renderColorStops();
64134
64533
  this.applyGradient();
64534
+ if (this.onChange) this.onChange();
64535
+ this.builder.onChange();
64135
64536
  }
64136
64537
  });
64137
64538
  const colorPicker = this.builder.colorPicker;
64138
64539
  const btnPicks = this.pickGradient.querySelectorAll('.btn-colorstop');
64139
- btnPicks.forEach(btn => {
64540
+ btnPicks.forEach((btn, index) => {
64140
64541
  btn.addEventListener('click', () => {
64141
64542
  this.builder.uo.saveForUndo(true);
64142
64543
  colorPicker.open(color => {
64143
64544
  if (color === '') {
64144
64545
  const allow = this.allowRemoveStop();
64145
64546
  if (allow) {
64146
- // clear
64147
- btn.parentNode.remove();
64148
- this.updateColorsArray();
64149
- this.applyGradient();
64150
- if (this.onChange) this.onChange();
64151
- this.builder.onChange();
64547
+ // remove
64548
+ btn.parentNode.querySelector('.btn-remove').click();
64152
64549
  this.builder.util.hidePopOverlay(); // if pop is opened using overlay, to programmatically close, use this
64153
64550
  return;
64154
64551
  }
@@ -64157,14 +64554,7 @@ class GradientPicker {
64157
64554
 
64158
64555
  btn.setAttribute('data-color', color);
64159
64556
  btn.style.backgroundColor = color;
64160
- this.updateColorsArray();
64161
- if (this.areArraysIdentical(this.colorsArray, ['rgba(255, 255, 255, 1)', 'rgba(255, 255, 255, 1)'])) {
64162
- console.log('Initial, no gradient');
64163
- return;
64164
- }
64165
- this.applyGradient();
64166
- if (this.onChange) this.onChange();
64167
- this.builder.onChange();
64557
+ this.gradSlider.updateColor(color, index); // triggers gradSlider.on('change')
64168
64558
  }, btn.style.backgroundColor, () => {
64169
64559
  btn.removeAttribute('data-focus');
64170
64560
  btn.focus();
@@ -64174,28 +64564,25 @@ class GradientPicker {
64174
64564
  });
64175
64565
  });
64176
64566
  const btnRemove = divSort.querySelectorAll('.btn-remove');
64177
- btnRemove.forEach(btn => {
64567
+ btnRemove.forEach((btn, index) => {
64178
64568
  btn.addEventListener('click', e => {
64179
64569
  this.builder.uo.saveForUndo();
64180
64570
  const allow = this.allowRemoveStop();
64181
64571
  if (allow) {
64182
64572
  btn.parentNode.remove();
64183
- } else {
64184
- let color = 'rgba(255, 255, 255, 1)'; // gradient stop requires value
64573
+ this.colorsPosArray.splice(index, 1);
64574
+ this.renderColorStops(); // a must
64185
64575
 
64186
- const btnColor = btn.parentNode.querySelector('.btn-colorstop');
64187
- btnColor.setAttribute('data-color', color);
64188
- btnColor.style.backgroundColor = color;
64576
+ this.gradSlider.removeColor(index);
64189
64577
  }
64190
- this.updateColorsArray();
64191
- this.applyGradient();
64192
- if (this.onChange) this.onChange();
64193
- this.builder.onChange();
64194
64578
  e.preventDefault();
64195
64579
  e.stopImmediatePropagation();
64196
64580
  });
64197
64581
  });
64198
64582
  }
64583
+ renderColorPositions() {
64584
+ this.gradSlider.draw(this.colorsPosArray);
64585
+ }
64199
64586
  renderAngle() {
64200
64587
  const inpAngle = this.pickGradient.querySelector('.inp-angle');
64201
64588
  inpAngle.value = this.angle;
@@ -64302,16 +64689,117 @@ class GradientPicker {
64302
64689
  // this.onFinish = onFinish; // used in showPop below
64303
64690
 
64304
64691
  let cssGradient = elm.style.backgroundImage;
64305
- const colorsArray = this.extractColors(cssGradient);
64306
- this.colorsArray = colorsArray;
64307
- const angle = this.extractAngle(cssGradient);
64308
- this.angle = angle;
64309
- this.renderAngle();
64310
- this.renderColorStops();
64692
+ if (!cssGradient) {
64693
+ this.angle = 0;
64694
+ this.renderAngle();
64695
+ this.colorsPosArray = [{
64696
+ color: 'rgba(255, 255, 255, 1)',
64697
+ position: 0
64698
+ }, {
64699
+ color: 'rgba(255, 255, 255, 1)',
64700
+ position: 100
64701
+ }];
64702
+ this.renderColorPositions();
64703
+ this.renderColorStops();
64704
+ } else {
64705
+ const angle = this.extractAngle(cssGradient);
64706
+ this.angle = angle;
64707
+ this.renderAngle();
64708
+ const colorsPosArray = this.extractColorsPos(cssGradient);
64709
+ this.colorsPosArray = colorsPosArray;
64710
+ this.renderColorPositions();
64711
+ this.renderColorStops();
64712
+ }
64311
64713
  setTimeout(() => {
64312
64714
  this.slider.create();
64313
64715
  }, 0);
64314
64716
  }
64717
+ extractColorsPos(gradientString) {
64718
+ // Regular expression to match rgb(a) colors and hex colors (with optional alpha) and their positions
64719
+ const colorPositionRegex = /((rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(,\s*\d*\.?\d+\s*)?\)|#[0-9a-fA-F]{6}([0-9a-fA-F]{2})?))(?:\s+(\d+)%\s*)?/g;
64720
+ const matches = [...gradientString.matchAll(colorPositionRegex)];
64721
+ let colorsWithPositions = matches.map(match => ({
64722
+ color: match[1],
64723
+ // The color value
64724
+ position: match[5] ? parseInt(match[5], 10) : undefined // The position, if present
64725
+ }));
64726
+
64727
+ // Additional operation to correctly parse positions
64728
+ const positionMatches = [...gradientString.matchAll(/\d+\.?\d*%/g)].map(match => parseFloat(match[0]));
64729
+ positionMatches.forEach((position, index) => {
64730
+ if (colorsWithPositions[index]) {
64731
+ colorsWithPositions[index].position = position;
64732
+ }
64733
+ });
64734
+
64735
+ // For gradients without explicit positions, we'll distribute positions evenly
64736
+ if (colorsWithPositions.some(c => c.position === undefined)) {
64737
+ const step = 100 / (colorsWithPositions.length - 1);
64738
+ colorsWithPositions.forEach((c, i) => c.position = i * step);
64739
+ }
64740
+ return colorsWithPositions;
64741
+ }
64742
+ extractAngle(gradientString) {
64743
+ const anglePattern = /linear-gradient\((\d+)deg,/;
64744
+ const match = anglePattern.exec(gradientString);
64745
+ if (match && match[1]) {
64746
+ return parseInt(match[1], 10);
64747
+ } else {
64748
+ return 0;
64749
+ }
64750
+ }
64751
+
64752
+ // Utils
64753
+
64754
+ removeItemByIndex(arr, index) {
64755
+ if (index > -1 && index < arr.length) {
64756
+ arr.splice(index, 1);
64757
+ }
64758
+ return arr;
64759
+ }
64760
+ allowRemoveStop() {
64761
+ const divSort = this.pickGradient.querySelector('.div-sort');
64762
+ const btns = divSort.querySelectorAll('button[data-color]');
64763
+ if (btns.length === 2) {
64764
+ return false;
64765
+ } else {
64766
+ return true;
64767
+ }
64768
+ }
64769
+ convertColorsToGradient(colorsArray, deg = 0) {
64770
+ let gradientString = `linear-gradient(${deg}deg, `;
64771
+ colorsArray.forEach((color, index) => {
64772
+ gradientString += color;
64773
+ if (index < colorsArray.length - 1) {
64774
+ gradientString += ', ';
64775
+ }
64776
+ });
64777
+ gradientString += ')';
64778
+ return gradientString;
64779
+ }
64780
+ constructGradientString(points, angle) {
64781
+ const gradientParts = points.map(color => `${color.color} ${color.position}%`);
64782
+ if (angle) {
64783
+ return `linear-gradient(${angle}deg, ${gradientParts.join(', ')})`;
64784
+ } else {
64785
+ return `linear-gradient(${this.angle}deg, ${gradientParts.join(', ')})`;
64786
+ }
64787
+ }
64788
+ areArraysIdentical(arr1, arr2) {
64789
+ if (arr1.length !== arr2.length) {
64790
+ return false; // Arrays of different lengths cannot be identical
64791
+ }
64792
+
64793
+ for (let i = 0; i < arr1.length; i++) {
64794
+ if (arr1[i] !== arr2[i]) {
64795
+ return false; // Found elements that are not the same
64796
+ }
64797
+ }
64798
+
64799
+ return true; // All elements are the same and in the same order
64800
+ }
64801
+
64802
+ // Pop stuff
64315
64803
  getElementPosition(element) {
64316
64804
  const top = element.getBoundingClientRect().top;
64317
64805
  const left = element.getBoundingClientRect().left;
@@ -90971,7 +91459,7 @@ class ContentBuilder {
90971
91459
  /* If not empty, applying font size will apply class: size-12, size-14, and so on. All responsive, defined in content.css */
90972
91460
  gradientColors: [
90973
91461
  // 'linear-gradient(234deg, rgba(255, 253, 185, 1), rgb(255, 208, 100), rgb(239, 98, 159), rgb(73, 88, 195), rgba(2, 20, 145, 1))',
90974
- 'linear-gradient(234deg, rgba(255, 253, 193, 1), rgba(255, 211, 111, 1), rgba(246, 108, 168, 1), rgba(97, 110, 204, 1), rgba(4, 98, 183, 1))', 'linear-gradient(15deg, rgba(222, 90, 69, 1), rgba(255, 118, 96, 1), rgba(249, 214, 137, 1), rgba(255, 242, 172, 1))', 'linear-gradient(357deg, rgba(68, 85, 204, 1), rgba(4, 166, 240, 1), rgba(51, 241, 255, 1))', 'linear-gradient(26deg, rgba(41, 145, 255, 1), rgba(49, 103, 240, 1), rgba(67, 107, 208, 1), rgba(149, 115, 255, 1), rgba(159, 159, 255, 1))', 'linear-gradient(0deg, rgba(198, 233, 155, 1), rgba(97, 221, 180, 1), rgba(244, 255, 190, 1))', 'linear-gradient(342deg, rgb(189, 156, 219), rgb(163, 172, 240), rgba(154, 203, 253, 1))', 'linear-gradient(45deg, rgb(255, 225, 172), rgb(253, 194, 141), rgba(246, 150, 183, 1), rgba(221, 140, 207, 1))', 'linear-gradient(0deg, rgba(157, 172, 246, 1), rgba(129, 205, 255, 1), rgba(202, 255, 207, 1))'],
91462
+ 'linear-gradient(32deg, rgb(4, 98, 183) 0%, rgb(97, 110, 204) 23.5075%, rgb(246, 108, 168) 50%, rgb(255, 211, 111) 75%, rgb(255, 253, 193) 100%)', 'linear-gradient(15deg, rgba(222, 90, 69, 1), rgba(255, 118, 96, 1), rgba(249, 214, 137, 1), rgba(255, 242, 172, 1))', 'linear-gradient(357deg, rgba(68, 85, 204, 1), rgba(4, 166, 240, 1), rgba(51, 241, 255, 1))', 'linear-gradient(26deg, rgba(41, 145, 255, 1), rgba(49, 103, 240, 1), rgba(67, 107, 208, 1), rgba(149, 115, 255, 1), rgba(159, 159, 255, 1))', 'linear-gradient(0deg, rgba(198, 233, 155, 1), rgba(97, 221, 180, 1), rgba(244, 255, 190, 1))', 'linear-gradient(342deg, rgb(189, 156, 219), rgb(163, 172, 240), rgba(154, 203, 253, 1))', 'linear-gradient(45deg, rgb(255, 225, 172), rgb(253, 194, 141), rgba(246, 150, 183, 1), rgba(221, 140, 207, 1))', 'linear-gradient(0deg, rgba(157, 172, 246, 1), rgba(129, 205, 255, 1), rgba(202, 255, 207, 1))'],
90975
91463
  elementEditor: true,
90976
91464
  customval: '',
90977
91465
  moduleConfig: [],
@@ -92867,7 +93355,7 @@ Add an image for each feature.`, 'Create a new content showcasing a photo galler
92867
93355
  dropdown.style.display = 'none';
92868
93356
  });
92869
93357
  }
92870
- const clrPicker = document.querySelector('.pop-picker.active');
93358
+ const clrPicker = document.querySelector('.pop-picker.active') || document.querySelector('.pickgradientcolor.active');
92871
93359
  // if(clrPicker) return;
92872
93360
 
92873
93361
  // Image Resizer