{"version":3,"sources":["jsdelivr-header.js","/npm/ipad-cursor-js@1.2.1/index.js"],"names":[],"mappings":"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","file":"/npm/ipad-cursor-js@1.2.1/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.39.0.\n * Original file: /npm/ipad-cursor-js@1.2.1/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","const CONSTANTS = {\n  TEXT_ELEMENT_TAGS: [\"P\", \"SPAN\", \"H1\", \"H2\", \"H3\", \"H4\", \"TEXTAREA\"],\n};\n\n/** @type {HTMLDivElement} */\nlet cursor;\n/** @type {HTMLStyleElement} */\nlet nativeCursorStyles;\n\n/**\n * Global App State\n */\nconst $ = {\n  // width and height for general cursor\n  baseCursorWidth: \"10px\",\n  baseCursorHeight: \"10px\",\n  // current width and height and borderRadius, see `onCursorMove`\n  cursorWidth: \"10px\",\n  cursorHeight: \"10px\",\n  borderRadius: \"0px\",\n  // current mouse position on page\n  mouseX: undefined,\n  mouseY: undefined,\n  /**@type {HTMLElement} */\n  hoveredElement: null,\n  // when true, cursor will stop following mouse position\n  isCursorLocked: false,\n};\n\nconst load = () => {\n  // start animation\n  requestAnimationFrame(onCursorMove);\n  // dont want on mobile\n  if (\"ontouchstart\" in window) {\n    return;\n  }\n  // create cursor\n  cursor = document.getElementById(\"cursor\") || document.createElement(\"div\");\n  document.body.appendChild(cursor);\n  cursor.id = \"cursor\";\n  $.baseCursorWidth = cursor.dataset.w || \"10px\";\n  $.baseCursorHeight = cursor.dataset.h || \"10px\";\n  $.cursorWidth = $.baseCursorWidth;\n  $.cursorHeight = $.baseCursorHeight;\n  $.borderRadius = `calc(${$.baseCursorWidth} / 2)`;\n  // disable default cursor, add base cursor styles\n  nativeCursorStyles = document.createElement(\"style\");\n  nativeCursorStyles.id = \"native-cursor-styles\";\n  document.head.appendChild(nativeCursorStyles);\n  nativeCursorStyles.innerText = \"*{ cursor:none ;}\";\n\n  // apply styles to cursor\n  const customCursorStyles = document.createElement(\"style\");\n  document.head.appendChild(customCursorStyles);\n  customCursorStyles.innerText = `\n #cursor {\n   position:fixed;\n   top:0;\n   left:0;\n   width: ${$.cursorWidth};\n   height: ${$.cursorHeight};\n   background:${cursor.dataset.bg || \"gray\"};\n   opacity: 0.5;\n   border-radius: 50%;\n   display: none;\n   pointer-events:none;\n   transition-timing-function: ease;\n   transition: ${transition({\n     width: 0.15,\n     height: 0.15,\n     opacity: 0.15,\n     transform: 0.07,\n   })};\n   margin: 0px !important;\n   padding: 0px !important;\n   z-index: 99999999;\n }`;\n\n  // keep track of current mouse position on page\n  document.addEventListener(\"mousemove\", (e) => {\n    $.mouseX = e.clientX;\n    $.mouseY = e.clientY;\n  });\n};\n\n// main cursor logic here\nconst onCursorMove = () => {\n  const nextFrame = () => requestAnimationFrame(onCursorMove);\n  if (!cursor) return nextFrame();\n  // mouse hasn't moved yet\n  if ($.mouseX === undefined || $.mouseY === undefined) return nextFrame();\n  // on every frame, we update the cursor based on our app state\n  cursor.style.width = $.cursorWidth;\n  cursor.style.height = $.cursorHeight;\n  cursor.style.borderRadius = $.borderRadius;\n  cursor.style.display = \"block\";\n  if (!$.isCursorLocked) {\n    cursor.style.transform = `translate(calc(${$.mouseX}px - (${$.cursorWidth} / 2)), calc(${$.mouseY}px - (${$.cursorHeight} / 2))) `;\n  }\n  // (because of drag cursor) remove lingering transform in case the element is no longer hovered\n  if ($.hoveredElement) {\n    $.hoveredElement.style.removeProperty(\"transform\");\n  }\n  // grab the element under cursor, usually the most nested element\n  $.hoveredElement = document.elementFromPoint($.mouseX, $.mouseY);\n  // cursor probably left browser and we received negative coords\n  if (!$.hoveredElement) return nextFrame();\n\n  // check if any parent element has the data-cursor attribute as that will take priority\n  // added this to prevent text based elements taking priority\n  /**\n   * e.g. div[data-cursor='fill'] > h1 > span\n   * It's likely the effect wants to be applied to the div here but the\n   * span would be picked up by elementFromPoint\n   */\n  const elementsFromPoint = document.elementsFromPoint($.mouseX, $.mouseY);\n  if (elementsFromPoint) {\n    for (const el of elementsFromPoint) {\n      // if anything we are hovering over has data-cursor then we set that as the hovered element\n      if (el.dataset[\"cursor\"]) {\n        $.hoveredElement = el;\n        break;\n      }\n    }\n  }\n  if ($.hoveredElement.dataset[\"cursor\"] === \"reset\") {\n    $.isCursorLocked = false;\n    useNativeCursor();\n    return nextFrame();\n  }\n  // handle fill cursor\n  if ($.hoveredElement.dataset[\"cursor\"] === \"fill\") {\n    $.isCursorLocked = true;\n    useFillCursor();\n    return nextFrame();\n  }\n  // handle drag cursor\n  if ($.hoveredElement.dataset[\"cursor\"] === \"drag\") {\n    $.isCursorLocked = true;\n    useDragCursor();\n    return nextFrame();\n  }\n  // handle text cursor\n  if (CONSTANTS.TEXT_ELEMENT_TAGS.includes($.hoveredElement.tagName)) {\n    $.isCursorLocked = false;\n    useTextCursor();\n    return nextFrame();\n  }\n  // handle inputs\n  if ($.hoveredElement.tagName === \"INPUT\") {\n    $.isCursorLocked = false;\n    resetCursor();\n    hideNativeCursor();\n    const textInputs = [\n      \"text\",\n      \"email\",\n      \"number\",\n      \"password\",\n      \"search\",\n      \"tel\",\n      \"url\",\n      null,\n    ];\n    if (textInputs.includes($.hoveredElement.getAttribute(\"type\"))) {\n      useTextCursor();\n    } else {\n      useGeneralCursor();\n    }\n    return nextFrame();\n  }\n  // use general cursor\n  $.isCursorLocked = false;\n  useGeneralCursor();\n  nextFrame();\n};\n\nconst resetCursor = () => {\n  // removes all possible overrides, results in the defaults applied by css stylesheet\n  cursor.style.removeProperty(\"z-index\");\n  cursor.style.removeProperty(\"opacity\");\n  cursor.style.removeProperty(\"transition\");\n};\n\nconst hideNativeCursor = () => {\n  if (nativeCursorStyles.innerText !== \"*{cursor: none;}\") {\n    nativeCursorStyles.innerText = `*{cursor: none;}`;\n  }\n};\n\nconst useNativeCursor = () => {\n  cursor.style.setProperty(\"opacity\", 0);\n  nativeCursorStyles.innerText = ``;\n};\n\nconst useGeneralCursor = () => {\n  resetCursor();\n  hideNativeCursor();\n\n  $.cursorWidth = $.baseCursorWidth;\n  $.cursorHeight = $.baseCursorHeight;\n  $.borderRadius = `calc(${$.baseCursorWidth} / 2)`;\n};\n\nconst useFillCursor = () => {\n  hideNativeCursor();\n\n  const {\n    width: w,\n    height: h,\n    x,\n    y,\n  } = $.hoveredElement.getBoundingClientRect();\n\n  const offsetW = w / 30;\n  const offsetH = h / 30;\n  // expand to containers size + offset\n  $.cursorWidth = `${w + offsetW}px`;\n  $.cursorHeight = `${h + offsetH}px`;\n  $.borderRadius = \"3px\";\n  // slow down transition\n  cursor.style.transition = transition({\n    width: 0.2,\n    height: 0.2,\n    opacity: 0.15,\n    transform: 0.15,\n  });\n  // make cursor go below hovered element\n  cursor.style.zIndex = -1;\n  cursor.style.opacity = \"0.3\";\n  const alignCentreCoords = {\n    x: x - offsetW / 2,\n    y: y - offsetH / 2,\n  };\n  const cursorParallax = parallaxShiftAmount(\n    $.hoveredElement,\n    offsetW,\n    offsetH\n  );\n  const hoveredElementParallax = parallaxShiftAmount(\n    $.hoveredElement,\n    offsetW / 2,\n    offsetH / 2\n  );\n  const resultantCoords = {\n    x: alignCentreCoords.x + cursorParallax.x,\n    y: alignCentreCoords.y + cursorParallax.y,\n  };\n  cursor.style.transform = `translate(${resultantCoords.x}px, ${resultantCoords.y}px)`;\n  $.hoveredElement.style.transform = `translate(${hoveredElementParallax.x}px,${hoveredElementParallax.y}px)`;\n};\n\nconst useDragCursor = () => {\n  hideNativeCursor();\n\n  // shrink cursor, then hide with opacity\n  const { width, height } = $.hoveredElement.getBoundingClientRect();\n  $.cursorWidth = \"5px\";\n  $.cursorHeight = \"5px\";\n  cursor.style.opacity = \"0\";\n  cursor.style.transition = \"initial\";\n\n  const { x, y } = parallaxShiftAmount(\n    $.hoveredElement,\n    width / 20,\n    height / 20\n  );\n  $.hoveredElement.style.transform = `translate(${x}px,${y}px)`;\n};\n\nconst useTextCursor = () => {\n  resetCursor();\n  hideNativeCursor();\n\n  const fontSize = window\n    .getComputedStyle($.hoveredElement)\n    .getPropertyValue(\"font-size\");\n  $.cursorWidth = \"1px\";\n  $.cursorHeight = fontSize;\n};\n\n/**\n * @param {HTMLElement} elementToGetDimensionsFrom\n * @param {number} offset\n */\nconst parallaxShiftAmount = (elementToGetDimensionsFrom, offsetW, offsetH) => {\n  // calculates mouse distance from the centre of the element\n  // then calculates how many pixels to shift an element for every pixel moved by mouse\n  // where offset is the total distance moveable\n  const {\n    width: w,\n    height: h,\n    x,\n    y,\n  } = elementToGetDimensionsFrom.getBoundingClientRect();\n\n  const elementCentre = { x: x + w / 2, y: y + h / 2 };\n  const mouseDistanceFromCentre = {\n    x: $.mouseX - elementCentre.x,\n    y: $.mouseY - elementCentre.y,\n  };\n  const parallaxFactor = {\n    x: offsetW / (w / 2),\n    y: offsetH / (h / 2),\n  };\n  return {\n    x: mouseDistanceFromCentre.x * parallaxFactor.x,\n    y: mouseDistanceFromCentre.y * parallaxFactor.y,\n  };\n};\n\nconst transition = (properties) =>\n  Object.entries(properties)\n    .map(([key, value]) => `${key} ${value}s`)\n    .join(\",\");\n\nwindow.addEventListener(\"DOMContentLoaded\", load);\n"]}