Skip to content

Instantly share code, notes, and snippets.

@damiencarbery
Last active December 1, 2021 23:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save damiencarbery/3a5e9bfd1df0333054471d8fd30b438d to your computer and use it in GitHub Desktop.
Save damiencarbery/3a5e9bfd1df0333054471d8fd30b438d to your computer and use it in GitHub Desktop.
Elementor - Percentage circle widget - An Elementor widget for a Percentage circle where the circle is complete to the specific percentage. https://www.damiencarbery.com/2021/06/elementor-percentage-circle-widget/
<?php
/*
Plugin Name: Elementor - Percentage circle widget
Description: An Elementor widget for a Percentage circle where the circle is complete to the specific percentage.
Plugin URI: https://www.damiencarbery.com/2021/06/percentage-circle-block-for-elementor/
Version: 0.1
Author: Damien Carbery
*/
use Elementor\Plugin;
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
// The Widget_Base class is not available immediately after plugins are loaded, so
// we delay the class use until Elementor widgets are registered.
add_action( 'elementor/widgets/widgets_registered', function() {
require_once('percentage-circle-widget.php');
$percent_circle_widget = new Percentage_Circle_Widget();
// Let Elementor know about our widget
Plugin::instance()->widgets_manager->register_widget_type( $percent_circle_widget );
});
.circular-chart { display: block; margin: 10px auto; max-width: 80%; max-width: 250px; max-height: 250px; }
.circle-bg { fill: none; stroke: #eee; stroke-width: 3.8; }
.circle { fill: none; stroke-width: 2.8; stroke-linecap: round; animation: progress 2s ease-out forwards; }
@keyframes progress { 0% { stroke-dasharray: 0 100; } }
.percentage { fill: #666; font-size: 0.5em; text-anchor: middle; }
<?php
defined( 'ABSPATH' ) || exit;
use Elementor\Widget_Base;
use Elementor\Controls_Manager;
// The code is based on tutorials at:
// https://www.soliddigital.com/blog/creating-a-custom-elementor-widget
// https://www.benmarshall.me/create-an-elementor-widget/
// https://github.com/bmarshall511/elementor-awesomesauce
// https://code.elementor.com/
class Percentage_Circle_Widget extends \Elementor\Widget_Base {
public function __construct( $data = array(), $args = null ) {
parent::__construct( $data, $args );
wp_register_style( 'percentage-circle', plugin_dir_url( __FILE__ ) . 'percentage-circle-widget.css', array(), null );
}
public function get_style_depends() {
return array( 'percentage-circle' );
}
public function get_name() {
return 'percent_circle';
}
public function get_title() {
return __( 'Percentage Circle', 'plugin-name' );
}
public function get_icon() {
return 'fa fa-spinner';
}
// Return the list of categories the oEmbed widget belongs to.
public function get_categories() {
return [ 'general' ];
}
// Add different input fields to allow the user to change and customize the widget settings.
protected function register_controls() {
$this->start_controls_section(
'percentage_circle_section',
[
'label' => __( 'Circle settings', 'plugin-name' ),
]
);
// See: https://developers.elementor.com/elementor-controls/number-control/
$this->add_control(
'percentage',
[
'label' => __( 'Percentage complete', 'plugin-name' ),
'type' => \Elementor\Controls_Manager::NUMBER,
'min' => 1,
'max' => 100,
'step' => 1,
'default' => 40,
]
);
// See: https://developers.elementor.com/elementor-controls/color-control/
$this->add_control(
'circle_colour',
[
'label' => __( 'Circle colour', 'plugin-domain' ),
'description' => __( 'Colour for the progress portion of the circle.', 'plugin-domain' ),
'type' => \Elementor\Controls_Manager::COLOR,
]
);
// See: https://developers.elementor.com/elementor-controls/text-control/
$this->add_control(
'inside_text',
[
'label' => __( 'Text', 'plugin-domain' ),
'description' => __( 'Very short amount of text to be displayed inside the circle. If not specified it will be the percentage with "%" appended.', 'plugin-domain' ),
'type' => \Elementor\Controls_Manager::TEXT,
'default' => __( 'Default title', 'plugin-domain' ),
'placeholder' => __( 'Type your title here', 'plugin-domain' ),
]
);
$this->end_controls_section();
}
// Render widget output on the frontend - generates the final HTML.
protected function render() {
$settings = $this->get_settings_for_display();
$inside_text = $settings['inside_text'];
// If no text specified then use percentage with %.
if ( empty( $inside_text ) ) {
$inside_text = $settings['percentage'] . '%';
}
//error_log( 'Render Settings: ' . var_export( $settings, true ) );
?>
<svg viewBox="0 0 36 36" class="circular-chart">
<path class="circle-bg"
d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831"
/>
<path class="circle" stroke="<?php echo $settings['circle_colour']; ?>"
stroke-dasharray="<?php echo $settings['percentage']; ?>, 100"
d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831"
/>
<text x="18" y="20.35" class="percentage"><?php echo $inside_text; ?></text>
</svg>
<?php
}
protected function _content_template() {
?>
<# var inside_text = settings.inside_text;
if (!settings.inside_text) { inside_text = settings.percentage + '%'; } #>
<svg viewBox="0 0 36 36" class="circular-chart">
<path class="circle-bg"
d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831"
/>
<path class="circle" stroke="{{{ settings.circle_colour}}}"
stroke-dasharray="{{{ settings.percentage}}}, 100"
d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831"
/>
<text x="18" y="20.35" class="percentage">{{{ inside_text }}}</text>
</svg>
<?php
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment