Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions js/ui/form/effect.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
const EFFECTS = [
{ name: 'none', style: 'none', min: 0, max: 100, step: 1, unit: '' },
{ name: 'chrome', style: 'grayscale', min: 0, max: 1, step: 0.1, unit: '' },
{ name: 'sepia', style: 'sepia', min: 0, max: 1, step: 0.1, unit: '' },
{ name: 'marvin', style: 'invert', min: 0, max: 100, step: 1, unit: '%' },
{ name: 'phobos', style: 'blur', min: 0, max: 3, step: 0.1, unit: 'px' },
{ name: 'heat', style: 'brightness', min: 1, max: 3, step: 0.1, unit: '' },
];

const DEFAULT_EFFECT = EFFECTS[0];

const EFFECTS_MAP = Object.fromEntries(
EFFECTS.map((effect) => [effect.name, effect])
);

let chosenEffect = DEFAULT_EFFECT;

const imageElement = document.querySelector('.img-upload__preview img');
const effectsElement = document.querySelector('.effects');
const sliderElement = document.querySelector('.effect-level__slider');
const sliderContainerElement = document.querySelector('.img-upload__effect-level');
const effectLevelElement = document.querySelector('.effect-level__value');

const isDefault = () => chosenEffect.name === 'none';

const showSlider = () => {
sliderContainerElement.classList.remove('hidden');
};

const hideSlider = () => {
sliderContainerElement.classList.add('hidden');
};

const removeEffectClasses = () => {
EFFECTS.forEach((effect) => {
imageElement.classList.remove(`effects__preview--${effect.name}`);
});
};

const applyEffectClass = () => {
removeEffectClasses();
imageElement.classList.add(`effects__preview--${chosenEffect.name}`);
};

const updateSlider = () => {
sliderElement.noUiSlider.updateOptions({
range: {
min: chosenEffect.min,
max: chosenEffect.max,
},
start: chosenEffect.max,
step: chosenEffect.step,
});

if (isDefault()) {
hideSlider();
} else {
showSlider();
}
};

const onEffectsChange = (evt) => {
if (!evt.target.classList.contains('effects__radio')) {
return;
}

chosenEffect = EFFECTS_MAP[evt.target.value];

applyEffectClass();
updateSlider();
};

const onSliderUpdate = () => {
const sliderValue = Number(sliderElement.noUiSlider.get());

imageElement.style.filter = isDefault()
? 'none'
: `${chosenEffect.style}(${sliderValue}${chosenEffect.unit})`;

effectLevelElement.value = sliderValue;
};

const resetEffects = () => {
chosenEffect = DEFAULT_EFFECT;

removeEffectClasses();
imageElement.style.filter = 'none';
effectLevelElement.value = '';

updateSlider();
};

const initEffects = () => {
noUiSlider.create(sliderElement, {
range: {
min: DEFAULT_EFFECT.min,
max: DEFAULT_EFFECT.max,
},
start: DEFAULT_EFFECT.max,
step: DEFAULT_EFFECT.step,
connect: 'lower',
});

hideSlider();
resetEffects();

effectsElement.addEventListener('change', onEffectsChange);
sliderElement.noUiSlider.on('update', onSliderUpdate);
};

export { initEffects, resetEffects };
4 changes: 4 additions & 0 deletions js/ui/form/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { initModal } from './modal.js';
import { initValidation, resetValidation } from './validation.js';
import { initSubmit } from './submit.js';
import { initScale } from './scale.js';
import { initEffects } from './effect.js';

const initForm = () => {
initValidation();
initSubmit();
initScale();
initEffects();

initModal(() => {
resetValidation();
Expand Down
4 changes: 4 additions & 0 deletions js/ui/form/modal.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { isEscapeKey } from '../../utils/common.js';
import { resetScale } from './scale.js';
import { resetEffects } from './effect.js';

const body = document.body;
const form = document.querySelector('.img-upload__form');
Expand All @@ -17,6 +19,8 @@ const showModal = () => {
const hideModal = () => {
form.reset();
fileField.value = '';
resetScale();
resetEffects();

overlay.classList.add('hidden');
body.classList.remove('modal-open');
Expand Down
48 changes: 48 additions & 0 deletions js/ui/form/scale.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const SCALE_STEP = 25;
const MIN_SCALE = 25;
const MAX_SCALE = 100;
const DEFAULT_SCALE = 100;

const modalElement = document.querySelector('.img-upload');
const smallerButtonElement = modalElement.querySelector('.scale__control--smaller');
const biggerButtonElement = modalElement.querySelector('.scale__control--bigger');
const scaleInputElement = modalElement.querySelector('.scale__control--value');
const imageElement = modalElement.querySelector('.img-upload__preview img');

const getScaleValue = () =>
Number(scaleInputElement.value.replace('%', ''));

const scaleImage = (value) => {
imageElement.style.transform = `scale(${value / 100})`;
scaleInputElement.value = `${value}%`;
};

const changeScale = (delta) => {
const currentValue = getScaleValue();
let newValue = currentValue + delta;

if (newValue < MIN_SCALE) {
newValue = MIN_SCALE;
}
if (newValue > MAX_SCALE) {
newValue = MAX_SCALE;
}

scaleImage(newValue);
};

const onSmallerButtonClick = () => changeScale(-SCALE_STEP);
const onBiggerButtonClick = () => changeScale(SCALE_STEP);

const resetScale = () => {
scaleImage(DEFAULT_SCALE);
};

const initScale = () => {
scaleImage(DEFAULT_SCALE);

smallerButtonElement.addEventListener('click', onSmallerButtonClick);
biggerButtonElement.addEventListener('click', onBiggerButtonClick);
};

export { initScale, resetScale };
Loading