color-picker.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  1. /**
  2. * A color picker based on the Beaver Builder Color Picker,
  3. * with support for accents
  4. */
  5. (function( v, $, undefined ) {
  6. 'use strict';
  7. var FLBuilderColorPresets = [],
  8. UA = navigator.userAgent.toLowerCase();
  9. /**
  10. * @since 1.8.4
  11. * @method flBuilderParseColorValue
  12. * @return {Array}
  13. */
  14. flBuilderParseColorValue = function( val ) {
  15. var value = val.replace(/\s+/g, ''),
  16. alpha = ( value.indexOf('rgba') !== -1 ) ? parseFloat( value.replace(/^.*,(.+)\)/, '$1') * 100 ) : 100,
  17. rgba = ( alpha < 100 ) ? true : false;
  18. return { value: value, alpha: alpha, rgba: rgba };
  19. }
  20. /**
  21. * Main color picker class for Beaver Builder's custom implementation.
  22. *
  23. * @class window.VAMTAM.ColorPicker
  24. * @param {Object} settings
  25. * @since 1.6.4
  26. */
  27. v.ColorPicker = function( settings ) {
  28. this._html = '<div class="vamtam-color-picker-ui"><div class="iris-picker"><div class="iris-picker-inner"><div class="iris-square"><a class="iris-square-value" href="#"><span class="iris-square-handle ui-slider-handle"></span></a><div class="iris-square-inner iris-square-horiz"></div><div class="iris-square-inner iris-square-vert"></div></div><div class="iris-slider iris-strip"><div class="iris-slider-offset"></div></div></div></div></div>';
  29. // default settings
  30. var defaults = {
  31. elements : null,
  32. color : '',
  33. mode : 'hsl',
  34. controls : {
  35. horiz : 's', // horizontal defaults to saturation
  36. vert : 'l', // vertical defaults to lightness
  37. strip : 'h' // right strip defaults to hue
  38. },
  39. target : false, // a DOM element / jQuery selector that the element will be appended within. Only used when called on an input.
  40. width : 200, // the width of the collection of UI elements
  41. presets: [],
  42. labels : {
  43. colorPresets: 'Color Presets',
  44. colorPicker: 'Color Picker',
  45. placeholder: 'Paste color here...',
  46. removePresetConfirm: 'Are you sure?',
  47. noneColorSelected: 'None color selected.',
  48. alreadySaved: '%s is already a saved preset.',
  49. noPresets: 'Add a color preset first.',
  50. accentsTitle: 'Accent Colors',
  51. presetAdded: '%s added to presets!',
  52. }
  53. };
  54. // setting plugin options
  55. this.options = $.extend( {}, defaults, settings );
  56. // initialize the color picker single instance
  57. this._init();
  58. };
  59. v.ColorPicker.prototype = Object.create( FLBuilderColorPicker.prototype );
  60. /**
  61. * Prototype for new instances.
  62. *
  63. * @since 1.6.4
  64. * @property {Object} prototype
  65. */
  66. v.ColorPicker.prototype = Object.assign( v.ColorPicker.prototype, {
  67. /**
  68. * Initializes this instance.
  69. *
  70. * @since 1.6.4
  71. * @method _init
  72. *
  73. * ** MODIFIED **
  74. */
  75. _init: function(){
  76. var self = this,
  77. el = $( self.options.elements );
  78. this.el = el;
  79. el.on( 'change', function( e ) {
  80. FLBuilder.preview.delayPreview( e );
  81. var accent = self._sanitizeAccent( e.target.value );
  82. if ( accent ) {
  83. $( e.target ).parent().find( '.vamtam-color-picker-color' ).css( 'background', accent );
  84. }
  85. } );
  86. this._color = new Color( '#ff0000' ).setHSpace( self.options.mode );
  87. // Set picker color presets
  88. FLBuilderColorPresets = this.options.presets;
  89. // appends color picker markup to the body
  90. // check if there's already a color picker instance
  91. if( $('html').hasClass( 'vamtam-color-picker-init' ) ){
  92. self.picker = $( '.vamtam-color-picker-ui' );
  93. } else {
  94. self.picker = $( this._html ).appendTo( 'body' );
  95. }
  96. // Browsers / Versions
  97. // Feature detection doesn't work for these, and $.browser is deprecated
  98. if ( UA.indexOf('compatible') < 0 && UA.indexOf('khtml') < 0 && UA.match( /mozilla/ ) ) {
  99. self.picker.addClass( 'iris-mozilla' );
  100. }
  101. // prep 'em for re-use
  102. self.controls = {
  103. square : self.picker.find( '.iris-square' ),
  104. squareDrag : self.picker.find( '.iris-square-value' ),
  105. horiz : self.picker.find( '.iris-square-horiz' ),
  106. vert : self.picker.find( '.iris-square-vert' ),
  107. strip : self.picker.find( '.iris-strip' ),
  108. stripSlider : self.picker.find( '.iris-strip .iris-slider-offset' )
  109. };
  110. // small sanity check - if we chose hsv, change default controls away from hsl
  111. if ( self.options.mode === 'hsv' && self._has('l', self.options.controls) ) {
  112. self.options.controls = self._defaultHSVControls;
  113. } else if ( self.options.mode === 'hsl' && self._has('v', self.options.controls) ) {
  114. self.options.controls = self._defaultHSLControls;
  115. }
  116. // store it. HSL gets squirrely
  117. self.hue = self._color.h();
  118. this._setTemplates();
  119. // COLOR PRESETS UI -------------------------------------//
  120. // cache reference to the picker wrapper
  121. this._ui = $( '.vamtam-color-picker-ui' );
  122. this._iris = $( '.iris-picker' );
  123. this._wrapper = $( 'body' );
  124. if( !$('html').hasClass( 'vamtam-color-picker-init' ) ){
  125. this._ui
  126. .prepend( this._hexHtml )
  127. .append( this._presetsHtml );
  128. }
  129. self.element = this._ui.find( '.vamtam-color-picker-input' );
  130. self._initControls();
  131. self.active = 'external';
  132. //self._dimensions();
  133. self._change();
  134. // binds listeners to all color picker instances
  135. self._addInputListeners( self.element );
  136. // build the presets UI
  137. this._buildUI();
  138. // adds needed markup and bind functions to all color fields
  139. this._prepareColorFields();
  140. // bind picker control events
  141. this._pickerControls();
  142. // bind presets control events
  143. this._presetsControls();
  144. // adds opacity/alpha support
  145. this._buildAlphaUI();
  146. // now we know that the picker is already added to the body
  147. $('html').addClass( 'vamtam-color-picker-init' );
  148. },
  149. _sanitizeAccent: function( value ) {
  150. var accent = value.match( /^accent(\d)/ );
  151. if ( accent ) {
  152. return this.options.labels.accents[ accent[1] ];
  153. }
  154. return false;
  155. },
  156. /**
  157. * @since 1.6.4
  158. * @method _prepareColorFields
  159. *
  160. * ** MODIFIED **
  161. */
  162. _prepareColorFields: function(){
  163. var self = this;
  164. // append presets initial html and trigger that toggles the picker
  165. self.el.each( function(){
  166. var $this = $( this ),
  167. $colorValue = $this.val(),
  168. $colorTrigger = $this.parent().find( '.vamtam-color-picker-color' ),
  169. $parsedValue = flBuilderParseColorValue( $colorValue ),
  170. $bgColor = '',
  171. accent = self._sanitizeAccent( $parsedValue.value );
  172. if( $colorValue ){
  173. // set initial color, check for alpha support
  174. if ( $colorTrigger.hasClass('vamtam-color-picker-alpha-enabled') && $parsedValue.rgba ) {
  175. $bgColor = $this.val().toString();
  176. } else if ( ! $colorTrigger.hasClass('vamtam-color-picker-alpha-enabled') && $parsedValue.rgba ) {
  177. var $newColorValue = $colorValue.replace('rgba', 'rgb')
  178. $newColorValue = $newColorValue.substr(0, $newColorValue.lastIndexOf(",")) + ')';
  179. self._color._alpha = 1;
  180. $bgColor = $newColorValue;
  181. $this.val($newColorValue);
  182. } else {
  183. $bgColor = accent || $this.val().toString();
  184. }
  185. $colorTrigger.css({ backgroundColor: $bgColor });
  186. }
  187. });
  188. },
  189. /**
  190. * Sets templates to build the color picker markup.
  191. *
  192. * @since 1.6.4
  193. * @method _setTemplates
  194. *
  195. * ** MODIFIED **
  196. */
  197. _setTemplates: function(){
  198. this._alphaHtml = '<div class="vamtam-alpha-wrap">' +
  199. '<div class="vamtam-alpha-slider"></div>' +
  200. '<div class="vamtam-alpha-slider-offset"></div>' +
  201. '</div>';
  202. this._presetsHtml = '<div class="vamtam-color-picker-presets">' +
  203. '<div class="vamtam-color-picker-presets-toggle">' +
  204. '<div class="vamtam-color-picker-presets-open-label vamtam-color-picker-active">' + this.options.labels.colorPresetsAccents + ' <span class="vamtam-color-picker-icon-arrow-up"></span></div>' +
  205. '<div class="vamtam-color-picker-presets-close-label">' + this.options.labels.colorPicker + ' <span class="vamtam-color-picker-icon-arrow-down"></span></div>' +
  206. '</div>' +
  207. '<ul class="vamtam-color-picker-presets-list"></ul>' +
  208. '</div>';
  209. this._hexHtml = '<input type="text" class="vamtam-color-picker-input" maxlength="7" placeholder="' + this.options.labels.placeholder + '">' +
  210. '<div class="vamtam-color-picker-preset-add"></div>';
  211. this._presetsTpl = '<li class="vamtam-color-picker-preset"><span class="vamtam-color-picker-preset-color"></span> <span class="vamtam-color-picker-preset-label"></span> <span class="vamtam-color-picker-preset-remove vamtam-color-picker-icon-remove"></span></li>';
  212. this._noPresetsTpl = '<li class="vamtam-color-picker-no-preset"><span class="vamtam-color-picker-preset-label">' + this.options.labels.noPresets + '</span></li>';
  213. this._accentsTitleTpl = '<li class="vamtam-color-picker-accents-heading"><span class="vamtam-color-picker-preset-label"><b>' + this.options.labels.accentsTitle + '</b></span></li>';
  214. this._presetsTitleTpl = '<li class="vamtam-color-picker-presets-heading"><span class="vamtam-color-picker-preset-label"><b>' + this.options.labels.colorPresets + '</b></span></li>';
  215. },
  216. /**
  217. * Builds the UI for color presets
  218. *
  219. * @see _addPresetView
  220. * @since 1.6.4
  221. * @method _buildUI
  222. *
  223. * ** MODIFIED **
  224. */
  225. _buildUI: function(){
  226. var self = this;
  227. self._presetsList = this._ui.find( '.vamtam-color-picker-presets-list' );
  228. self._presetsList.html('');
  229. // accents
  230. self._presetsList.append( this._accentsTitleTpl );
  231. var accentsWrapper = document.createElement( 'li' );
  232. accentsWrapper.classList.add( 'vamtam-color-picker-accents-list' );
  233. for ( var i in this.options.labels.accents ) {
  234. var accent = this.options.labels.accents[ i ];
  235. var s = document.createElement( 'span' );
  236. s.innerHTML = i;
  237. s.style.background = accent;
  238. s.style.color = new Color( accent ).getMaxContrastColor().toString();
  239. accentsWrapper.appendChild( s );
  240. }
  241. self._presetsList.append( accentsWrapper );
  242. // presets
  243. self._presetsList.append( this._presetsTitleTpl );
  244. if( this.options.presets.length > 0 ){
  245. $.each( this.options.presets, function( index, val ) {
  246. self._addPresetView( val );
  247. });
  248. } else {
  249. self._presetsList.append( this._noPresetsTpl );
  250. }
  251. },
  252. /**
  253. * Helper function to build a view for each color preset.
  254. *
  255. * @since 1.6.4
  256. * @param {string} val the respective hex code for the color preset.
  257. * @return void
  258. *
  259. * ** MODIFIED **
  260. */
  261. _addPresetView: function( val ){
  262. var hasEmpty = this._presetsList.find( '.vamtam-color-picker-no-preset' );
  263. if( hasEmpty.length > 0 ){
  264. hasEmpty.remove();
  265. }
  266. var tpl = $( this._presetsTpl ),
  267. color = Color( val );
  268. tpl
  269. .attr( 'data-color', val )
  270. .find( '.vamtam-color-picker-preset-color' )
  271. .css({ backgroundColor: color.toString() })
  272. .end()
  273. .find( '.vamtam-color-picker-preset-label' )
  274. .html( color.toString() );
  275. this._presetsList.append( tpl );
  276. },
  277. /**
  278. * Shows a visual feedback when a color is added as a preset.
  279. *
  280. * @since 1.6.4
  281. * @method _addPresetFeedback
  282. *
  283. * ** MODIFIED **
  284. */
  285. _addPresetFeedback: function(){
  286. this._ui.append( '<div class="vamtam-color-picker-added"><div class="vamtam-color-picker-added-text"><div class="vamtam-color-picker-icon-check"></div> "' + this.options.labels.presetAdded.replace( '%s', this._color.toString() ) + '"</div></div>' );
  287. this._ui
  288. .find( '.vamtam-color-picker-added' )
  289. .hide()
  290. .fadeIn( 200 )
  291. .delay( 2000 )
  292. .fadeOut( 200, function(){
  293. $(this).remove();
  294. } );
  295. },
  296. /**
  297. * Sets some triggers for positioning logic of the picker and color reset.
  298. *
  299. * @since 1.6.4
  300. * @method _pickerControls
  301. *
  302. * ** MODIFIED **
  303. */
  304. _pickerControls: function(){
  305. var self = this;
  306. // logic for picker positioning
  307. this._wrapper
  308. .on( 'click', '.vamtam-color-picker-color', function(){
  309. var $this = $(this);
  310. self._currentElement = $this.parent().find('.vamtam-color-picker-value');
  311. self._ui.position({
  312. my: 'left top',
  313. at: 'left bottom',
  314. of: $this,
  315. collision: 'flipfit',
  316. using: function( position, feedback ){
  317. self._togglePicker( position );
  318. }
  319. })
  320. } )
  321. .on( 'click', '.vamtam-color-picker-clear', function(){
  322. var $this = $(this);
  323. self._currentElement = $this.parent().find('.vamtam-color-picker-value');
  324. $this
  325. .prev( '.vamtam-color-picker-color' )
  326. .css({ backgroundColor: 'transparent' })
  327. .addClass('vamtam-color-picker-empty');
  328. self._setColor( '' );
  329. self.element.val( '' );
  330. self._currentElement
  331. .val( '' )
  332. .trigger( 'change' );
  333. } );
  334. // logic to hide picker when the user clicks outside it
  335. $( document ).on( 'click', function( event ) {
  336. if ( 0 === $( event.target ).closest( '.vamtam-color-picker-ui' ).length ) {
  337. $( '.vamtam-color-picker-ui.vamtam-color-picker-active' ).removeClass( 'vamtam-color-picker-active' );
  338. }
  339. });
  340. },
  341. /**
  342. * Logic for color presets UI.
  343. *
  344. * @see _addPreset
  345. * @see _removePreset
  346. * @since 1.6.4
  347. * @method _presetsControls
  348. *
  349. * ** MODIFIED **
  350. */
  351. _presetsControls: function(){
  352. var self = this,
  353. addPreset = self._ui.find( '.vamtam-color-picker-preset-add' ),
  354. presets = self._ui.find( '.vamtam-color-picker-presets' ),
  355. presetsOpenLabel = presets.find( '.vamtam-color-picker-presets-open-label' ),
  356. presetsCloseLabel = presets.find( '.vamtam-color-picker-presets-close-label' ),
  357. presetsList = presets.find( '.vamtam-color-picker-presets-list' );
  358. // add preset
  359. addPreset
  360. .off( 'click' )
  361. .on( 'click', function(){
  362. self._addPreset( self.element.val() );
  363. } );
  364. // presets toggle
  365. presetsList
  366. .css({ height: ( self.element.innerHeight() + self._iris.innerHeight() + 14 ) + 'px' })
  367. .hide();
  368. presets
  369. .off( 'click' )
  370. .on( 'click', '.vamtam-color-picker-presets-toggle', function(){
  371. presetsOpenLabel.toggleClass('vamtam-color-picker-active');
  372. presetsCloseLabel.toggleClass('vamtam-color-picker-active');
  373. presetsList.slideToggle( 500 );
  374. } )
  375. // set preset as current color
  376. .on( 'click', '.vamtam-color-picker-preset', function( e ){
  377. var currentColor = new Color( $( this ).data( 'color' ).toString() );
  378. self._setColor( currentColor );
  379. self._currentElement
  380. .parent()
  381. .find( '.vamtam-color-picker-color' )
  382. .css({ backgroundColor: currentColor.toString() })
  383. .removeClass('vamtam-color-picker-empty');
  384. presetsOpenLabel.toggleClass('vamtam-color-picker-active');
  385. presetsCloseLabel.toggleClass('vamtam-color-picker-active');
  386. presetsList.slideToggle( 500 );
  387. })
  388. // removes a preset
  389. .on( 'click', '.vamtam-color-picker-preset-remove', function( e ){
  390. e.stopPropagation();
  391. self._removePreset( $( this ).parent().data( 'color' ) );
  392. })
  393. // accents
  394. .on( 'click', '.vamtam-color-picker-accents-list span', function( e ) {
  395. e.stopPropagation();
  396. self._setColor( 'accent' + e.target.innerHTML );
  397. } )
  398. },
  399. /**
  400. * Removes a color preset from the array of presets and from the UI.
  401. *
  402. * @since 1.6.4
  403. * @method _removePreset
  404. * @param {String} preset The respective hex value of the preset.
  405. *
  406. * ** MODIFIED **
  407. */
  408. _removePreset: function( preset ){
  409. if( confirm( this.options.labels.removePresetConfirm ) ){
  410. var color = preset.toString(),
  411. index = FLBuilderColorPresets.indexOf( color );
  412. if( index > -1 ){
  413. FLBuilderColorPresets.splice( index, 1 );
  414. this.options.presets = FLBuilderColorPresets;
  415. this._presetsList
  416. .find('.vamtam-color-picker-preset[data-color="'+ color +'"]' )
  417. .slideUp( function(){
  418. $( this ).remove();
  419. });
  420. }
  421. if( FLBuilderColorPresets.length < 1 ){
  422. this._presetsList.append( this._noPresetsTpl );
  423. }
  424. // CALLBACK FOR PRESET REMOVED
  425. $(this).trigger( 'presetRemoved', { presets: FLBuilderColorPresets } );
  426. }
  427. },
  428. /**
  429. * Logic to add a color preset to the array of presets, and to the UI.
  430. *
  431. * @see _addPresetView
  432. * @see _addPresetFeedback
  433. * @method _addPreset
  434. * @param {String} preset The respective hex value of the preset.
  435. * @since 1.6.4
  436. *
  437. * ** MODIFIED **
  438. */
  439. _addPreset: function( preset ){
  440. var color = preset.toString();
  441. // check if color is empty
  442. if( color === '' ){
  443. alert( this.options.labels.noneColorSelected );
  444. // check if the color is already added
  445. } else if( FLBuilderColorPresets.indexOf( color ) > -1 ){
  446. alert( this.options.labels.alreadySaved.replace( '%s', '#' + color ) );
  447. // add color to presets, fires visual feedback and triggers an event
  448. } else {
  449. this._addPresetView( color );
  450. this._addPresetFeedback();
  451. FLBuilderColorPresets.push( color );
  452. this.options.presets = FLBuilderColorPresets;
  453. // CALLBACK FOR COLOR ADDED
  454. $(this).trigger( 'presetAdded', { presets: FLBuilderColorPresets } );
  455. }
  456. },
  457. /**
  458. * Logic for positioning of the color picker.
  459. *
  460. * @since 1.6.4
  461. * @method _togglePicker
  462. * @param {Object} position An object containing x and y location for positioning.
  463. *
  464. * ** MODIFIED **
  465. */
  466. _togglePicker: function( position ){
  467. var self = this;
  468. // logic for correct order of things
  469. if( this._ui.hasClass( 'vamtam-color-picker-active' ) ){
  470. // if the picker is open, hides first, then changes the position
  471. this._ui.removeClass( 'vamtam-color-picker-active' );
  472. if( position ){
  473. setTimeout( function(){
  474. self._ui.css( position );
  475. self._ui.addClass( 'vamtam-color-picker-active' );
  476. self._setColor( self._currentElement.val() );
  477. }, 200 );
  478. }
  479. } else {
  480. if( position ){
  481. self._ui.css( position );
  482. }
  483. // if the picker is closed, changes position first, then shows it
  484. setTimeout( function(){
  485. self._ui.addClass( 'vamtam-color-picker-active' );
  486. self._setColor( self._currentElement.val() );
  487. }, 200 );
  488. }
  489. },
  490. /**
  491. * Logic to listen to events from the main color input and to bind it to the current color field.
  492. *
  493. * @see _setColor
  494. * @since 1.6.4
  495. * @method _addInputListeners
  496. * @param {Object} input
  497. *
  498. * ** MODIFIED **
  499. */
  500. _addInputListeners: function( input ) {
  501. var self = this,
  502. debounceTimeout = 100,
  503. callback = function( event ){
  504. var color = new Color( input.val() ),
  505. val = input.val();
  506. input.removeClass( 'iris-error' );
  507. // we gave a bad color
  508. if ( color.error ) {
  509. // don't error on an empty input - we want those allowed
  510. if ( val !== '' ) {
  511. input.addClass( 'iris-error' );
  512. }
  513. } else {
  514. if ( color.toString() !== self._color.toString() ) {
  515. if( event.type === 'keyup' ){
  516. if( val.match( /^[0-9a-fA-F]{3}$/ ) )
  517. return;
  518. self._setColor( val );
  519. self._currentElement
  520. .parent()
  521. .find( '.vamtam-color-picker-color' )
  522. .css({ backgroundColor: Color( val ).toString() })
  523. .removeClass( 'vamtam-color-picker-empty' );
  524. self._currentElement
  525. .val( val )
  526. .trigger( 'change' );
  527. } else if( event.type === 'paste' ){
  528. val = event.originalEvent.clipboardData.getData( 'text' );
  529. hex = Color( val ).toString();
  530. self._setColor( val );
  531. input.val( hex );
  532. self._currentElement
  533. .parent()
  534. .find( '.vamtam-color-picker-color' )
  535. .css({ backgroundColor: hex })
  536. .removeClass( 'vamtam-color-picker-empty' );
  537. self._currentElement
  538. .val( val )
  539. .trigger( 'change' );
  540. return false;
  541. }
  542. }
  543. }
  544. };
  545. input.on( 'change', callback ).on( 'keyup', self._debounce( callback, debounceTimeout ) );
  546. },
  547. /**
  548. * @since 1.6.4
  549. * @method _setColor
  550. * @param {String} value
  551. *
  552. * ** MODIFIED **
  553. */
  554. _setColor: function( value ) {
  555. var self = this,
  556. oldValue = self.options.color,
  557. doDimensions = false,
  558. newColor,
  559. method;
  560. // ensure the new value is set. We can reset to oldValue if some check wasn't met.
  561. self.options.color = value;
  562. // cast to string in case we have a number
  563. value = '' + value;
  564. newColor = new Color( value ).setHSpace( self.options.mode );
  565. if ( newColor.error ) {
  566. var accent = self._sanitizeAccent( value );
  567. if ( accent ) {
  568. self._color = new Color( accent ).setHSpace( self.options.mode );
  569. self.options.color = value;
  570. self.active = 'external';
  571. self.usedAccent = value;
  572. self._change();
  573. } else {
  574. self.options.color = oldValue;
  575. }
  576. } else {
  577. self._color = newColor;
  578. self.options.color = self._color.toString();
  579. self.active = 'external';
  580. self._change();
  581. }
  582. },
  583. /**
  584. * @since 1.6.4
  585. * @method _change
  586. *
  587. * ** MODIFIED **
  588. */
  589. _change: function() {
  590. var self = this,
  591. controls = self.controls,
  592. color = self._getHSpaceColor(),
  593. actions = [ 'square', 'strip' ],
  594. controlOpts = self.options.controls,
  595. type = controlOpts[self.active] || 'external',
  596. oldHue = self.hue;
  597. if ( self.active === 'strip' ) {
  598. // take no action on any of the square sliders if we adjusted the strip
  599. actions = [];
  600. } else if ( self.active !== 'external' ) {
  601. // for non-strip, non-external, strip should never change
  602. actions.pop(); // conveniently the last item
  603. }
  604. $.each( actions, function(index, item) {
  605. var value, dimensions, cssObj;
  606. if ( item !== self.active ) {
  607. switch ( item ) {
  608. case 'strip':
  609. // reverse for hue
  610. value = ( controlOpts.strip === 'h' ) ? self._scale[controlOpts.strip] - color[controlOpts.strip] : color[controlOpts.strip];
  611. controls.stripSlider.slider( 'value', value );
  612. break;
  613. case 'square':
  614. dimensions = self._squareDimensions();
  615. cssObj = {
  616. left: color[controlOpts.horiz] / self._scale[controlOpts.horiz] * dimensions.w,
  617. top: dimensions.h - ( color[controlOpts.vert] / self._scale[controlOpts.vert] * dimensions.h )
  618. };
  619. self.controls.squareDrag.css( cssObj );
  620. break;
  621. }
  622. }
  623. });
  624. // Ensure that we don't change hue if we triggered a hue reset
  625. if ( color.h !== oldHue && self._isNonHueControl( self.active, type ) ) {
  626. self._color.h(oldHue);
  627. }
  628. // store hue for repeating above check next time
  629. self.hue = self._color.h();
  630. self.options.color = self._color.toString();
  631. if ( self.element.is( ':input' ) && ! self._color.error ) {
  632. self.element.removeClass( 'iris-error' );
  633. if ( self.element.val() !== self._color.toString() ) {
  634. self.element.val( self.usedAccent || self._color.toString() );
  635. if ( this._currentElement ) {
  636. var bgColor = self._sanitizeAccent( self.usedAccent || '' ) || self._color.toString();
  637. this._currentElement
  638. .val( self.usedAccent || self._color.toString() )
  639. .parent()
  640. .find( '.vamtam-color-picker-color' )
  641. .css({ backgroundColor: bgColor })
  642. .removeClass( 'vamtam-color-picker-empty' );
  643. self._wrapper.find( '.vamtam-alpha-slider-offset' ).css( 'background-color', bgColor );
  644. this._currentElement.trigger( 'change' );
  645. }
  646. }
  647. }
  648. self._paint();
  649. self._inited = true;
  650. self.active = false;
  651. delete self.usedAccent;
  652. },
  653. /**
  654. * Show an alpha UI when it is enabled
  655. *
  656. * @since 1.8.5
  657. * @method _buildAlphaUI
  658. *
  659. * ** MODIFIED **
  660. */
  661. _buildAlphaUI: function() {
  662. var self = this;
  663. self._wrapper.on( 'click', '.vamtam-color-picker-color', function(){
  664. var $this = $(this),
  665. $currentColor = self._currentElement.val();
  666. if ( $this.hasClass('vamtam-color-picker-alpha-enabled') ) {
  667. // Add alpha if not exists
  668. if (self._ui.find('.vamtam-alpha-wrap').length <= 0) {
  669. $(self._alphaHtml).insertAfter( self._iris );
  670. }
  671. self._pickerAlphaControls();
  672. }
  673. else {
  674. self._ui.find('.vamtam-alpha-wrap').remove();
  675. }
  676. });
  677. },
  678. /**
  679. * Enable the opacity/alpha to color picker
  680. * Credits to https://github.com/Codestar/codestar-wp-color-picker
  681. *
  682. * @since 1.8.5
  683. * @method _pickerAlphaControls
  684. *
  685. * ** MODIFIED **
  686. */
  687. _pickerAlphaControls: function() {
  688. var self = this,
  689. el = self._currentElement,
  690. picker = flBuilderParseColorValue( el.val() ),
  691. floatValue = parseFloat( picker.alpha / 100 ),
  692. wrapper = self._wrapper,
  693. container = self._ui,
  694. alphaWrap = container.find('.vamtam-alpha-wrap'),
  695. alphaSlider = alphaWrap.find('.vamtam-alpha-slider'),
  696. alphaOffset = alphaWrap.find('.vamtam-alpha-slider-offset'),
  697. alphaHandle = alphaWrap.find('.ui-slider-handle');
  698. // alpha slider
  699. alphaSlider.slider({
  700. orientation: "horizontal",
  701. // slider: slide
  702. slide: function( event, ui ) {
  703. var slideValue = parseFloat( ui.value / 100 );
  704. // update iris data alpha && color option && alpha text
  705. self._color._alpha = slideValue;
  706. self._change.apply( self, arguments );
  707. },
  708. // slider: create
  709. create: function() {
  710. // Initializes alpha values
  711. alphaOffset.css({ backgroundColor: picker.value });
  712. // Clear alpha values
  713. wrapper.on('click', '.vamtam-color-picker-clear', function() {
  714. self._color._alpha = 1;
  715. alphaSlider.slider('value', 100).trigger('slide');
  716. });
  717. },
  718. // slider: options
  719. value: picker.alpha,
  720. step: 1,
  721. min: 1,
  722. max: 100
  723. });
  724. },
  725. } );
  726. FLBuilder.addHook( 'settings-form-init', function( e ) {
  727. setTimeout( function() {
  728. var picker = new v.ColorPicker({
  729. mode: 'hsv',
  730. elements: '.vamtam-color-picker-value',
  731. presets: FLBuilderConfig.colorPresets || [],
  732. labels: Object.assign( {}, FLBuilderStrings, VamtamColorPickerStrings ),
  733. mode: 'hsv'
  734. });
  735. $( picker ).on( 'presetRemoved presetAdded', function( event, data ) {
  736. FLBuilder.ajax({
  737. action: 'save_color_presets',
  738. presets: data.presets
  739. });
  740. });
  741. }, 0 );
  742. } );
  743. })( window.VAMTAM = window.VAMTAM || {}, jQuery );