0

Is there a way to have an dynamically colored svg as a cursor? I want to have a prop that changes the fill value and then reflect that on the cursor.

I saw this post and followed their example and not getting the same results.

How to change CSS cursor dynamically vuejs

I made a CodeSandbox to test this out, but currently it's not working. What am I doing wrong here?

If anyone has any tips or advice I would really appreciate it!

Cheers

NOTE: I use this to get the URL code from the svg

https://codepen.io/yoksel/details/MWKeKK

App.vue

<template>
  <CustomSVG :style="{ cursor: customCursor }" :fill="fill" />
</template>

<script>
import CustomSVG from "./components/CustomSVG.vue";
import { defineComponent, ref } from "vue";

export default defineComponent({
  name: "MyComponent",
  props: {},
  setup(props) {
    const fill = ref("red");
    const customCursor = `url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.7071 10.7071C10.3166 11.0976 9.68342 11.0976 9.29289 10.7071C8.90237 10.3166 8.90237 9.68342 9.29289 9.29289L15.2929 3.29289C15.6834 2.90237 16.3166 2.90237 16.7071 3.29289C17.0976 3.68342 17.0976 4.31658 16.7071 4.70711L10.7071 10.7071Z' fill='${fill.value}'/%3E%3Cpath d='M15 15V11.5C15 10.9477 15.4477 10.5 16 10.5C16.5523 10.5 17 10.9477 17 11.5V16C17 16.5523 16.5523 17 16 17H4C3.44772 17 3 16.5523 3 16V4C3 3.44772 3.44772 3 4 3H8.5C9.05228 3 9.5 3.44772 9.5 4C9.5 4.55228 9.05228 5 8.5 5H5V15H15Z' fill='${fill.value}'/%3E%3Cpath d='M17 8C17 8.55228 16.5523 9 16 9C15.4477 9 15 8.55228 15 8V4C15 3.44772 15.4477 3 16 3C16.5523 3 17 3.44772 17 4V8Z' fill='${fill.value}'/%3E%3Cpath d='M12 5C11.4477 5 11 4.55228 11 4C11 3.44772 11.4477 3 12 3H16C16.5523 3 17 3.44772 17 4C17 4.55228 16.5523 5 16 5H12Z' fill='${fill.value}'/%3E%3C/svg%3E")`;
    return { fill, customCursor };
  },
  components: { CustomSVG },
});
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

LovelyAndy
  • 841
  • 8
  • 22

1 Answers1

1

Try to add pointer at the end of customCursor svg:

const { ref } = Vue
const app = Vue.createApp({
  setup() {
    const fill = ref("rgb(255, 99, 71)");
    const customCursor = `url("data:image/svg+xml,%3Csvg width='20' height='20' viewBox='0 0 20 20' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10.7071 10.7071C10.3166 11.0976 9.68342 11.0976 9.29289 10.7071C8.90237 10.3166 8.90237 9.68342 9.29289 9.29289L15.2929 3.29289C15.6834 2.90237 16.3166 2.90237 16.7071 3.29289C17.0976 3.68342 17.0976 4.31658 16.7071 4.70711L10.7071 10.7071Z' fill='${fill.value}'/%3E%3Cpath d='M15 15V11.5C15 10.9477 15.4477 10.5 16 10.5C16.5523 10.5 17 10.9477 17 11.5V16C17 16.5523 16.5523 17 16 17H4C3.44772 17 3 16.5523 3 16V4C3 3.44772 3.44772 3 4 3H8.5C9.05228 3 9.5 3.44772 9.5 4C9.5 4.55228 9.05228 5 8.5 5H5V15H15Z' fill='${fill.value}'/%3E%3Cpath d='M17 8C17 8.55228 16.5523 9 16 9C15.4477 9 15 8.55228 15 8V4C15 3.44772 15.4477 3 16 3C16.5523 3 17 3.44772 17 4V8Z' fill='${fill.value}'/%3E%3Cpath d='M12 5C11.4477 5 11 4.55228 11 4C11 3.44772 11.4477 3 12 3H16C16.5523 3 17 3.44772 17 4C17 4.55228 16.5523 5 16 5H12Z' fill='${fill.value}'/%3E%3C/svg%3E")
    , pointer`;
    return { fill, customCursor };
  },
})

app.component('customSvg', {
  template: `
    <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><rect opacity="0.8" x="7" y="6" width="11" height="11" rx="1" :fill="fill" /><path d="M14.5 14.5V11.25C14.5 10.9739 14.7239 10.75 15 10.75C15.2761 10.75 15.5 10.9739 15.5 11.25V15C15.5 15.2761 15.2761 15.5 15 15.5H5C4.72386 15.5 4.5 15.2761 4.5 15V5C4.5 4.72386 4.72386 4.5 5 4.5H8.75C9.02614 4.5 9.25 4.72386 9.25 5C9.25 5.27614 9.02614 5.5 8.75 5.5H5.5V14.5H14.5Z" fill="black" /><path d="M10.3536 10.3536C10.1583 10.5488 9.84171 10.5488 9.64645 10.3536C9.45118 10.1583 9.45118 9.84171 9.64645 9.64645L14.6464 4.64645C14.8417 4.45118 15.1583 4.45118 15.3536 4.64645C15.5488 4.84171 15.5488 5.15829 15.3536 5.35355L10.3536 10.3536Z" fill="black" /><path d="M15.5 8.5C15.5 8.77614 15.2761 9 15 9C14.7239 9 14.5 8.77614 14.5 8.5V5C14.5 4.72386 14.7239 4.5 15 4.5C15.2761 4.5 15.5 4.72386 15.5 5V8.5Z" fill="black" /><path d="M11.5 5.5C11.2239 5.5 11 5.27614 11 5C11 4.72386 11.2239 4.5 11.5 4.5H15C15.2761 4.5 15.5 4.72386 15.5 5C15.5 5.27614 15.2761 5.5 15 5.5H11.5Z" fill="black" /></svg>
  `,
  props: {
    fill: { type: String, default: "currentColor" },
  },
  setup(props) {
    return {};
  },
})

app.mount('#demo')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <custom-svg :style="{ cursor: customCursor }" :fill="fill"></custom-svg>
</div>
Nikola Pavicevic
  • 21,952
  • 9
  • 25
  • 46
  • This is great, thank you! Is there anyway this works with hex values? I've tried putting a hex value in there and it didn't work; very odd – LovelyAndy Sep 24 '22 at 19:03
  • 1
    @LovelyAndy hey mate, you can use `rgb` colors, I'm not sure if it is possible with hex values – Nikola Pavicevic Sep 24 '22 at 19:21
  • 1
    So I just figured it out, but with the encoded URL you need to put replace the '#' with '%23' and then it works! Just for future reference. Thanks again man! – LovelyAndy Sep 24 '22 at 19:26