diff --git a/includes/assets/js/kb-progress-bars.min.js b/includes/assets/js/kb-progress-bars.min.js new file mode 100644 index 000000000..85b61cef5 --- /dev/null +++ b/includes/assets/js/kb-progress-bars.min.js @@ -0,0 +1 @@ +(function(){"use strict";const a={cache:{},scroller:{},items:JSON.parse(kadence_blocks_progress_bars.items),windowResize(){a?.items&&Object.keys(a?.items).forEach(function(b){a.updateContainer(a.items[b])})},updateContainer(b){const c=document.querySelectorAll(".kb-progress-bar-"+b.unique_id),d=[];if(c?.length)for(let e=0;ewindow.innerWidth?("line"===b.type&&(a.setAttribute("viewBox","0 0 100 "+b.stokeWidths[2]),d.setAttribute("d","M 0,"+b.stokeWidths[2]/2+" L 100,"+b.stokeWidths[2]/2),e.setAttribute("d","M 0,"+b.stokeWidths[2]/2+" L 100,"+b.stokeWidths[2]/2)),d.setAttribute("stroke-width",b.stokeWidths[2]),e.setAttribute("stroke-width",b.stokeWidths[2])):1025>window.innerWidth?("line"===b.type&&(a.setAttribute("viewBox","0 0 100 "+b.stokeWidths[1]),d.setAttribute("d","M 0,"+b.stokeWidths[1]/2+" L 100,"+b.stokeWidths[1]/2),e.setAttribute("d","M 0,"+b.stokeWidths[1]/2+" L 100,"+b.stokeWidths[1]/2)),d.setAttribute("stroke-width",b.stokeWidths[1]),e.setAttribute("stroke-width",b.stokeWidths[1])):("line"===b.type&&(a.setAttribute("viewBox","0 0 100 "+b.stokeWidths[0]),d.setAttribute("d","M 0,"+b.stokeWidths[0]/2+" L 100,"+b.stokeWidths[0]/2),e.setAttribute("d","M 0,"+b.stokeWidths[0]/2+" L 100,"+b.stokeWidths[0]/2)),d.setAttribute("stroke-width",b.stokeWidths[0]),e.setAttribute("stroke-width",b.stokeWidths[0]))},triggerAnimation(b,c,d){if(a.cache[d.simple_id][c]){const e=d?.prefix?a.stripHtml(d.prefix):"",f=d?.suffix?a.stripHtml(d.suffix):"";a.cache[d.simple_id][c].animate(d.progress_real/d.progress_max,{duration:1e3*d.duration,step(a,c){let g=0;const h=b.querySelector(".kb-current-progress-above"),i=b.querySelector(".kb-current-progress-inside"),j=b.querySelector(".kb-current-progress-below");g=d.is_relative?100*c.value():c.value()*d.progress_max,"one"===d.decimal?(g=Math.round(10*g)/10,g=g.toFixed(1)):"two"===d.decimal?(g=Math.round(100*g)/100,g=g.toFixed(2)):g=Math.round(g),h?h.innerHTML=e+g+f:i?i.innerHTML=e+g+f:j&&(j.innerHTML=e+g+f)}})}},initSingleBarElement(b,c,d){let e=768>window.innerWidth?d.stokeWidths?.[2]?d.stokeWidths[2]:2:1025>window.innerWidth?d.stokeWidths?.[1]?d.stokeWidths[1]:2:d.stokeWidths?.[0]?d.stokeWidths[0]:2;const f=b.querySelector(".kb-progress-bar"),g={color:d.progressColor,trailColor:d.barBackground,duration:1e3*d.duration,easing:d.easing,strokeWidth:e};switch(a.cache[d.simple_id]||(a.cache[d.simple_id]=[]),d.type){case"circle":a.cache[d.simple_id][c]=new ProgressBar.Circle(f,g);break;case"line":a.cache[d.simple_id][c]=new ProgressBar.Line(f,g);break;case"semicircle":a.cache[d.simple_id][c]=new ProgressBar.SemiCircle(f,g)}if(d.delay){a.scroller[d.simple_id]||(a.scroller[d.simple_id]=[]),a.scroller[d.simple_id][c]=new ScrollMagic.Controller;const e=new ScrollMagic.Scene({triggerElement:b});e.triggerHook(.88),e.addTo(a.scroller[d.simple_id][c]),e.on("start",function(){a.triggerAnimation(b,c,d)})}else a.triggerAnimation(b,c,d)},initSingleBar(b){const c=document.querySelectorAll(".kb-progress-bar-container"+b.unique_id);if(c?.length)for(let d=0;d${a}`,"text/html");return b.body.textContent||""},initAll(){a?.items&&Object.keys(a?.items).forEach(function(b){a.initSingleBar(a.items[b])})},init(){if("undefined"!=typeof ProgressBar)a.initAll();else var b=setInterval(function(){"undefined"!=typeof ProgressBar&&(a.initAll(),clearInterval(b))},200)}};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",a.init):a.init(),window.addEventListener("resize",a.windowResize,!1)})(); \ No newline at end of file diff --git a/includes/blocks/class-kadence-blocks-progress-bar-block.php b/includes/blocks/class-kadence-blocks-progress-bar-block.php index a6422f8fc..47d80c686 100644 --- a/includes/blocks/class-kadence-blocks-progress-bar-block.php +++ b/includes/blocks/class-kadence-blocks-progress-bar-block.php @@ -31,6 +31,13 @@ class Kadence_Blocks_Progress_Bar_Block extends Kadence_Blocks_Abstract_Block { */ protected $block_name = 'progress-bar'; + /** + * Block determines in scripts need to be loaded for block. + * + * @var string + */ + protected static $progress_bars = []; + /** * Block determines in scripts need to be loaded for block. * @@ -48,6 +55,13 @@ public static function get_instance() { return self::$instance; } + /** + * Class Constructor. + */ + public function __construct() { + parent::__construct(); + add_action( 'wp_footer', [ $this, 'data_enqueue' ], 9 ); + } /** * Builds CSS for block. @@ -59,9 +73,6 @@ public static function get_instance() { */ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { - wp_enqueue_script( 'kadence-blocks-' . $this->block_name ); - wp_enqueue_script( 'kadence-blocks-scroll-magic' ); - $css->set_style_id( 'kb-' . $this->block_name . $unique_style_id ); $css->set_selector( '.kb-progress-bar-container' . $unique_id ); @@ -126,15 +137,15 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { $css->set_selector( '.kb-progress-bar-container' . $unique_id . ' .kb-progress-label-wrap .kt-progress-percent' ); - if( isset( $attributes['numberFont'], $attributes['labelFont'] ) ) { + if ( isset( $attributes['numberFont'], $attributes['labelFont'] ) ) { $default_font = $this->get_default_font(); - $diff = $this->arrayRecursiveDiff( $attributes['numberFont'], $default_font ); - $attributes['numberFont'] = array_merge( $attributes['labelFont'], $diff ); + $diff = $this->array_recursive_diff( $attributes['numberFont'], $default_font ); + $attributes['numberFont'] = array_merge( $attributes['labelFont'], $diff ); $css->render_typography( $attributes, 'numberFont' ); - } else if ( isset( $attributes['numberFont'] ) ) { + } elseif ( isset( $attributes['numberFont'] ) ) { $css->render_typography( $attributes, 'numberFont' ); - } else if ( isset( $attributes['labelFont'] ) ) { + } elseif ( isset( $attributes['labelFont'] ) ) { $css->render_typography( $attributes, 'labelFont' ); } @@ -171,7 +182,7 @@ public function build_css( $attributes, $css, $unique_id, $unique_style_id ) { $mask_height_tablet_string = $mask_height_tablet ? $mask_height_tablet . 'px' : ''; $mask_height_mobile_string = $mask_height_mobile ? $mask_height_mobile . 'px' : ''; - $css->set_selector( '#kb-progress-bar' . $unique_id ); + $css->set_selector( '.kb-progress-bar-container' . $unique_id . ' .kb-progress-bar-' . $unique_id ); $css->add_property( '-webkit-mask-image', $mask_image_string ); $css->add_property( 'mask-image', $mask_image_string ); @@ -207,26 +218,19 @@ public function build_html( $attributes, $unique_id, $content, $block_instance ) $css = new Kadence_Blocks_CSS(); - $simple_id = str_replace( '-', '', esc_attr( $unique_id ) ); - - $bar_types = array( - 'line' => 'Line', - 'circle' => 'Circle', - 'semicircle' => 'SemiCircle' - ); - + $simple_id = str_replace( '-', '', esc_attr( $unique_id ) ); $progress_color = ! empty( $attributes['progressColor'] ) ? $css->sanitize_color( $attributes['progressColor'], $attributes['progressOpacity'] ) : 'var(--global-palette1, #2B6CB0)'; $bar_background = ! empty( $attributes['barBackground'] ) ? $css->sanitize_color( $attributes['barBackground'], $attributes['barBackgroundOpacity'] ) : 'var(--global-palette7, #EDF2F7)'; - $prefix = isset( $attributes['numberPrefix'] ) ? esc_attr( $attributes['numberPrefix'] ) : ''; - $suffix = isset( $attributes['numberSuffix'] ) ? esc_attr( $attributes['numberSuffix'] ) : ''; - $progress_min = 0; + $prefix = isset( $attributes['numberPrefix'] ) ? esc_attr( $attributes['numberPrefix'] ) : ''; + $suffix = isset( $attributes['numberSuffix'] ) ? esc_attr( $attributes['numberSuffix'] ) : ''; + $progress_min = 0; $progress_amount = ! empty( $attributes['progressAmount'] ) ? $attributes['progressAmount'] : 0; - $progress_max = ! empty( $attributes['progressMax'] ) ? $attributes['progressMax'] : 100; - $is_relative = isset( $attributes['numberIsRelative'] ) ? $attributes['numberIsRelative'] : false; - $decimal = ! empty( $attributes['decimal'] ) ? $attributes['decimal'] : 'none'; - $delay = isset( $attributes['delayUntilInView'] ) ? $attributes['delayUntilInView'] : true; - $stroke_widths = array( + $progress_max = ! empty( $attributes['progressMax'] ) ? $attributes['progressMax'] : 100; + $is_relative = isset( $attributes['numberIsRelative'] ) ? $attributes['numberIsRelative'] : false; + $decimal = ! empty( $attributes['decimal'] ) ? $attributes['decimal'] : 'none'; + $delay = isset( $attributes['delayUntilInView'] ) ? $attributes['delayUntilInView'] : true; + $stroke_widths = array( ! empty( $attributes['progressWidth'] ) ? $attributes['progressWidth'] : 2, ! empty( $attributes['progressWidthTablet'] ) ? $attributes['progressWidthTablet'] : ( ! empty( $attributes['progressWidth'] ) ? $attributes['progressWidth'] : 2 ), ! empty( $attributes['progressWidthMobile'] ) ? $attributes['progressWidthMobile'] : ( ! empty( $attributes['progressWidthTablet'] ) ? $attributes['progressWidthTablet'] : ( ! empty( $attributes['progressWidth'] ) ? $attributes['progressWidth'] : 2 ) ), @@ -237,8 +241,7 @@ public function build_html( $attributes, $unique_id, $content, $block_instance ) $content .= $this->get_label( $attributes, 'above' ); $progress_args = [ - 'id' => 'kb-progress-bar' . esc_attr( $unique_id ), - 'class' => 'kb-progress-bar', + 'class' => 'kb-progress-bar kb-progress-bar-' . esc_attr( $unique_id ), ]; if ( ! empty( $attributes['label'] ) && ( ! isset( $attributes['displayLabel'] ) || ( isset( $attributes['displayLabel'] ) && $attributes['displayLabel'] !== false ) ) ) { $progress_args['aria-labelledby'] = 'kt-progress-label' . esc_attr( $unique_id ); @@ -264,111 +267,26 @@ public function build_html( $attributes, $unique_id, $content, $block_instance ) $content .= ''; $bar_type_for_script = $attributes['barType'] == 'line-mask' ? 'line' : $attributes['barType']; - - $content .= ''; - + $progress_real = $progress_amount <= $progress_max ? $progress_amount : $progress_max; + + self::$progress_bars[ $unique_id ] = [ + 'unique_id' => $unique_id, + 'simple_id' => $simple_id, + 'type' => $bar_type_for_script, + 'progressColor' => $progress_color, + 'barBackground' => $bar_background, + 'stokeWidths' => $stroke_widths, + 'decimal' => $decimal, + 'delay' => $delay, + 'duration' => ! empty( $attributes['duration'] ) ? $attributes['duration'] : 1, + 'easing' => ! empty( $attributes['easing'] ) ? $attributes['easing'] : 'linear', + 'prefix' => $prefix, + 'suffix' => $suffix, + 'progress_real' => $progress_real, + 'progress_max' => $progress_max, + 'is_relative' => $is_relative, + ]; + wp_enqueue_script( 'kadence-blocks-' . $this->block_name ); return $content; } @@ -422,11 +340,11 @@ private function get_percent( $attributes ) { $prefix = isset( $attributes['numberPrefix'] ) ? $attributes['numberPrefix'] : ''; $suffix = isset( $attributes['numberSuffix'] ) ? $attributes['numberSuffix'] : ''; - $starting = !empty( $attributes['progressMax'] ) && !empty( $attributes['showMaxProgressOnPageLoad'] ) ? $attributes['progressMax'] : 0; + $starting = ! empty( $attributes['progressMax'] ) && ! empty( $attributes['showMaxProgressOnPageLoad'] ) ? $attributes['progressMax'] : 0; $position = isset( $attributes['labelPosition'] ) ? $attributes['labelPosition'] : 'above'; - return '' . $prefix . $starting . $suffix . ''; + return '' . $prefix . $starting . $suffix . ''; } /** @@ -500,31 +418,47 @@ private function get_default_font() { * array_diff_assoc doesn't work on multidimensional arrays, so we need to use this function. * If any sub-key value is different, to entire parent key is returned. * - * @param $aArray1 - * @param $aArray2 + * @param $a_array + * @param $b_array * * @return array */ - private function arrayRecursiveDiff($aArray1, $aArray2) { - $aReturn = array(); - - foreach ($aArray1 as $mKey => $mValue) { - if (array_key_exists($mKey, $aArray2)) { - if (is_array($mValue)) { - $aRecursiveDiff = $this->arrayRecursiveDiff($mValue, $aArray2[$mKey]); - if (count($aRecursiveDiff)) { $aReturn[$mKey] = $mValue; } + private function array_recursive_diff( $a_array, $b_array ) { + $a_return = []; + + foreach ( $a_array as $m_key => $m_value) { + if ( array_key_exists( $m_key, $b_array ) ) { + if ( is_array( $m_value ) ) { + $a_recursive_diff = $this->array_recursive_diff( $m_value, $b_array[ $m_key ] ); + if ( count( $a_recursive_diff ) ) { + $a_return[ $m_key ] = $m_value; + } } else { - if ($mValue != $aArray2[$mKey]) { - $aReturn[$mKey] = $mValue; + if ( $m_value != $b_array[ $m_key ] ) { + $a_return[ $m_key ] = $m_value; } } } else { - $aReturn[$mKey] = $mValue; + $a_return[ $m_key ] = $m_value; } } - return $aReturn; + return $a_return; + } + /** + * Enqueue the block's items. + */ + public function data_enqueue() { + if ( empty( self::$progress_bars ) ) { + return; + } + wp_localize_script( + 'kadence-blocks-' . $this->block_name, + 'kadence_blocks_progress_bars', + [ + 'items' => wp_json_encode( self::$progress_bars ), + ] + ); } - /** * Registers scripts and styles. */ @@ -540,9 +474,9 @@ public function register_scripts() { return; } - wp_register_script( 'kadence-blocks-' . $this->block_name, KADENCE_BLOCKS_URL . 'includes/assets/js/progressBar.min.js', array(), KADENCE_BLOCKS_VERSION, false ); - wp_register_script( 'kadence-blocks-scroll-magic', KADENCE_BLOCKS_URL . 'includes/assets/js/scroll-magic.min.js', array(), KADENCE_BLOCKS_VERSION, false ); - + wp_register_script( 'kadence-blocks-scroll-magic', KADENCE_BLOCKS_URL . 'includes/assets/js/scroll-magic.min.js', [], KADENCE_BLOCKS_VERSION, true ); + wp_register_script( 'kadence-blocks-progress', KADENCE_BLOCKS_URL . 'includes/assets/js/progressBar.min.js', [], KADENCE_BLOCKS_VERSION, true ); + wp_register_script( 'kadence-blocks-' . $this->block_name, KADENCE_BLOCKS_URL . 'includes/assets/js/kb-progress-bars.min.js', [ 'kadence-blocks-scroll-magic', 'kadence-blocks-progress' ], KADENCE_BLOCKS_VERSION, true ); } } diff --git a/src/assets/js/kb-progress-bars.js b/src/assets/js/kb-progress-bars.js new file mode 100644 index 000000000..3f9435625 --- /dev/null +++ b/src/assets/js/kb-progress-bars.js @@ -0,0 +1,194 @@ +/* global kadence_blocks_progress_bars */ +/* global ProgressBar */ +(function () { + 'use strict'; + const kadenceProgressBars = { + cache: {}, + scroller: {}, + items: JSON.parse(kadence_blocks_progress_bars.items), + windowResize() { + if (!kadenceProgressBars?.items) { + return; + } + Object.keys(kadenceProgressBars?.items).forEach(function (key) { + kadenceProgressBars.updateContainer(kadenceProgressBars.items[key]); + }); + }, + updateContainer(item) { + const barContainers = document.querySelectorAll('.kb-progress-bar-' + item.unique_id); + const barSvgs = []; + if (!barContainers?.length) { + return; + } + for (let n = 0; n < barContainers.length; n++) { + barSvgs[n] = barContainers[n].querySelector('svg'); + if (barSvgs?.[n]) { + kadenceProgressBars.updatePathSize(barSvgs[n], item); + } + } + }, + updatePathSize(barSvg, item) { + const barPaths = barSvg.querySelectorAll('path'); + const path1 = barPaths[0]; + const path2 = barPaths[1]; + if (window.innerWidth < 768) { + if (item.type === 'line') { + barSvg.setAttribute('viewBox', '0 0 100 ' + item.stokeWidths[2]); + path1.setAttribute('d', 'M 0,' + item.stokeWidths[2] / 2 + ' L 100,' + item.stokeWidths[2] / 2); + path2.setAttribute('d', 'M 0,' + item.stokeWidths[2] / 2 + ' L 100,' + item.stokeWidths[2] / 2); + } + path1.setAttribute('stroke-width', item.stokeWidths[2]); + path2.setAttribute('stroke-width', item.stokeWidths[2]); + } else if (window.innerWidth < 1025) { + if (item.type === 'line') { + barSvg.setAttribute('viewBox', '0 0 100 ' + item.stokeWidths[1]); + path1.setAttribute('d', 'M 0,' + item.stokeWidths[1] / 2 + ' L 100,' + item.stokeWidths[1] / 2); + path2.setAttribute('d', 'M 0,' + item.stokeWidths[1] / 2 + ' L 100,' + item.stokeWidths[1] / 2); + } + path1.setAttribute('stroke-width', item.stokeWidths[1]); + path2.setAttribute('stroke-width', item.stokeWidths[1]); + } else { + if (item.type === 'line') { + barSvg.setAttribute('viewBox', '0 0 100 ' + item.stokeWidths[0]); + path1.setAttribute('d', 'M 0,' + item.stokeWidths[0] / 2 + ' L 100,' + item.stokeWidths[0] / 2); + path2.setAttribute('d', 'M 0,' + item.stokeWidths[0] / 2 + ' L 100,' + item.stokeWidths[0] / 2); + } + path1.setAttribute('stroke-width', item.stokeWidths[0]); + path2.setAttribute('stroke-width', item.stokeWidths[0]); + } + }, + triggerAnimation(element, index, item) { + if (kadenceProgressBars.cache[item.simple_id][index]) { + const prefix = item?.prefix ? kadenceProgressBars.stripHtml(item.prefix) : ''; + const suffix = item?.suffix ? kadenceProgressBars.stripHtml(item.suffix) : ''; + kadenceProgressBars.cache[item.simple_id][index].animate(item.progress_real / item.progress_max, { + duration: item.duration * 1000, + step(state, bar) { + let value = 0; + const elementAbove = element.querySelector('.kb-current-progress-above'); + const elementInside = element.querySelector('.kb-current-progress-inside'); + const elementBelow = element.querySelector('.kb-current-progress-below'); + + //get current raw progress value + if (item.is_relative) { + value = bar.value() * 100; + } else { + value = bar.value() * item.progress_max; + } + + //format the value according to decimal points indicated in settings + if (item.decimal === 'one') { + value = Math.round(value * 10) / 10; + value = value.toFixed(1); + } else if (item.decimal === 'two') { + value = Math.round(value * 100) / 100; + value = value.toFixed(2); + } else { + value = Math.round(value); + } + + if (elementAbove) { + elementAbove.innerHTML = prefix + value + suffix; + } else if (elementInside) { + elementInside.innerHTML = prefix + value + suffix; + } else if (elementBelow) { + elementBelow.innerHTML = prefix + value + suffix; + } + }, + }); + } + }, + initSingleBarElement(element, index, item) { + let initialStroke; + if (window.innerWidth < 768) { + initialStroke = item.stokeWidths?.[2] ? item.stokeWidths[2] : 2; + } else if (window.innerWidth < 1025) { + initialStroke = item.stokeWidths?.[1] ? item.stokeWidths[1] : 2; + } else { + initialStroke = item.stokeWidths?.[0] ? item.stokeWidths[0] : 2; + } + const progressElement = element.querySelector('.kb-progress-bar'); + const args = { + color: item.progressColor, + trailColor: item.barBackground, + duration: item.duration * 1000, + easing: item.easing, + strokeWidth: initialStroke, + }; + if (!kadenceProgressBars.cache[item.simple_id]) { + kadenceProgressBars.cache[item.simple_id] = []; + } + switch (item.type) { + case 'circle': + kadenceProgressBars.cache[item.simple_id][index] = new ProgressBar.Circle(progressElement, args); + break; + case 'line': + kadenceProgressBars.cache[item.simple_id][index] = new ProgressBar.Line(progressElement, args); + break; + case 'semicircle': + kadenceProgressBars.cache[item.simple_id][index] = new ProgressBar.SemiCircle( + progressElement, + args + ); + break; + } + if (item.delay) { + if (!kadenceProgressBars.scroller[item.simple_id]) { + kadenceProgressBars.scroller[item.simple_id] = []; + } + kadenceProgressBars.scroller[item.simple_id][index] = new ScrollMagic.Controller(); + const desiredAnimation = new ScrollMagic.Scene({ triggerElement: element }); + desiredAnimation.triggerHook(0.88); + desiredAnimation.addTo(kadenceProgressBars.scroller[item.simple_id][index]); + desiredAnimation.on('start', function (e) { + kadenceProgressBars.triggerAnimation(element, index, item); + }); + } else { + kadenceProgressBars.triggerAnimation(element, index, item); + } + }, + initSingleBar(item) { + const barContainers = document.querySelectorAll('.kb-progress-bar-container' + item.unique_id); + if (!barContainers?.length) { + return; + } + for (let n = 0; n < barContainers.length; n++) { + kadenceProgressBars.initSingleBarElement(barContainers[n], n, item); + } + }, + stripHtml(html) { + const wrappedHtml = `
${html}
`; + const doc = new DOMParser().parseFromString(wrappedHtml, 'text/html'); + return doc.body.textContent || ''; + }, + initAll() { + if (!kadenceProgressBars?.items) { + return; + } + Object.keys(kadenceProgressBars?.items).forEach(function (key) { + kadenceProgressBars.initSingleBar(kadenceProgressBars.items[key]); + }); + }, + // Initiate the menus when the DOM loads. + init() { + if (typeof ProgressBar !== 'undefined') { + kadenceProgressBars.initAll(); + } else { + var initLoadDelay = setInterval(function () { + if (typeof ProgressBar !== 'undefined') { + kadenceProgressBars.initAll(); + clearInterval(initLoadDelay); + } + }, 200); + } + }, + }; + if ('loading' === document.readyState) { + // The DOM has not yet been loaded. + document.addEventListener('DOMContentLoaded', kadenceProgressBars.init); + } else { + // The DOM has already been loaded. + kadenceProgressBars.init(); + } + window.addEventListener('resize', kadenceProgressBars.windowResize, false); +})();