Skip to content

Commit

Permalink
fix: slider works properly when the size changed (#68)
Browse files Browse the repository at this point in the history
* fix: slider works properly when the size changed

* test: fix tests for changes

* chore: apply code reviews

chore: change constants to variables
chore: set sliders maximum pos when drag starts
  • Loading branch information
jajugoguma authored Jun 14, 2022
1 parent d75c1db commit 263cbb2
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 18 deletions.
65 changes: 47 additions & 18 deletions src/js/slider.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ var tmpl = require('../template/slider');

// Limitation position of point element inside of colorslider and hue bar
// Minimum value can to be negative because that using color point of handle element is center point. not left, top point.
var COLORSLIDER_POS_LIMIT_RANGE = [-7, 112];
var HUEBAR_POS_LIMIT_RANGE = [-3, 115];
var DEFAULT_COLORSLIDER_POS_LIMIT_MIN = -7;
var DEFAULT_COLORSLIDER_POS_LIMIT_MAX = 112;
var DEFAULT_HUEBAR_POS_LIMIT_MIN = -3;
var DEFAULT_HUEBAR_POS_LIMIT_MAX = 115;
var HUE_WHEEL_MAX = 359.99;

/**
Expand Down Expand Up @@ -88,6 +90,13 @@ function Slider(options, container) {
container
);

this.colorSliderPosLimitRange = [
DEFAULT_COLORSLIDER_POS_LIMIT_MIN,
DEFAULT_COLORSLIDER_POS_LIMIT_MAX
];

this.huebarPosLimitRange = [DEFAULT_HUEBAR_POS_LIMIT_MIN, DEFAULT_HUEBAR_POS_LIMIT_MAX];

// bind drag events
this.drag.on(
{
Expand Down Expand Up @@ -149,6 +158,8 @@ Slider.prototype.render = function(colorStr) {

this.container.innerHTML = html;

this.sliderSvgElement = container.querySelector('.' + options.cssPrefix + 'svg-slider');
this.huebarSvgElement = container.querySelector('.' + options.cssPrefix + 'svg-huebar');
this.sliderHandleElement = container.querySelector('.' + options.cssPrefix + 'slider-handle');
this.huebarHandleElement = container.querySelector('.' + options.cssPrefix + 'huebar-handle');
this.baseColorElement = container.querySelector('.' + options.cssPrefix + 'slider-basecolor');
Expand All @@ -160,6 +171,14 @@ Slider.prototype.render = function(colorStr) {
this.moveSaturationAndValue(hsv[1], hsv[2], true);
};

Slider.prototype._setColorSliderPosMax = function() {
var sliderRects = this.sliderSvgElement.getClientRects()[0];

if (sliderRects) {
this.colorSliderPosLimitRange[1] = sliderRects.height - 10;
}
};

/**
* Move colorslider by newLeft(X), newTop(Y) value
* @private
Expand All @@ -172,10 +191,10 @@ Slider.prototype._moveColorSliderHandle = function(newLeft, newTop, silent) {
var handleColor;

// Check position limitation.
newTop = Math.max(COLORSLIDER_POS_LIMIT_RANGE[0], newTop);
newTop = Math.min(COLORSLIDER_POS_LIMIT_RANGE[1], newTop);
newLeft = Math.max(COLORSLIDER_POS_LIMIT_RANGE[0], newLeft);
newLeft = Math.min(COLORSLIDER_POS_LIMIT_RANGE[1], newLeft);
newTop = Math.max(this.colorSliderPosLimitRange[0], newTop);
newTop = Math.min(this.colorSliderPosLimitRange[1], newTop);
newLeft = Math.max(this.colorSliderPosLimitRange[0], newLeft);
newLeft = Math.min(this.colorSliderPosLimitRange[1], newLeft);

svgvml.setTranslateXY(handle, newLeft, newTop);

Expand Down Expand Up @@ -203,8 +222,8 @@ Slider.prototype.moveSaturationAndValue = function(saturation, value, silent) {
saturation = saturation || 0;
value = value || 0;

absMin = Math.abs(COLORSLIDER_POS_LIMIT_RANGE[0]);
maxValue = COLORSLIDER_POS_LIMIT_RANGE[1];
absMin = Math.abs(this.colorSliderPosLimitRange[0]);
maxValue = this.colorSliderPosLimitRange[1];

// subtract absMin value because current color position is not left, top of handle element.
// The saturation. from left 0 to right 100
Expand All @@ -224,7 +243,7 @@ Slider.prototype.moveSaturationAndValue = function(saturation, value, silent) {
* @param {number} y - the pixel value to move handle
*/
Slider.prototype._moveColorSliderByPosition = function(x, y) {
var offset = COLORSLIDER_POS_LIMIT_RANGE[0];
var offset = this.colorSliderPosLimitRange[0];
this._moveColorSliderHandle(x + offset, y + offset);
};

Expand All @@ -233,8 +252,8 @@ Slider.prototype._moveColorSliderByPosition = function(x, y) {
* @returns {number[]} saturation and value
*/
Slider.prototype.getSaturationAndValue = function() {
var absMin = Math.abs(COLORSLIDER_POS_LIMIT_RANGE[0]);
var maxValue = absMin + COLORSLIDER_POS_LIMIT_RANGE[1];
var absMin = Math.abs(this.colorSliderPosLimitRange[0]);
var maxValue = absMin + this.colorSliderPosLimitRange[1];
var position = svgvml.getTranslateXY(this.sliderHandleElement);
var saturation, value;

Expand All @@ -245,6 +264,14 @@ Slider.prototype.getSaturationAndValue = function() {
return [saturation, value];
};

Slider.prototype._setHueBarPosMax = function() {
var huebarRects = this.huebarSvgElement.getClientRects()[0];

if (huebarRects) {
this.huebarPosLimitRange[1] = huebarRects.height - 7;
}
};

/**
* Move hue handle supplied pixel value
* @private
Expand All @@ -256,8 +283,8 @@ Slider.prototype._moveHueHandle = function(newTop, silent) {
var baseColorElement = this.baseColorElement;
var newGradientColor, hexStr;

newTop = Math.max(HUEBAR_POS_LIMIT_RANGE[0], newTop);
newTop = Math.min(HUEBAR_POS_LIMIT_RANGE[1], newTop);
newTop = Math.max(this.huebarPosLimitRange[0], newTop);
newTop = Math.min(this.huebarPosLimitRange[1], newTop);

svgvml.setTranslateY(hueHandleElement, newTop);

Expand All @@ -282,8 +309,8 @@ Slider.prototype.moveHue = function(degree, silent) {
var newTop = 0;
var absMin, maxValue;

absMin = Math.abs(HUEBAR_POS_LIMIT_RANGE[0]);
maxValue = absMin + HUEBAR_POS_LIMIT_RANGE[1];
absMin = Math.abs(this.huebarPosLimitRange[0]);
maxValue = absMin + this.huebarPosLimitRange[1];

degree = degree || 0;
newTop = (maxValue * degree) / HUE_WHEEL_MAX - absMin;
Expand All @@ -297,7 +324,7 @@ Slider.prototype.moveHue = function(degree, silent) {
* @param {number} y - pixel value to move hue handle
*/
Slider.prototype._moveHueByPosition = function(y) {
var offset = HUEBAR_POS_LIMIT_RANGE[0];
var offset = this.huebarPosLimitRange[0];

this._moveHueHandle(y + offset);
};
Expand All @@ -311,8 +338,8 @@ Slider.prototype.getHue = function() {
var position = svgvml.getTranslateXY(handle);
var absMin, maxValue;

absMin = Math.abs(HUEBAR_POS_LIMIT_RANGE[0]);
maxValue = absMin + HUEBAR_POS_LIMIT_RANGE[1];
absMin = Math.abs(this.huebarPosLimitRange[0]);
maxValue = absMin + this.huebarPosLimitRange[1];

// maxValue : 359.99 = pos.y : x
return ((position[0] + absMin) * HUE_WHEEL_MAX) / maxValue;
Expand Down Expand Up @@ -381,6 +408,8 @@ Slider.prototype._onClick = function(clickEvent) {
* @param {object} dragStartEvent - dragStart event data from Drag#dragStart
*/
Slider.prototype._onDragStart = function(dragStartEvent) {
this._setColorSliderPosMax();
this._setHueBarPosMax();
this._prepareColorSliderForMouseEvent(dragStartEvent);
};

Expand Down
12 changes: 12 additions & 0 deletions test/slider.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,25 @@ describe('Slider', function() {
var colorslider = { name: 'colorslider' };
var huehandle = { name: 'huehandle' };
var gradient = { name: 'gradient' };
var sliderSvg = {
getClientRects: function() {
return { height: 122 };
}
};
var huebarSvg = {
getClientRects: function() {
return { height: 122 };
}
};

beforeEach(function() {
var el = document.createElement('div');
inst = new Slider({}, el);
inst.sliderHandleElement = colorslider;
inst.huebarHandleElement = huehandle;
inst.baseColorElement = gradient;
inst.sliderSvgElement = sliderSvg;
inst.huebarSvgElement = huebarSvg;

svgvml.setTranslateXY = jest.fn();
svgvml.setStrokeColor = jest.fn();
Expand Down

0 comments on commit 263cbb2

Please sign in to comment.