Image Hotspot

An interactive image field where editors upload an image and click to place named hotspot pins at any position. Each pin stores a label, description, optional link, and — depending on pin style — a Font Awesome icon. Coordinates are stored as percentages so hotspots remain responsive at any image size.

Pro field

Image Hotspot requires the Extra Fields for ACF Pro license.

Settings

SettingDefaultOptionsDescription
Pin Styledotdot · pin · numbered · iconVisual appearance of placed pins. icon requires a Font Awesome class per pin.
Max Hotspots0IntegerMaximum pins allowed. 0 = unlimited.
Description Typeplainplain · richrich enables a TinyMCE editor for formatted pin descriptions.

Return values

Returns an associative array with an image_id and a hotspots array.

$hotspot = get_field('product_diagram');
// [
//   'image_id' => 456,
//   'hotspots' => [
//     [
//       'x'           => 45.5,   // % from left
//       'y'           => 32.1,   // % from top
//       'label'       => 'Power button',
//       'description' => 'Hold for 3 seconds to power on.',
//       'link'        => 'https://example.com/docs/power',
//       'icon'        => 'fas fa-power-off',
//     ],
//     ...
//   ],
// ]

Usage

Rendering a responsive hotspot image

$data = get_field('diagram');

if ($data && !empty($data['image_id'])) {
    $img_url = wp_get_attachment_image_url($data['image_id'], 'large');

    echo '<div class="hotspot-wrap" style="position: relative; display: inline-block;">';
    echo '<img src="' . esc_url($img_url) . '" style="width: 100%; display: block;">';

    foreach ($data['hotspots'] as $pin) {
        printf(
            '<button class="hotspot-pin" style="position: absolute; left: %s%%; top: %s%%;" aria-label="%s" data-description="%s">',
            esc_attr(round($pin['x'], 2)),
            esc_attr(round($pin['y'], 2)),
            esc_attr($pin['label']),
            esc_attr($pin['description'])
        );
        echo '<span class="pin-dot"></span>';
        echo '</button>';
    }

    echo '</div>';
}

Building a hotspot list alongside the image

$data = get_field('feature_diagram');

if ($data) {
    echo '<div class="diagram-layout">';

    // Image
    echo '<div class="diagram-image">';
    echo wp_get_attachment_image($data['image_id'], 'full');
    echo '</div>';

    // Numbered list
    echo '<ol class="diagram-pins">';
    foreach ($data['hotspots'] as $i => $pin) {
        echo '<li>';
        echo '<strong>' . esc_html($pin['label']) . '</strong>';
        if ($pin['description']) {
            echo '<p>' . wp_kses_post($pin['description']) . '</p>';
        }
        if ($pin['link']) {
            echo '<a href="' . esc_url($pin['link']) . '">Learn more</a>';
        }
        echo '</li>';
    }
    echo '</ol>';

    echo '</div>';
}