register_content_controls();
$this->register_variable_font_controls();
$this->register_magnetic_controls();
$this->register_reveal_controls();
$this->register_motion_controls();
$this->register_style_text_controls();
$this->register_style_effect_controls();
$this->register_style_preset_controls();
$this->register_pro_notice_controls();
}
public function render(): void
{
$settings = $this->get_settings_for_display();
$text = sanitize_textarea_field((string) ($settings['kng_text'] ?? ''));
if ($text === '') {
$text = esc_html__('Kinetic Text Hover', 'king-addons');
}
$tag = $this->sanitize_html_tag($settings['kng_html_tag'] ?? 'h2');
$preset = $settings['kng_preset'] ?? 'split-underline';
$trigger = $settings['kng_trigger'] ?? 'hover';
$mobile_behavior = $settings['kng_mobile_behavior'] ?? 'disable';
$gradient_enabled = ($settings['kng_gradient_text_enable'] ?? '') === 'yes';
if (!$this->can_use_pro() && $trigger === 'idle') {
$trigger = 'hover';
}
$classes = [
'king-addons-kinetic-text-hover',
'is-preset-' . $preset,
];
if ($gradient_enabled) {
$classes[] = 'is-gradient-text';
}
$mask_direction = $settings['kng_mask_direction'] ?? 'left';
if ($preset === 'mask-reveal') {
$classes[] = 'is-mask-' . $mask_direction;
}
$link = is_array($settings['kng_link'] ?? null) ? $settings['kng_link'] : [];
$has_link = !empty($link['url']);
if ($has_link) {
$classes[] = 'is-link';
}
$can_pro = $this->can_use_pro();
$options = [
'preset' => $preset,
'trigger' => $trigger,
'mobileBehavior' => $mobile_behavior,
'intensity' => (int) ($this->get_slider_size($settings, 'kng_effect_intensity', 35)),
'letterDrift' => [
'max' => (float) $this->get_slider_size($settings, 'kng_letter_drift_max', 10),
'randomness' => (float) $this->get_slider_size($settings, 'kng_letter_drift_randomness', 40),
],
'magnetic' => [
'enabled' => $can_pro && (($settings['kng_magnetic_enable'] ?? '') === 'yes'),
'strength' => (float) ($settings['kng_magnetic_strength']['size'] ?? 35),
'radius' => (float) ($settings['kng_magnetic_radius']['size'] ?? 140),
'maxOffset' => (float) ($settings['kng_magnetic_max_offset']['size'] ?? 14),
'smoothing' => (float) ($settings['kng_magnetic_smoothing'] ?? 0.35),
'clamp' => $settings['kng_magnetic_clamp'] ?? 'soft',
'disableMobile' => ($settings['kng_magnetic_disable_mobile'] ?? '') === 'yes',
],
'variableFont' => [
'enabled' => $can_pro && (($settings['kng_varfont_enable'] ?? '') === 'yes'),
'wghtMin' => (float) ($settings['kng_varfont_wght_min'] ?? 400),
'wghtMax' => (float) ($settings['kng_varfont_wght_max'] ?? 700),
'wdthMin' => (float) ($settings['kng_varfont_wdth_min'] ?? 100),
'wdthMax' => (float) ($settings['kng_varfont_wdth_max'] ?? 110),
'widthSafe' => ($settings['kng_varfont_width_safe'] ?? '') === 'yes',
],
'reveal' => [
'enabled' => $can_pro && (($settings['kng_reveal_enable'] ?? '') === 'yes'),
'type' => $settings['kng_reveal_type'] ?? 'fade',
'threshold' => (float) ($settings['kng_reveal_threshold'] ?? 0.2),
'once' => ($settings['kng_reveal_once'] ?? '') === 'yes',
],
'reducedMotion' => [
'respect' => $can_pro && (($settings['kng_motion_respect'] ?? '') === 'yes'),
'mode' => $settings['kng_motion_mode'] ?? 'simplify',
],
'editorPreview' => $this->is_editor_mode(),
];
if ($options['reveal']['enabled']) {
$classes[] = 'has-reveal';
$classes[] = 'reveal-' . $options['reveal']['type'];
}
$this->add_render_attribute('wrapper', [
'class' => $classes,
'data-options' => wp_json_encode($options),
'data-trigger' => $trigger,
'data-mobile' => $mobile_behavior,
]);
echo '<' . esc_attr($tag) . ' ' . $this->get_render_attribute_string('wrapper') . '>';
if ($has_link) {
$this->add_render_attribute('link', 'class', 'king-addons-kinetic-text-hover__link');
$this->add_render_attribute('link', 'href', esc_url($link['url']));
if (!empty($link['is_external'])) {
$this->add_render_attribute('link', 'target', '_blank');
}
$rel = [];
if (!empty($link['nofollow'])) {
$rel[] = 'nofollow';
}
if (!empty($link['is_external'])) {
$rel[] = 'noopener';
$rel[] = 'noreferrer';
}
if ($rel) {
$this->add_render_attribute('link', 'rel', implode(' ', array_unique($rel)));
}
echo 'get_render_attribute_string('link') . '>';
}
echo '';
echo '' . esc_html($text) . '';
echo '' . esc_html($text) . '';
echo '';
if ($has_link) {
echo '';
}
echo '' . esc_attr($tag) . '>';
}
protected function register_content_controls(): void
{
$this->start_controls_section(
'kng_content_section',
[
'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Content', 'king-addons'),
'tab' => Controls_Manager::TAB_CONTENT,
]
);
$this->add_control(
'kng_text',
[
'label' => esc_html__('Text', 'king-addons'),
'type' => Controls_Manager::TEXTAREA,
'default' => esc_html__('Kinetic Text Hover', 'king-addons'),
'label_block' => true,
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'kng_html_tag',
[
'label' => esc_html__('HTML Tag', 'king-addons'),
'type' => Controls_Manager::SELECT,
'default' => 'h2',
'options' => [
'h1' => 'H1',
'h2' => 'H2',
'h3' => 'H3',
'h4' => 'H4',
'h5' => 'H5',
'h6' => 'H6',
'div' => 'DIV',
'span' => 'SPAN',
'p' => 'P',
],
]
);
$this->add_control(
'kng_link',
[
'label' => esc_html__('Link', 'king-addons'),
'type' => Controls_Manager::URL,
'placeholder' => esc_html__('https://your-link.com', 'king-addons'),
'default' => [
'url' => '',
],
]
);
$this->add_control(
'kng_preset',
[
'label' => esc_html__('Preset', 'king-addons'),
'type' => Controls_Manager::SELECT,
'default' => 'split-underline',
'options' => [
'split-underline' => esc_html__('Split Underline', 'king-addons'),
'glow-stroke' => esc_html__('Glow Stroke', 'king-addons'),
'chroma-shift' => esc_html__('Chroma Shift', 'king-addons'),
'letter-drift' => esc_html__('Letter Drift', 'king-addons'),
'sheen-sweep' => esc_html__('Sheen Sweep', 'king-addons'),
'mask-reveal' => esc_html__('Mask Reveal', 'king-addons'),
],
]
);
$trigger_options = [
'hover' => esc_html__('Hover', 'king-addons'),
'hover-move' => esc_html__('Hover + Cursor Move', 'king-addons'),
];
if ($this->can_use_pro()) {
$trigger_options['idle'] = esc_html__('Always On (Idle)', 'king-addons');
} else {
$trigger_options['idle'] = $this->get_pro_label(esc_html__('Always On (Idle)', 'king-addons'));
}
$this->add_control(
'kng_trigger',
[
'label' => esc_html__('Trigger', 'king-addons'),
'type' => Controls_Manager::SELECT,
'default' => 'hover',
'options' => $trigger_options,
]
);
$this->add_control(
'kng_mobile_behavior',
[
'label' => esc_html__('Mobile Behavior', 'king-addons'),
'type' => Controls_Manager::SELECT,
'default' => 'disable',
'options' => [
'disable' => esc_html__('Disable Effects', 'king-addons'),
'tap' => esc_html__('Tap to Activate', 'king-addons'),
],
]
);
$this->end_controls_section();
}
protected function register_variable_font_controls(): void
{
$this->start_controls_section(
'kng_varfont_section',
[
'label' => $this->get_pro_label(esc_html__('Variable Font Axes', 'king-addons')),
'tab' => Controls_Manager::TAB_CONTENT,
'classes' => $this->get_pro_control_class(),
]
);
$this->add_control(
'kng_varfont_enable',
[
'label' => $this->get_pro_label(esc_html__('Enable Variable Font', 'king-addons')),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
'default' => '',
'classes' => $this->get_pro_control_class(),
]
);
$this->add_control(
'kng_varfont_notice',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => esc_html__('Requires a variable font that supports wght/wdth axes.', 'king-addons'),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
'condition' => [
'kng_varfont_enable' => 'yes',
],
]
);
$this->add_control(
'kng_varfont_wght_min',
[
'label' => $this->get_pro_label(esc_html__('Weight Min (wght)', 'king-addons')),
'type' => Controls_Manager::NUMBER,
'default' => 400,
'min' => 100,
'max' => 900,
'step' => 1,
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_varfont_enable' => 'yes',
],
]
);
$this->add_control(
'kng_varfont_wght_max',
[
'label' => $this->get_pro_label(esc_html__('Weight Max (wght)', 'king-addons')),
'type' => Controls_Manager::NUMBER,
'default' => 700,
'min' => 100,
'max' => 900,
'step' => 1,
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_varfont_enable' => 'yes',
],
]
);
$this->add_control(
'kng_varfont_wdth_min',
[
'label' => $this->get_pro_label(esc_html__('Width Min (wdth)', 'king-addons')),
'type' => Controls_Manager::NUMBER,
'default' => 100,
'min' => 75,
'max' => 125,
'step' => 1,
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_varfont_enable' => 'yes',
],
]
);
$this->add_control(
'kng_varfont_wdth_max',
[
'label' => $this->get_pro_label(esc_html__('Width Max (wdth)', 'king-addons')),
'type' => Controls_Manager::NUMBER,
'default' => 110,
'min' => 75,
'max' => 125,
'step' => 1,
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_varfont_enable' => 'yes',
],
]
);
$this->add_control(
'kng_varfont_width_safe',
[
'label' => $this->get_pro_label(esc_html__('Use Width-Safe Mode', 'king-addons')),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
'default' => 'yes',
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_varfont_enable' => 'yes',
],
]
);
$this->end_controls_section();
}
protected function register_magnetic_controls(): void
{
$this->start_controls_section(
'kng_magnetic_section',
[
'label' => $this->get_pro_label(esc_html__('Magnetic Letters', 'king-addons')),
'tab' => Controls_Manager::TAB_CONTENT,
'classes' => $this->get_pro_control_class(),
]
);
$this->add_control(
'kng_magnetic_enable',
[
'label' => $this->get_pro_label(esc_html__('Enable Magnetic Letters', 'king-addons')),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
'default' => '',
'classes' => $this->get_pro_control_class(),
]
);
$this->add_control(
'kng_magnetic_strength',
[
'label' => $this->get_pro_label(esc_html__('Strength', 'king-addons')),
'type' => Controls_Manager::SLIDER,
'size_units' => ['%'],
'range' => [
'%' => [
'min' => 0,
'max' => 100,
],
],
'default' => [
'size' => 35,
'unit' => '%',
],
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_magnetic_enable' => 'yes',
],
]
);
$this->add_control(
'kng_magnetic_radius',
[
'label' => $this->get_pro_label(esc_html__('Radius', 'king-addons')),
'type' => Controls_Manager::SLIDER,
'size_units' => ['px'],
'range' => [
'px' => [
'min' => 40,
'max' => 320,
],
],
'default' => [
'size' => 140,
'unit' => 'px',
],
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_magnetic_enable' => 'yes',
],
]
);
$this->add_control(
'kng_magnetic_max_offset',
[
'label' => $this->get_pro_label(esc_html__('Max Offset', 'king-addons')),
'type' => Controls_Manager::SLIDER,
'size_units' => ['px'],
'range' => [
'px' => [
'min' => 0,
'max' => 30,
],
],
'default' => [
'size' => 14,
'unit' => 'px',
],
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_magnetic_enable' => 'yes',
],
]
);
$this->add_control(
'kng_magnetic_smoothing',
[
'label' => $this->get_pro_label(esc_html__('Smoothing', 'king-addons')),
'type' => Controls_Manager::NUMBER,
'default' => 0.35,
'min' => 0,
'max' => 1,
'step' => 0.05,
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_magnetic_enable' => 'yes',
],
]
);
$this->add_control(
'kng_magnetic_clamp',
[
'label' => $this->get_pro_label(esc_html__('Clamp Mode', 'king-addons')),
'type' => Controls_Manager::SELECT,
'default' => 'soft',
'options' => [
'none' => esc_html__('None', 'king-addons'),
'soft' => esc_html__('Soft', 'king-addons'),
'hard' => esc_html__('Hard', 'king-addons'),
],
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_magnetic_enable' => 'yes',
],
]
);
$this->add_control(
'kng_magnetic_disable_mobile',
[
'label' => $this->get_pro_label(esc_html__('Disable on Mobile', 'king-addons')),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
'default' => 'yes',
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_magnetic_enable' => 'yes',
],
]
);
$this->end_controls_section();
}
protected function register_reveal_controls(): void
{
$this->start_controls_section(
'kng_reveal_section',
[
'label' => $this->get_pro_label(esc_html__('Reveal on Scroll', 'king-addons')),
'tab' => Controls_Manager::TAB_CONTENT,
'classes' => $this->get_pro_control_class(),
]
);
$this->add_control(
'kng_reveal_enable',
[
'label' => $this->get_pro_label(esc_html__('Enable Reveal', 'king-addons')),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
'default' => '',
'classes' => $this->get_pro_control_class(),
]
);
$this->add_control(
'kng_reveal_type',
[
'label' => $this->get_pro_label(esc_html__('Reveal Type', 'king-addons')),
'type' => Controls_Manager::SELECT,
'default' => 'fade',
'options' => [
'fade' => esc_html__('Fade', 'king-addons'),
'slide' => esc_html__('Slide Up', 'king-addons'),
'clip' => esc_html__('Clip Reveal', 'king-addons'),
],
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_reveal_enable' => 'yes',
],
]
);
$this->add_control(
'kng_reveal_duration',
[
'label' => $this->get_pro_label(esc_html__('Duration', 'king-addons')),
'type' => Controls_Manager::SLIDER,
'size_units' => ['ms'],
'range' => [
'ms' => [
'min' => 100,
'max' => 2000,
],
],
'default' => [
'size' => 600,
'unit' => 'ms',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-reveal-duration: {{SIZE}}ms;',
],
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_reveal_enable' => 'yes',
],
]
);
$this->add_control(
'kng_reveal_delay',
[
'label' => $this->get_pro_label(esc_html__('Delay', 'king-addons')),
'type' => Controls_Manager::SLIDER,
'size_units' => ['ms'],
'range' => [
'ms' => [
'min' => 0,
'max' => 1000,
],
],
'default' => [
'size' => 0,
'unit' => 'ms',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-reveal-delay: {{SIZE}}ms;',
],
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_reveal_enable' => 'yes',
],
]
);
$this->add_control(
'kng_reveal_threshold',
[
'label' => $this->get_pro_label(esc_html__('Threshold', 'king-addons')),
'type' => Controls_Manager::NUMBER,
'default' => 0.2,
'min' => 0,
'max' => 1,
'step' => 0.05,
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_reveal_enable' => 'yes',
],
]
);
$this->add_control(
'kng_reveal_once',
[
'label' => $this->get_pro_label(esc_html__('Reveal Once', 'king-addons')),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
'default' => 'yes',
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_reveal_enable' => 'yes',
],
]
);
$this->end_controls_section();
}
protected function register_motion_controls(): void
{
$this->start_controls_section(
'kng_motion_section',
[
'label' => $this->get_pro_label(esc_html__('Reduced Motion', 'king-addons')),
'tab' => Controls_Manager::TAB_CONTENT,
'classes' => $this->get_pro_control_class(),
]
);
$this->add_control(
'kng_motion_respect',
[
'label' => $this->get_pro_label(esc_html__('Respect Reduced Motion', 'king-addons')),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
'default' => 'yes',
'classes' => $this->get_pro_control_class(),
]
);
$this->add_control(
'kng_motion_mode',
[
'label' => $this->get_pro_label(esc_html__('Mode', 'king-addons')),
'type' => Controls_Manager::SELECT,
'default' => 'simplify',
'options' => [
'disable' => esc_html__('Disable Animations', 'king-addons'),
'simplify' => esc_html__('Simplify Effects', 'king-addons'),
],
'classes' => $this->get_pro_control_class(),
'condition' => [
'kng_motion_respect' => 'yes',
],
]
);
$this->end_controls_section();
}
protected function register_style_text_controls(): void
{
$this->start_controls_section(
'kng_style_text_section',
[
'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Typography', 'king-addons'),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'kng_text_typography',
'selector' => '{{WRAPPER}} .king-addons-kinetic-text-hover__visual',
]
);
$this->add_responsive_control(
'kng_text_align',
[
'label' => esc_html__('Alignment', 'king-addons'),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => esc_html__('Left', 'king-addons'),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__('Center', 'king-addons'),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => esc_html__('Right', 'king-addons'),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'{{WRAPPER}}' => 'text-align: {{VALUE}};',
],
]
);
$this->add_control(
'kng_text_color',
[
'label' => esc_html__('Text Color', 'king-addons'),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-color: {{VALUE}};',
],
]
);
$this->add_control(
'kng_text_hover_color',
[
'label' => esc_html__('Hover Color', 'king-addons'),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-hover-color: {{VALUE}};',
],
]
);
$this->add_control(
'kng_text_stroke_color',
[
'label' => esc_html__('Stroke Color', 'king-addons'),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-stroke-color: {{VALUE}};',
],
]
);
$this->add_control(
'kng_gradient_text_enable',
[
'label' => esc_html__('Gradient Text', 'king-addons'),
'type' => Controls_Manager::SWITCHER,
'return_value' => 'yes',
'default' => '',
'separator' => 'before',
]
);
$this->add_group_control(
Group_Control_Background::get_type(),
[
'name' => 'kng_text_gradient',
'types' => ['gradient'],
'selector' => '{{WRAPPER}} .king-addons-kinetic-text-hover__visual',
'condition' => [
'kng_gradient_text_enable' => 'yes',
],
]
);
$this->add_group_control(
Group_Control_Background::get_type(),
[
'name' => 'kng_text_background',
'types' => ['classic', 'gradient'],
'selector' => '{{WRAPPER}} .king-addons-kinetic-text-hover__inner',
]
);
$this->add_responsive_control(
'kng_container_padding',
[
'label' => esc_html__('Padding', 'king-addons'),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => ['px', 'em', '%'],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover__inner' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'separator' => 'before',
]
);
$this->add_control(
'kng_letter_spacing_hover',
[
'label' => esc_html__('Letter Spacing on Hover', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['px', 'em'],
'range' => [
'px' => [
'min' => -5,
'max' => 20,
],
'em' => [
'min' => -0.2,
'max' => 1,
'step' => 0.01,
],
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-letter-spacing-hover: {{SIZE}}{{UNIT}};',
],
]
);
$this->end_controls_section();
}
protected function register_style_effect_controls(): void
{
$this->start_controls_section(
'kng_style_effects_section',
[
'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Effects', 'king-addons'),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'kng_effect_intensity',
[
'label' => esc_html__('Intensity', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['%'],
'range' => [
'%' => [
'min' => 0,
'max' => 100,
],
],
'default' => [
'size' => 35,
'unit' => '%',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-intensity: calc({{SIZE}} / 100);',
],
]
);
$this->add_control(
'kng_effect_speed',
[
'label' => esc_html__('Speed', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['ms'],
'range' => [
'ms' => [
'min' => 100,
'max' => 2000,
],
],
'default' => [
'size' => 420,
'unit' => 'ms',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-speed: {{SIZE}}ms;',
],
]
);
$this->add_control(
'kng_effect_easing',
[
'label' => esc_html__('Easing', 'king-addons'),
'type' => Controls_Manager::SELECT,
'default' => 'ease',
'options' => [
'ease' => esc_html__('Ease', 'king-addons'),
'linear' => esc_html__('Linear', 'king-addons'),
'ease-in' => esc_html__('Ease In', 'king-addons'),
'ease-out' => esc_html__('Ease Out', 'king-addons'),
'ease-in-out' => esc_html__('Ease In Out', 'king-addons'),
'cubic-bezier(0.4, 0, 0.2, 1)' => esc_html__('Cubic', 'king-addons'),
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-ease: {{VALUE}};',
],
]
);
$this->add_control(
'kng_effect_out_duration',
[
'label' => esc_html__('Hover Out Duration', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['ms'],
'range' => [
'ms' => [
'min' => 0,
'max' => 2000,
],
],
'default' => [
'size' => 320,
'unit' => 'ms',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-out-speed: {{SIZE}}ms;',
],
]
);
$this->end_controls_section();
}
protected function register_style_preset_controls(): void
{
$this->start_controls_section(
'kng_style_underline_section',
[
'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Split Underline', 'king-addons'),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'kng_preset' => 'split-underline',
],
]
);
$this->add_control(
'kng_underline_thickness',
[
'label' => esc_html__('Thickness', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['px'],
'range' => [
'px' => [
'min' => 1,
'max' => 8,
],
],
'default' => [
'size' => 2,
'unit' => 'px',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-underline-thickness: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'kng_underline_offset',
[
'label' => esc_html__('Offset', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['px'],
'range' => [
'px' => [
'min' => 0,
'max' => 20,
],
],
'default' => [
'size' => 6,
'unit' => 'px',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-underline-offset: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'kng_underline_radius',
[
'label' => esc_html__('Radius', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['px'],
'range' => [
'px' => [
'min' => 0,
'max' => 20,
],
],
'default' => [
'size' => 4,
'unit' => 'px',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-underline-radius: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'kng_underline_color',
[
'label' => esc_html__('Underline Color', 'king-addons'),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-underline-color: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'kng_style_glow_section',
[
'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Glow Stroke', 'king-addons'),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'kng_preset' => 'glow-stroke',
],
]
);
$this->add_control(
'kng_stroke_width',
[
'label' => esc_html__('Stroke Width', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['px'],
'range' => [
'px' => [
'min' => 0,
'max' => 3,
],
],
'default' => [
'size' => 1,
'unit' => 'px',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-stroke-width: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'kng_glow_blur',
[
'label' => esc_html__('Glow Blur', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['px'],
'range' => [
'px' => [
'min' => 0,
'max' => 30,
],
],
'default' => [
'size' => 12,
'unit' => 'px',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-glow-blur: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'kng_glow_intensity',
[
'label' => esc_html__('Glow Intensity', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['%'],
'range' => [
'%' => [
'min' => 0,
'max' => 100,
],
],
'default' => [
'size' => 50,
'unit' => '%',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-glow-intensity: calc({{SIZE}} / 100);',
],
]
);
$this->add_control(
'kng_glow_color',
[
'label' => esc_html__('Glow Color', 'king-addons'),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-glow-color: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'kng_style_chroma_section',
[
'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Chroma Shift', 'king-addons'),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'kng_preset' => 'chroma-shift',
],
]
);
$this->add_control(
'kng_chroma_distance',
[
'label' => esc_html__('Chroma Distance', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['px'],
'range' => [
'px' => [
'min' => 0,
'max' => 12,
],
],
'default' => [
'size' => 5,
'unit' => 'px',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-chroma-distance: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'kng_chroma_opacity',
[
'label' => esc_html__('Chroma Opacity', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['%'],
'range' => [
'%' => [
'min' => 0,
'max' => 100,
],
],
'default' => [
'size' => 40,
'unit' => '%',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-chroma-opacity: calc({{SIZE}} / 100);',
],
]
);
$this->add_control(
'kng_chroma_color_1',
[
'label' => esc_html__('Left Color', 'king-addons'),
'type' => Controls_Manager::COLOR,
'default' => 'rgba(255, 0, 96, 0.4)',
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-chroma-color-1: {{VALUE}};',
],
]
);
$this->add_control(
'kng_chroma_color_2',
[
'label' => esc_html__('Right Color', 'king-addons'),
'type' => Controls_Manager::COLOR,
'default' => 'rgba(0, 209, 255, 0.4)',
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-chroma-color-2: {{VALUE}};',
],
]
);
$this->add_control(
'kng_chroma_color_3',
[
'label' => esc_html__('Bottom Color', 'king-addons'),
'type' => Controls_Manager::COLOR,
'default' => 'rgba(140, 0, 255, 0.4)',
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-chroma-color-3: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'kng_style_drift_section',
[
'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Letter Drift', 'king-addons'),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'kng_preset' => 'letter-drift',
],
]
);
$this->add_control(
'kng_letter_drift_max',
[
'label' => esc_html__('Max Translate', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['px'],
'range' => [
'px' => [
'min' => 0,
'max' => 30,
],
],
'default' => [
'size' => 10,
'unit' => 'px',
],
]
);
$this->add_control(
'kng_letter_drift_randomness',
[
'label' => esc_html__('Randomness', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['%'],
'range' => [
'%' => [
'min' => 0,
'max' => 100,
],
],
'default' => [
'size' => 40,
'unit' => '%',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'kng_style_sheen_section',
[
'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Sheen Sweep', 'king-addons'),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'kng_preset' => 'sheen-sweep',
],
]
);
$this->add_control(
'kng_sheen_angle',
[
'label' => esc_html__('Angle', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['deg'],
'range' => [
'deg' => [
'min' => 0,
'max' => 180,
],
],
'default' => [
'size' => 120,
'unit' => 'deg',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-sheen-angle: {{SIZE}}deg;',
],
]
);
$this->add_control(
'kng_sheen_duration',
[
'label' => esc_html__('Sweep Duration', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['ms'],
'range' => [
'ms' => [
'min' => 200,
'max' => 3000,
],
],
'default' => [
'size' => 1400,
'unit' => 'ms',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-sheen-duration: {{SIZE}}ms;',
],
]
);
$this->add_control(
'kng_sheen_brightness',
[
'label' => esc_html__('Brightness', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['%'],
'range' => [
'%' => [
'min' => 0,
'max' => 100,
],
],
'default' => [
'size' => 65,
'unit' => '%',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-sheen-brightness: calc({{SIZE}} / 100);',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'kng_style_mask_section',
[
'label' => KING_ADDONS_ELEMENTOR_ICON . esc_html__('Mask Reveal', 'king-addons'),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'kng_preset' => 'mask-reveal',
],
]
);
$this->add_control(
'kng_mask_direction',
[
'label' => esc_html__('Reveal Direction', 'king-addons'),
'type' => Controls_Manager::SELECT,
'default' => 'left',
'options' => [
'left' => esc_html__('Left to Right', 'king-addons'),
'right' => esc_html__('Right to Left', 'king-addons'),
'up' => esc_html__('Bottom to Top', 'king-addons'),
'down' => esc_html__('Top to Bottom', 'king-addons'),
],
]
);
$this->add_control(
'kng_mask_softness',
[
'label' => esc_html__('Edge Softness', 'king-addons'),
'type' => Controls_Manager::SLIDER,
'size_units' => ['%'],
'range' => [
'%' => [
'min' => 0,
'max' => 40,
],
],
'default' => [
'size' => 12,
'unit' => '%',
],
'selectors' => [
'{{WRAPPER}} .king-addons-kinetic-text-hover' => '--kng-kt-mask-softness: {{SIZE}}%;',
],
]
);
$this->end_controls_section();
}
public function register_pro_notice_controls(): void
{
if (!$this->can_use_pro()) {
Core::renderProFeaturesSection($this, '', Controls_Manager::RAW_HTML, 'kinetic-text-hover', [
'Variable font axes animation (wght/wdth)',
'Magnetic letters on cursor movement',
'Reveal on scroll effects',
'Reduced motion modes and overrides',
'Always-on idle animation trigger',
]);
}
}
protected function sanitize_html_tag(string $tag): string
{
$allowed = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'span', 'p'];
$tag = strtolower(trim($tag));
return in_array($tag, $allowed, true) ? $tag : 'div';
}
protected function get_slider_size(array $settings, string $key, float $default = 0): float
{
if (isset($settings[$key]['size'])) {
return (float) $settings[$key]['size'];
}
return $default;
}
protected function is_editor_mode(): bool
{
return class_exists(\Elementor\Plugin::class) && \Elementor\Plugin::$instance->editor->is_edit_mode();
}
protected function can_use_pro(): bool
{
return function_exists('king_addons_can_use_pro') && king_addons_can_use_pro();
}
protected function get_pro_label(string $label): string
{
if ($this->can_use_pro()) {
return $label;
}
return $label . ' ';
}
protected function get_pro_control_class(string $extra = ''): string
{
if ($this->can_use_pro()) {
return $extra;
}
return trim('king-addons-pro-control ' . $extra);
}
}