最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Set cursor to be <symbol> element - Stack Overflow

programmeradmin0浏览0评论

I have an HTML symbol

<symbol id="arrow" viewBox="0 0 8.4666659 8.4666659">
  <g transform="translate(0,-288.53334)">
    <path style="fill:none;stroke:#000000;stroke-width:0.48417112;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;" d="m 0.17215798,288.70836 8.05225192,8.04935"></path>
    <path style="fill:none;stroke:#000000;stroke-width:0.48417112;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;" d="m 8.2221335,293.64243 0.00228,3.11528 -3.1283502,2.2e-4"></path>
  </g>
</symbol>

which I want to use as the cursor. I'm familiar with changing the cursor via JQuery like this:

body.css('cursor', `wait`);

But how can I do this for a <symbol> element?

I have an HTML symbol

<symbol id="arrow" viewBox="0 0 8.4666659 8.4666659">
  <g transform="translate(0,-288.53334)">
    <path style="fill:none;stroke:#000000;stroke-width:0.48417112;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;" d="m 0.17215798,288.70836 8.05225192,8.04935"></path>
    <path style="fill:none;stroke:#000000;stroke-width:0.48417112;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;" d="m 8.2221335,293.64243 0.00228,3.11528 -3.1283502,2.2e-4"></path>
  </g>
</symbol>

which I want to use as the cursor. I'm familiar with changing the cursor via JQuery like this:

body.css('cursor', `wait`);

But how can I do this for a <symbol> element?

Share Improve this question edited Dec 22, 2021 at 22:35 General Grievance 4,98838 gold badges37 silver badges55 bronze badges asked Aug 23, 2017 at 18:44 Scotty HScotty H 6,7147 gold badges45 silver badges100 bronze badges 4
  • 1 Relevant CSS-Tricks article: css-tricks.com/using-css-cursors/#article-header-id-1 Unfortunately, looks like their demo of using an SVG (albeit an CSS/base64-encoded one) doesn't work on my Chrome for macOS. But you could copy their JS demo of using a custom element as a "cursor" to follow the mouse. – Jon Uleis Commented Aug 23, 2017 at 18:47
  • Doesn't seem to work for SVG in Chrome on Windows either... – Scotty H Commented Aug 23, 2017 at 18:52
  • I'm looking around for verification of this but can't find anything.. appears SVG and GIF support for custom cursors in Chrome is broken.. tried stable and dev channels. Safari likes SVG, but not base64 SVG or GIF... codepen.io/geoffgraham/pen/QNgoQW – daviestar Commented Aug 25, 2017 at 18:40
  • 2 Alright, so here's my stab at it. Disclaimer: This is a work in progress. Only working on Windows in Chrome,FF,Opera. Doesn't work in IE/Edge. Had to add an xmlns namespace to the element as well as change it from an <sybmol> to an <svg> element. jsfiddle.net/6jnvcsu4/56 Is this even remotely close to what you're trying to accomplish? – luxdvie Commented Aug 28, 2017 at 18:02
Add a comment  | 

2 Answers 2

Reset to default 18 +25

You can set two <svg> elements one to define your SVG symbol and the other to hold the element. Then with Javascript, you can set an event listener and change the position of the whole <svg> (the one holding your element) when the user's cursor moves. Also, I have hidden the default browser cursor with the CSS property cursor: none. Here's a working code:

document.addEventListener('mousemove', function(e) {

  let newTransformRule = 'translate(' + (e.pageX - 360) + 'px, ' + (e.pageY - 115) + 'px)';

  document.querySelector('#arrowCanvas').style.transform = newTransformRule;

});
body {
  cursor: none;
}
<svg>
  <symbol id="arrow" viewBox="0 0 8.4666659 8.4666659">
    <g transform="translate(0,-288.53334)">
      <path style="fill:none;stroke:#000000;stroke-width:0.48417112;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;" d="m 0.17215798,288.70836 8.05225192,8.04935"></path>
      <path style="fill:none;stroke:#000000;stroke-width:0.48417112;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;" d="m 8.2221335,293.64243 0.00228,3.11528 -3.1283502,2.2e-4"></path>
    </g>
  </symbol>
</svg>

<svg id="arrowCanvas" width="100" height="60">
  <use href="#arrow" width="100" height="50"/>
</svg>

You will have to tweak the values in newTransformRule to center your custom cursor with the default cursor. Remove the CSS rule to do the adjustment.

The code is working on Firefox, Chrome and Edge.

@Ivan answer is good, but, this way it will work better.

I just made some changes

document.addEventListener('mousemove', function(e) {

  let newTransformRule = 'translate(' + (e.pageX - 380) + 'px, ' + (e.pageY - 60) + 'px)';

  document.querySelector('#arrowCanvas').style.transform = newTransformRule;

});
body {
  cursor: none;
}

#arrowCanvas {
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: -1;
}
<svg id="arrowContainer">
  <symbol id="arrow" viewBox="0 0 8.4666659 8.4666659">
    <g transform="translate(0,-288.53334)">
      <path style="fill:none;stroke:#000000;stroke-width:0.48417112;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;" d="m 0.17215798,288.70836 8.05225192,8.04935"></path>
      <path style="fill:none;stroke:#000000;stroke-width:0.48417112;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;" d="m 8.2221335,293.64243 0.00228,3.11528 -3.1283502,2.2e-4"></path>
    </g>
  </symbol>
</svg>

<svg id="arrowCanvas" width="100" height="60">
  <use href="#arrow" width="100" height="50"/>
</svg>

发布评论

评论列表(0)

  1. 暂无评论