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>';
}