@@ -4,13 +4,55 @@ const MAX_HASHTAGS = 5;
44const VALID_SYMBOLS = / ^ # [ a - z а - я ё 0 - 9 ] { 1 , 19 } $ / i;
55const COMMENT_LENGTH = 140 ;
66
7+ const SCALE_STEP = 25 ;
8+ const MIN_SCALE = 25 ;
9+ const MAX_SCALE = 100 ;
10+ const DEFAULT_SCALE = 100 ;
11+
12+ const EFFECTS = {
13+ none : {
14+ range : { min : 0 , max : 100 } ,
15+ start : 100 , step : 1 , unit : '' , filter : 'none'
16+ } ,
17+ chrome : {
18+ range : { min : 0 , max : 1 } ,
19+ start : 1 , step : 0.1 , unit : '' , filter : 'grayscale'
20+ } ,
21+ sepia : {
22+ range : { min : 0 , max : 1 } ,
23+ start : 1 , step : 0.1 , unit : '' , filter : 'sepia'
24+ } ,
25+ marvin : {
26+ range : { min : 0 , max : 100 } ,
27+ start : 100 , step : 1 , unit : '%' , filter : 'invert'
28+ } ,
29+ phobos : {
30+ range : { min : 0 , max : 3 } ,
31+ start : 3 , step : 0.1 , unit : 'px' , filter : 'blur'
32+ } ,
33+ heat : {
34+ range : { min : 1 , max : 3 } , start : 3 , step : 0.1 , unit : '' , filter : 'brightness'
35+ } ,
36+ } ;
37+
738const uploadForm = document . querySelector ( '.img-upload__form' ) ;
839const fileInput = uploadForm . querySelector ( '.img-upload__input' ) ;
940const overlay = uploadForm . querySelector ( '.img-upload__overlay' ) ;
1041const closeButton = uploadForm . querySelector ( '.img-upload__cancel' ) ;
1142const hashtagInput = uploadForm . querySelector ( '.text__hashtags' ) ;
1243const commentInput = uploadForm . querySelector ( '.text__description' ) ;
1344
45+ const scaleControlSmaller = document . querySelector ( '.scale__control--smaller' ) ;
46+ const scaleControlBigger = document . querySelector ( '.scale__control--bigger' ) ;
47+ const scaleControlValue = document . querySelector ( '.scale__control--value' ) ;
48+ const imgPreview = document . querySelector ( '.img-upload__preview img' ) ;
49+ let currentScale = DEFAULT_SCALE ;
50+
51+ const sliderContainer = document . querySelector ( '.img-upload__effect-level' ) ;
52+ const sliderElement = document . querySelector ( '.effect-level__slider' ) ;
53+ const effectValueInput = document . querySelector ( '.effect-level__value' ) ;
54+ const effectsList = document . querySelector ( '.effects__list' ) ;
55+
1456// Инициализация Pristine
1557const pristine = new Pristine ( uploadForm , {
1658 classTo : 'img-upload__field-wrapper' ,
@@ -58,7 +100,7 @@ const validateHashtags = (value) => {
58100pristine . addValidator ( hashtagInput , validateHashtags , 'Некорректные хэштеги (макс 5, без повторов, начинаются с #)' ) ;
59101
60102// Валидация комментария
61- pristine . addValidator ( commentInput , ( val ) => val . length <= 140 , 'Максимум 140 символов' ) ;
103+ pristine . addValidator ( commentInput , ( val ) => val . length <= COMMENT_LENGTH , 'Максимум COMMENT_LENGTH символов' ) ;
62104
63105// Отправка формы
64106uploadForm . addEventListener ( 'submit' , ( evt ) => {
@@ -67,3 +109,58 @@ uploadForm.addEventListener('submit', (evt) => {
67109 evt . preventDefault ( ) ;
68110 }
69111} ) ;
112+
113+ // Управление масштабом
114+ const setScale = ( value ) => {
115+ currentScale = value ;
116+ scaleControlValue . value = `${ value } %` ;
117+ imgPreview . style . transform = `scale(${ value / 100 } )` ;
118+ } ;
119+
120+ scaleControlSmaller . addEventListener ( 'click' , ( ) => {
121+ if ( currentScale > MIN_SCALE ) {
122+ setScale ( currentScale - SCALE_STEP ) ;
123+ }
124+ } ) ;
125+
126+ scaleControlBigger . addEventListener ( 'click' , ( ) => {
127+ if ( currentScale < MAX_SCALE ) {
128+ setScale ( currentScale + SCALE_STEP ) ;
129+ }
130+ } ) ;
131+
132+ // Инициализация слайдера
133+ noUiSlider . create ( sliderElement , {
134+ range : { min : 0 , max : 100 } ,
135+ start : 100 ,
136+ step : 1 ,
137+ connect : 'lower' ,
138+ } ) ;
139+
140+ const updateEffect = ( effect ) => {
141+ if ( effect === 'none' ) {
142+ sliderContainer . classList . add ( 'hidden' ) ;
143+ imgPreview . style . filter = 'none' ;
144+ effectValueInput . value = '' ;
145+ return ;
146+ }
147+
148+ sliderContainer . classList . remove ( 'hidden' ) ;
149+ const { range, start, step, filter, unit } = EFFECTS [ effect ] ;
150+
151+ sliderElement . noUiSlider . updateOptions ( { range, start, step } ) ;
152+
153+ sliderElement . noUiSlider . on ( 'update' , ( ) => {
154+ const value = sliderElement . noUiSlider . get ( ) ;
155+ effectValueInput . value = value ;
156+ imgPreview . style . filter = `${ filter } (${ value } ${ unit } )` ;
157+ } ) ;
158+ } ;
159+
160+ // Сброс при старте
161+ updateEffect ( 'none' ) ;
162+
163+ effectsList . addEventListener ( 'change' , ( evt ) => {
164+ updateEffect ( evt . target . value ) ;
165+ } ) ;
166+
0 commit comments