{"id":3299,"date":"2026-09-01T06:23:58","date_gmt":"2026-09-01T06:23:58","guid":{"rendered":"https:\/\/new.parcodelpiano.ch\/experiences-and-itineraries\/cycling-route\/"},"modified":"2026-09-28T14:09:34","modified_gmt":"2026-09-28T14:09:34","slug":"cycling-route","status":"publish","type":"page","link":"https:\/\/new.parcodelpiano.ch\/en\/experiences-and-itineraries\/cycling-route\/","title":{"rendered":"Cycling Route"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"3299\" class=\"elementor elementor-3299 elementor-1281\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-24b3431 e-con-full e-flex e-con e-parent\" data-id=\"24b3431\" data-element_type=\"container\" data-e-type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t<div class=\"elementor-element elementor-element-3577a6c e-flex e-con-boxed e-con e-child\" data-id=\"3577a6c\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-9e76c24 e-con-full e-flex e-con e-child\" data-id=\"9e76c24\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-c9c9cb7 elementor-widget elementor-widget-heading\" data-id=\"c9c9cb7\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\"><a href=\"https:\/\/new.parcodelpiano.ch\/en\/experiences-and-itineraries\/\">Experiences<\/a><\/h3>\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-eb45e0e elementor-widget elementor-widget-heading\" data-id=\"eb45e0e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h3 class=\"elementor-heading-title elementor-size-default\">Cycling Route<\/h3>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-56d0387 elementor-widget elementor-widget-heading\" data-id=\"56d0387\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Saddle up for freedom, <br \/>to the rhythm of nature<\/h2>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-ec55a63 e-flex e-con-boxed e-con e-parent\" data-id=\"ec55a63\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-92ff903 elementor-widget elementor-widget-text-editor\" data-id=\"92ff903\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t\t\t\t\t\t<p>The Park area is an ideal space for recreation as it is flat, expansive, and close to residential areas. It is easily accessible by bicycle. Following the cycling path, you can admire the Park&#8217;s natural and agricultural beauty over approximately 9 km. The embankment path mainly runs alongside a side canal of the Ticino River, and while cycling, you will pass by Ciossa Antognini, the tree-lined avenue, the Demanio pond with its observatory, the Vigna Lunga Trebbione biotope, as well as several farm shops selling directly from the Park&#8217;s producers. What are you waiting for? Hop on your bike and come discover the natural beauty of the Parco del Piano di Magadino!    <\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-b4c3ef3 e-con-full e-flex e-con e-parent\" data-id=\"b4c3ef3\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-91009ba elementor-widget elementor-widget-html\" data-id=\"91009ba\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<div class=\"mappa-interattiva-wrapper\">\n\n  <!-- Intestazione: Titolo + Bottoni Tondi -->\n  <div class=\"map-header\">\n    <div id=\"map-title\" class=\"map-dynamic-title\">SELECT A ROUTE<\/div>\n    \n    <div class=\"map-controls\">\n      <!-- Home -->\n      <button class=\"btn-map active btn-home\" id=\"btn-all\" onclick=\"toggleRoute('all', 'SELEZIONA UN PERCORSO')\" title=\"Show all routes\">\n        <img decoding=\"async\" src=\"https:\/\/new.parcodelpiano.ch\/wp-content\/uploads\/2026\/09\/reset.svg\" alt=\"Home\">\n      <\/button>\n\n      <!-- Giallo: Pista d'argine -->\n      <button class=\"btn-map inactive btn-giallo\" id=\"btn-argine\" onclick=\"toggleRoute('argine', 'Pista d'argine')\" title=\"Embankment path\">\n        <img decoding=\"async\" src=\"https:\/\/new.parcodelpiano.ch\/wp-content\/uploads\/2026\/09\/pista_argine.svg\" alt=\"Embankment path\">\n      <\/button>\n\n      <!-- Rosso: Rete ciclabile -->\n      <button class=\"btn-map inactive btn-rosso\" id=\"btn-rete\" onclick=\"toggleRoute('rete', 'Rete ciclabile regionale 31')\" title=\"Regional cycling network 31\">\n        <img decoding=\"async\" src=\"https:\/\/new.parcodelpiano.ch\/wp-content\/uploads\/2026\/09\/rete_ciclabile.svg\" alt=\"Regional cycling network 31\">\n      <\/button>\n\n      <!-- Viola: Francisca -->\n      <button class=\"btn-map inactive btn-viola\" id=\"btn-francisca\" onclick=\"toggleRoute('francisca', 'Via Francisca del Lucomagno')\" title=\"Via Francisca del Lucomagno\">\n        <img decoding=\"async\" src=\"https:\/\/new.parcodelpiano.ch\/wp-content\/uploads\/2026\/09\/francisca_bici.svg\" alt=\"Via Francisca del Lucomagno\">\n      <\/button>\n    <\/div>\n  <\/div>\n\n  <!-- Viewport Mappa -->\n  <div id=\"map-viewport-1\" class=\"map-viewport\">\n    <div id=\"map-stage-1\" class=\"map-stage\">\n      <img decoding=\"async\" src=\"https:\/\/new.parcodelpiano.ch\/wp-content\/uploads\/2026\/09\/PPM_fondo.svg\" class=\"map-layer layer-fondo\" alt=\"Background Map\">\n      <img decoding=\"async\" id=\"layer-rete\" src=\"https:\/\/new.parcodelpiano.ch\/wp-content\/uploads\/2026\/09\/PPM_bici_rete_ciclabile.svg\" class=\"map-layer layer-route active\" alt=\"Cycling Network\">\n      <img decoding=\"async\" id=\"layer-francisca\" src=\"https:\/\/new.parcodelpiano.ch\/wp-content\/uploads\/2026\/09\/PPM_francisca_bici.svg\" class=\"map-layer layer-route active\" alt=\"Francisca Route\">\n      <img decoding=\"async\" id=\"layer-argine\" src=\"https:\/\/new.parcodelpiano.ch\/wp-content\/uploads\/2026\/09\/PPM_bici_argine.svg\" class=\"map-layer layer-route active\" alt=\"Embankment Path\">\n    <\/div>\n\n    <!-- Overlay Google Maps (solo mobile) -->\n    <div id=\"map-gesture-overlay-1\" class=\"map-gesture-overlay\">\n      <span id=\"overlay-text-1\">Use two fingers to move the map<\/span>\n    <\/div>\n  <\/div>\n\n<\/div>\n\n<style>\n.mappa-interattiva-wrapper {\n  position: relative;\n  width: 100%;\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  background-color: #ffffff;\n}\n\n.map-header {\n  display: flex;\n  flex-direction: column;\n  align-items: center;\n  justify-content: center;\n  padding: 15px 10px;\n  width: 100%;\n  z-index: 10;\n  background: #ffffff;\n}\n\n.map-dynamic-title {\n  font-family: var(--e-global-typography-bottoni-font-family, sans-serif) !important;\n  font-weight: var(--e-global-typography-bottoni-font-weight, bold) !important;\n  text-transform: var(--e-global-typography-bottoni-text-transform, uppercase) !important;\n  font-size: 16px;\n  letter-spacing: 1px;\n  color: #222222;\n  margin-bottom: 12px;\n  text-align: center;\n}\n\n.map-controls {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  gap: 16px;\n}\n\n.btn-map {\n  border: none !important;\n  border-radius: 50% !important;\n  width: 55px !important;\n  height: 55px !important;\n  min-width: 55px !important;\n  min-height: 55px !important;\n  display: flex !important;\n  align-items: center !important;\n  justify-content: center !important;\n  cursor: pointer !important;\n  padding: 0 !important;\n  box-shadow: none !important;\n  transition: transform 0.2s ease, opacity 0.3s ease !important;\n}\n\n.btn-home { background-color: #434343 !important; }\n.btn-giallo { background-color: #FFF29D !important; }\n.btn-rosso { background-color: #F89B9B !important; }\n.btn-viola { background-color: #9C99C7 !important; }\n\n.btn-map img {\n  width: 100% !important;\n  height: 100% !important;\n  object-fit: contain !important;\n  pointer-events: none;\n}\n\n.btn-map.active { opacity: 1 !important; transform: scale(1.05); }\n.btn-map.inactive { opacity: 0.35 !important; }\n.btn-map:hover { opacity: 0.85 !important; }\n\n.map-viewport {\n  width: 100%;\n  height: 80vh;\n  overflow: hidden;\n  position: relative;\n  background-color: #e5e5e5;\n  cursor: grab;\n  touch-action: pan-y;\n  user-select: none;\n}\n\n.map-viewport:active { cursor: grabbing; }\n\n.map-gesture-overlay {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  background: rgba(0, 0, 0, 0.55);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: #ffffff;\n  font-family: var(--e-global-typography-bottoni-font-family, sans-serif);\n  font-size: 15px;\n  font-weight: bold;\n  text-align: center;\n  padding: 20px;\n  opacity: 0;\n  pointer-events: none;\n  transition: opacity 0.3s ease;\n  z-index: 20;\n}\n\n.map-gesture-overlay.show { opacity: 1; }\n\n.map-stage {\n  position: absolute;\n  top: 0;\n  left: 0;\n  height: 100%;\n  aspect-ratio: 2048 \/ 985;\n  transform-origin: 0 0;\n  will-change: transform;\n}\n\n.map-layer {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  pointer-events: none;\n  transition: opacity 0.3s ease;\n  image-rendering: -webkit-optimize-contrast;\n  image-rendering: crisp-edges;\n}\n\n.layer-route { opacity: 0; z-index: 2; }\n.layer-route.active { opacity: 1; }\n.layer-fondo { z-index: 1; }\n\n@media (max-width: 768px) {\n  .map-viewport { height: 70vh; }\n  .btn-map { width: 44px !important; height: 44px !important; min-width: 44px !important; min-height: 44px !important; }\n}\n<\/style>\n\n<script>\ndocument.addEventListener(\"DOMContentLoaded\", function() {\n  const viewport = document.getElementById('map-viewport-1');\n  const stage = document.getElementById('map-stage-1');\n  const overlay = document.getElementById('map-gesture-overlay-1');\n  const overlayText = document.getElementById('overlay-text-1');\n\n  let scale = 1;\n  const maxScale = 2;\n\n  let currentX = 0;\n  let currentY = 0;\n\n  let isDragging = false;\n  let startX = 0, startY = 0;\n  let overlayTimeout = null;\n\n  function getMinScale() {\n    const vWidth = viewport.clientWidth;\n    const stageWidth = stage.clientWidth;\n    return Math.max(vWidth \/ stageWidth, 0.2);\n  }\n\n  function applyTransform() {\n    const vWidth = viewport.clientWidth;\n    const vHeight = viewport.clientHeight;\n\n    const minScale = getMinScale();\n    if (scale < minScale) scale = minScale;\n\n    const stageWidth = stage.clientWidth * scale;\n    const stageHeight = stage.clientHeight * scale;\n\n    let minX = vWidth - stageWidth;\n    let maxX = 0;\n    let minY = vHeight - stageHeight;\n    let maxY = 0;\n\n    if (stageWidth <= vWidth) {\n      currentX = (vWidth - stageWidth) \/ 2;\n    } else {\n      currentX = Math.min(maxX, Math.max(minX, currentX));\n    }\n\n    if (stageHeight <= vHeight) {\n      currentY = (vHeight - stageHeight) \/ 2;\n    } else {\n      currentY = Math.min(maxY, Math.max(minY, currentY));\n    }\n\n    stage.style.transform = `translate(${currentX}px, ${currentY}px) scale(${scale})`;\n  }\n\n  function centerMap() {\n    scale = 1;\n    const vWidth = viewport.clientWidth;\n    const stageWidth = stage.clientWidth;\n    currentX = (vWidth - stageWidth) \/ 2;\n    currentY = 0;\n    applyTransform();\n  }\n\n  function showOverlay(msg) {\n    overlayText.innerText = msg;\n    overlay.classList.add('show');\n    clearTimeout(overlayTimeout);\n    overlayTimeout = setTimeout(() => { overlay.classList.remove('show'); }, 1500);\n  }\n\n  \/\/ Mouse Dragging (Desktop)\n  viewport.addEventListener('mousedown', (e) => {\n    isDragging = true;\n    startX = e.clientX - currentX;\n    startY = e.clientY - currentY;\n    viewport.style.cursor = 'grabbing';\n  });\n\n  window.addEventListener('mousemove', (e) => {\n    if (!isDragging) return;\n    e.preventDefault();\n    currentX = e.clientX - startX;\n    currentY = e.clientY - startY;\n    applyTransform();\n  });\n\n  window.addEventListener('mouseup', () => {\n    isDragging = false;\n    viewport.style.cursor = 'grab';\n  });\n\n  \/\/ Touch Control (Mobile)\n  let initialTouchDist = null;\n  let touchStartX = 0, touchStartY = 0;\n\n  viewport.addEventListener('touchstart', (e) => {\n    if (e.touches.length === 1) {\n      touchStartX = e.touches[0].clientX;\n      touchStartY = e.touches[0].clientY;\n    } else if (e.touches.length === 2) {\n      overlay.classList.remove('show');\n      initialTouchDist = Math.hypot(\n        e.touches[0].clientX - e.touches[1].clientX,\n        e.touches[0].clientY - e.touches[1].clientY\n      );\n      const midX = (e.touches[0].clientX + e.touches[1].clientX) \/ 2;\n      const midY = (e.touches[0].clientY + e.touches[1].clientY) \/ 2;\n      startX = midX - currentX;\n      startY = midY - currentY;\n    }\n  }, { passive: true });\n\n  viewport.addEventListener('touchmove', (e) => {\n    if (e.touches.length === 1) {\n      const deltaX = Math.abs(e.touches[0].clientX - touchStartX);\n      const deltaY = Math.abs(e.touches[0].clientY - touchStartY);\n      if (deltaX > 10 || deltaY > 10) {\n        showOverlay(\"Usa due dita per muoverti nella mappa\");\n      }\n    } else if (e.touches.length === 2) {\n      e.preventDefault();\n\n      const midX = (e.touches[0].clientX + e.touches[1].clientX) \/ 2;\n      const midY = (e.touches[0].clientY + e.touches[1].clientY) \/ 2;\n\n      currentX = midX - startX;\n      currentY = midY - startY;\n\n      const dist = Math.hypot(\n        e.touches[0].clientX - e.touches[1].clientX,\n        e.touches[0].clientY - e.touches[1].clientY\n      );\n\n      if (initialTouchDist) {\n        const rect = viewport.getBoundingClientRect();\n        const focalX = midX - rect.left;\n        const focalY = midY - rect.top;\n\n        const zoomFactor = dist \/ initialTouchDist;\n        initialTouchDist = dist;\n\n        const minScale = getMinScale();\n        const newScale = Math.min(maxScale, Math.max(minScale, scale * zoomFactor));\n\n        if (newScale !== scale) {\n          const pointX = (focalX - currentX) \/ scale;\n          const pointY = (focalY - currentY) \/ scale;\n\n          scale = newScale;\n          currentX = focalX - pointX * scale;\n          currentY = focalY - pointY * scale;\n        }\n      }\n\n      applyTransform();\n    }\n  }, { passive: false });\n\n  viewport.addEventListener('touchend', () => { initialTouchDist = null; });\n\n  window.addEventListener('resize', centerMap);\n  centerMap();\n});\n\nfunction toggleRoute(routeId, titleText) {\n  const layers = document.querySelectorAll('.layer-route');\n  const buttons = document.querySelectorAll('.btn-map');\n  const titleElem = document.getElementById('map-title');\n\n  if (titleElem) titleElem.innerText = titleText;\n\n  buttons.forEach(btn => {\n    btn.classList.remove('active');\n    btn.classList.add('inactive');\n  });\n\n  if (routeId === 'all') {\n    layers.forEach(layer => layer.classList.add('active'));\n    const btnAll = document.getElementById('btn-all');\n    btnAll.classList.add('active');\n    btnAll.classList.remove('inactive');\n  } else {\n    layers.forEach(layer => layer.classList.remove('active'));\n    const selectedLayer = document.getElementById('layer-' + routeId);\n    if (selectedLayer) selectedLayer.classList.add('active');\n    \n    const selectedBtn = document.getElementById('btn-' + routeId);\n    if (selectedBtn) {\n      selectedBtn.classList.add('active');\n      selectedBtn.classList.remove('inactive');\n    }\n  }\n}\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-81eb59b e-flex e-con-boxed e-con e-parent\" data-id=\"81eb59b\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-2f5d173 elementor-widget elementor-widget-global elementor-global-3597 elementor-global-222 elementor-widget-spacer\" data-id=\"2f5d173\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Experiences Cycling Route Saddle up for freedom, to the rhythm of nature The Park area is an ideal space for recreation as it is flat, expansive, and close to residential areas. It is easily accessible by bicycle. Following the cycling path, you can admire the Park&#8217;s natural and agricultural beauty over approximately 9 km. The [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":3209,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-3299","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/new.parcodelpiano.ch\/en\/wp-json\/wp\/v2\/pages\/3299","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/new.parcodelpiano.ch\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/new.parcodelpiano.ch\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/new.parcodelpiano.ch\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/new.parcodelpiano.ch\/en\/wp-json\/wp\/v2\/comments?post=3299"}],"version-history":[{"count":1,"href":"https:\/\/new.parcodelpiano.ch\/en\/wp-json\/wp\/v2\/pages\/3299\/revisions"}],"predecessor-version":[{"id":3301,"href":"https:\/\/new.parcodelpiano.ch\/en\/wp-json\/wp\/v2\/pages\/3299\/revisions\/3301"}],"up":[{"embeddable":true,"href":"https:\/\/new.parcodelpiano.ch\/en\/wp-json\/wp\/v2\/pages\/3209"}],"wp:attachment":[{"href":"https:\/\/new.parcodelpiano.ch\/en\/wp-json\/wp\/v2\/media?parent=3299"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}