adobe / aem-core-wcm-components

Standardized components to build websites with AEM.
https://docs.adobe.com/content/help/en/experience-manager-core-components/using/introduction.html
Apache License 2.0
733 stars 741 forks source link

[Image] Image map not supported #35

Closed kwin closed 6 years ago

kwin commented 7 years ago

Although the inplace editor of the image component does allow to maintain an image map (https://github.com/Adobe-Marketing-Cloud/aem-core-wcm-components/blob/master/content/src/content/jcr_root/apps/core/wcm/components/image/v1/image/_cq_editConfig.xml#L69) this is not considered during rendering. I.e. the HTL script does not include any logic to include an image map (i.e. usemap attribute or map elements).

B3r commented 6 years ago

Hey there, just a thought, wouldn't it work with a sling model solution? If you enable imagemap support for the image component, edit an example image and add some example layers, you would get the following resource property: imagemap

Now you just need to split that String (caution, dirty ;-) ):

String[] areaStrings = StringUtils.split(imageMap, "][");
if (StringUtils.isNotBlank(imageMap)) { // [firstLayer][secondLayer][...]
for (String singleArea : areaStrings) { // [rect(12,12,92,63)"http://www.google.org"|"_self"|"Test"]
 String[] coordsAndLink = StringUtils.splitByWholeSeparatorPreserveAllTokens(singleArea, "\"", 2);
 String coords = StringUtils.substringBetween(coordsAndLink[0], "(", ")");
 String type = StringUtils.substringBefore(coordsAndLink[0], "(");
 String linkDetails = StringUtils.removeAll(coordsAndLink[1], "\"");
 String[] linkElements = StringUtils.split(linkDetails, "|");
 if (linkElements.length > 0 && StringUtils.isNotBlank(linkElements[0])) { // link is given
  String urlOrPath = linkElements[0];
  String target = linkElements.length > 1 ? linkElements[1] : "";
  String alt = linkElements.length > 2 ? linkElements[2] : "";
  LinkFactory fac = request.adaptTo(LinkFactory.class);
  Url url = null;
  try {
   if (StringUtils.startsWith(urlOrPath, "http://") || StringUtils.startsWith(urlOrPath, "https://")) {
    url = fac.createLink(urlOrPath).getUrl();
   } else {
    url = fac.createResourceUrl(urlOrPath);
   }
  } catch (MalformedURLException e) {
   e.printStackTrace();
  }

  if (url != null && url.isValid()) {
   areaList.add(new LinkArea(coords, url, target, alt, type));
  }
 }
}

And now for the HTL Part:

<img src="${image.src}" class="cmp-image__image img-responsive" data-cmp-hook-image="image"
             alt="${image.alt || true}" data-sly-attribute.usemap="${image.hasAreas ? resource.name : ''}"
             title="${image.displayPopupTitle && image.title}"/>
<sly data-sly-test="${image.hasAreas}">
 <usemap name="${resource.name}" data-sly-list.area="${image.areaList}">
  <area shape="${area.type}" target="${area.target}" coords="${area.coords}" href="${area.url.absoluteHref}" alt="${area.alt}">
 </usemap>
</sly>

Caution, not tested because of problems extending the ImageImpl class

raducotescu commented 6 years ago

@B3r, we've put the Image Map feature back on our roadmap, however it's not as simple as it looks with the Core Image component, given that the image that will get rendered is chosen by the client, depending on the width of the display container. Therefore you risk that a map defined on an author instance has totally different coordinates than the map would have on the final rendered image.

gabrielwalt commented 6 years ago

(CQ-4203499)