How to change CSS cursor dynamically vuejs - css

This is probably too broad of a question, but I am trying to recreate a cursomizer with Vuejs as a framework. I got stuck in a position where I have to change the cursors dynamically. These cursors are supposed to be SVG files which are able to be accessed from the next component where the user would be able to modify the size and fill. My concern is can store different cursors in different buttons and update when clicked. The code that I provided contains different list items which are dynamically generated and when clicked, it adds active class to the chosen item. If anyone has any advice on how to approach this problem, jump in.
<template>
<div>
<h1>Choose cursor</h1>
<section class="cursors-wrapper">
<ul class="cursor-list">
<li class="cursor-list-item" #click="activateCursor(cursor.cursorId)" :class="{ active : active_el == cursor.cursorId }" v-for="cursor in cursors" >
<a href="#" class="cursor-list-item-inner">
<!-- SVGG-->
<div v-html="cursor.cursorImage"></div>
</a>
</li>
</ul>
</section>
<div #click="choosenOne"></div>
</div>
<script>
export default {
data () {
return {
cursors: [
{
cursorId: '1',
cursorImage: `<svg class="cursor-svg cursor-svg_static hover_undefined move_undefined click_undefined" height="16"
width="16">
<ellipse class="cursor-svg__main" cx="8" cy="8" rx="8" ry="8" fill="#000"></ellipse>
</svg>`
},
{
cursorId: '2',
cursorImage: `<svg class="cursor-overflow cursor-svg cursor-svg_static hover_undefined move_undefined click_undefined" height="16"
width="16">/* */
<ellipse class="cursor-svg__main" cx="8" cy="8" rx="8" opacity="1" ry="8" fill="none"
stroke-width="3" stroke="#000"></ellipse>
</svg>`
},
{
cursorId: '3',
cursorImage: ` <svg class="cursor-svg cursor-svg_static hover_undefined move_undefined click_undefined" height="16"
width="16">
<path class="cursor-svg__main" d="M 0 0 L 12 10 L 0 16" opacity="1" fill="#000"></path>
</svg>`
}
],
active_el: 0
}
},
methods:{
activateCursor:function(el){
this.active_el = el;
console.log(this.cursorId);
}
}
}

The best solution I can think of is to use style bindings. This way, you can define the cursor in your data object and change it dynamically afterwards ( v-bind:style="{cursor: selectedCursor}").
As for setting the cursor, you can use the method like shown by the top answer of this question.
I've created a fiddle to illustrate what I mean
https://jsfiddle.net/rnab4tep/1/
All you have to do now is set selectedCursor to the cursor of your liking.

Related

SVG with multiple path

How do play with the different fill variables inside an svg ?
I am trying like this but I don't get any results :
<img class="icon-shop icon-colors" src="#/assets/icon-shop.svg"/>
...
<style>
.icon-colors {
--color-default: #c13127;
--color-dark: #ef5b49;
}
</style>
icon-shop.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="..." fill="var(--color-default)"/><path d="..." fill="var(--color-dark)"/><path d="..." fill="var(--color-default)"/><g><path d="..." fill="var(--color-default)"/></g></svg>
Edit 1 :
When I try to use svg as a .vue file, I get a blank page and this console error :
Failed to execute 'createElement' on 'Document': The tag name provided ('/img/icon-shop.7de319ba.svg') is not a valid name.
edit 2 :
I am not sure how I should export the variable components
<template>
<svg
v-if="name === 'shop'"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path
d="M15.6 1.6H8.4c-.4 0-.7.3-.7.7v2.5h8.5V2.3c.1-.4-.2-.7-.6-.7z"
fill="var(--color-default)"
/>
</svg>
</template>
<script>
export default {
props: ["name", "var(--color-default)", "var(--color-black)"],
};
</script>
Component Call
<IconShopVue
color-default="#c0ffee"
color-dark="#c0ffee"
class="w-8 h-8"
name="shop"
></IconShopVue>
UPDATE on how to make this code functional
<template>
<svg
v-if="name === 'shop'"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path
d="M15.6 1.6H8.4c-.4 0-.7.3-.7.7v2.5h8.5V2.3c.1-.4-.2-.7-.6-.7z"
:fill="colorDefault"
/>
</svg>
</template>
<script>
export default {
props: ["name", "colorDefault", "colorBlack"],
};
</script>
<IconShopVue
color-default="#c0ffee"
color-dark="#c0ffee"
class="w-8 h-8"
name="shop"
></IconShopVue>
You should put your svg into a .vue file, copy your SVG code into the template section. Then, pass some props to your .vue component and interpolate the actual default/dark colors as you would do with any other kind of props.
<my-cool-svg header-color="#c13127" outline-color="#ef5b49" fill-color="#c0ffee"></my-cool-svg>
This will provide a lot of flexibility overall VS working with a classic .svg file.
This is how the .vue should look like
<template>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="..." :fill="headerColor"/>
<path d="..." :fill="outlineColor"/>
<path d="..." :fill="fillColor"/>
<g>
<path d="..." :fill="fillColor"/>
</g>
</svg>
</template>
<script>
export default {
props: ['headerColor', 'outlineColor', 'fillColor']
}
</script>

How to change SVG fill color in Ionic 5

I am trying to implement dark mode in the app and for that I need to change the fill color of the svg icon when a user changes mode.
I am trying to use a variable directly in the svg code but it seems to have no effect.
<svg class="trophy" xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 36 36"><g id="Group_216" data-name="Group 216" transform="translate(-28 -158)"><rect id="Rectangle_2" data-name="Rectangle 2" width="36" height="36" rx="5" transform="translate(28 158)" fill="var(--primaryforicon)"/>
<path id="trophy" d="M19.853,6.795a.4.4,0,0,0-.4-.4H17.768V4.935c0-.013,0-.024,0-.037a.613.613,0,0,0-.612-.613l-.022,0v0H9.015V4.3a.61.61,0,0,0-.563.608c0,.013,0,.025,0,.037V6.394H6.773a.4.4,0,0,0-.4.384h0v5.452h0v0h0a.4.4,0,0,0,.4.4H8.511a4.659,4.659,0,0,0,3.562,3.85v2.66H9.992a.521.521,0,1,0,0,1.041v0h6.238v0a.521.521,0,1,0,0-1.041H14.15v-2.66a4.657,4.657,0,0,0,3.566-3.851h1.736a.4.4,0,0,0,.4-.381h0V6.795h0Zm-11.4,4.8H7.414V7.436H8.456Zm10.355,0H17.767V7.436h1.045Z" transform="translate(33.058 163.583)" fill="var(--secondaryforicon)"/>
It would be really helpful is someone can help me with this
Try this:
<svg class="trophy" xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 36 36"><g id="Group_216" data-name="Group 216" transform="translate(-28 -158)"><rect id="Rectangle_2" data-name="Rectangle 2" width="36" height="36" rx="5" transform="translate(28 158)" fill="var(--primaryforicon)"/>
<path id="trophy" d="M19.853,6.795a.4.4,0,0,0-.4-.4H17.768V4.935c0-.013,0-.024,0-.037a.613.613,0,0,0-.612-.613l-.022,0v0H9.015V4.3a.61.61,0,0,0-.563.608c0,.013,0,.025,0,.037V6.394H6.773a.4.4,0,0,0-.4.384h0v5.452h0v0h0a.4.4,0,0,0,.4.4H8.511a4.659,4.659,0,0,0,3.562,3.85v2.66H9.992a.521.521,0,1,0,0,1.041v0h6.238v0a.521.521,0,1,0,0-1.041H14.15v-2.66a4.657,4.657,0,0,0,3.566-3.851h1.736a.4.4,0,0,0,.4-.381h0V6.795h0Zm-11.4,4.8H7.414V7.436H8.456Zm10.355,0H17.767V7.436h1.045Z" transform="translate(33.058 163.583)" fill="var(--secondaryforicon)"/>
<script>
let varr = "yellow";
const svg0 = document.getElementsByClassName("trophy")[0];
svg0.addEventListener("click", (e) => e.target.setAttribute("fill", varr));
</script>
"var" is a reserved word, cannot be a variable name.
Try this solution. First detect whether the app running on dark mode. Then switch the fill color dynamically.
import { ThemeDetection } from '#ionic-native/theme-detection';
fillcolor: string;
constructor(private themeDetection: ThemeDetection) { }
...
this.themeDetection.isAvailable()
.then((res: ThemeDetectionResponse) => {
if(res.value) {
this.themeDetection.isDarkModeEnabled().then((res: ThemeDetectionResponse) => {
if(res){
this.fillcolor = "#FFFFF"
}else{
this.fillcolor = "#00000"
}
})
.catch((error: any) => console.error(error));
}
})
.catch((error: any) => console.error(error));
in SVG
<svg class="trophy" xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 36 36"><g id="Group_216" data-name="Group 216" transform="translate(-28 -158)"><rect id="Rectangle_2" data-name="Rectangle 2" width="36" height="36" rx="5" transform="translate(28 158)" [attr.fill]="fillcolor"/>

(Fullcalendar 4 VueJs) Adding custom element inside Calendar Header

Please take a look at my approach and tell me is it a good/correct way to add a complex DOM element inside Fullcalendar header.
viewSkeletonRender(info){
this.$refs.fullCalendar.$el.querySelector('.fc-header-toolbar').insertAdjacentHTML('afterbegin', `
<div class="event_create-wrap">
<div class="event_create-btn">
<div class="event_create-btn-left">
Create
</div>
<div class="event_create-dropdown">
<button class="event_create-btn-dropdown" #click="eventDropdownClicked">
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M111 13.8822L3.62734 8.39658C3.23555 8.01742 3.23555 7.40432 3.62734 7.0292L4.5693 6.11762C4.96109 5.73846 5.59462 5.73846 5.98224 6.11762L10.0002 10.006L14.0181 6.11762C14.4099 5.73846 15.0434 5.73846 15.431 6.11762L16.373 7.0292C16.7648 7.40836 16.7648 8.02146 16.373 8.39658L10.7045 13.8822C10.3211 14.2614 9.68756 14.2614 9.29578 13.8822Z" fill="white"/>
</svg>
</button>
<div class="event_create-btn-dropdown-content" :class="{show: isEventListShown}">
1
2
3
</div>
</div>
</div>
</div>
`);
}
I am using "viewSkeletonRender" hook but i am not really sure that using "insertAdjacentHTML" is good, since i've used it first time.
I can't use AppendChild because i need to add so many html code there and it is difficult to create all html objects step by step (what if i need to add 100 html tags...) .
I can't use innerHtml because it will remove all what i have in fc-header-toolbar.
And as i understand i can't bind any VueJs props and methods to this HTML with this approach because i add this html as vanila Js.
Thank you for your advice.

Filtering click element event with matching css selector to an object

I've ran into a problem and can't seem to get the GTM to register the event specifically.
Here is how the HTML looks like for the element that I need to register when someone clicks on it.
<div class="targetDiv option option-hoverable">
<div class="shape">
<svg width="140" height="140" viewBox="0 0 140 140" xmlns="http://www.w3.org/2000/svg" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<title>Shape + Shape + Shape</title>
<desc>Created with Sketch.</desc>
<g transform="translate(0 0)" sketch:type="MSShapeGroup" fill="none">
<circle id="Shape" fill="#CFDF80" cx="40" cy="84.434" r="40"></circle>
<circle id="Shape" fill="#FDE9E8" cx="80" cy="40" r="40"></circle>
<circle fill="#E2506E" cx="100" cy="100" r="40"></circle>
</g>
</svg>
</div>
<h3>Product Title</h3>
<div class="actions">
<a class="button button-subtle button-toggle" data-colors="tender" data-toggled="Select" href="">Select</a>
</div>
</div>
I can't get the Click to register on the outter DIV click, it registers wither the button click or the click on shapes. I need it to register on the DIV with class targetDiv.
I'm getting correct Click triggers from other places, so listening isn't a problem.
Right now the trigger is set like this:
Trigger Type - Click - all elements
Trigger fires on some clicks.
And the conditions are:
Click Element -> matches CSS selector -> targetDiv
This
Click Element -> matches CSS selector -> targetDiv
wants to match a <targetDiv> element, which is not present in your html code.
Try writing a dot before the classname, since that is how you can write a css selector for a class:
Click Element -> matches CSS selector -> .targetDiv

Spacebars - Insert inline SVG icons with Template.registerHelper or UI.dynamic

I am making a template helper that will insert inline SVG icons into my templates. I want to pass an argument to add an additional CSS class (which will be used to change the default size, color, etc.).
What I Expect
<button>
<svg viewBox="0 0 78 73" class="svg-icon svgWhite" version="1.1" ...>
<polygon id="icon-star" points="39 ... 60">
</polygon>
</svg>
</button>
What I Get
<button>
"[object Object]"
<svg viewBox="0 0 78 73" class="svg-icon" version="1.1" ...>
<polygon id="icon-star" points="39 ... 60">
</polygon>
<!--[object Object]-->
</svg>
</button>
My Template
<template name="whatever">
<button>{{{icon.star svgWhite}}}</button>
</template>
My Template Helper
Template.registerHelper('icon', {
star: function (userClass, userWrapper) {
var wrapper = (userWrapper == undefined) ? "i" : userWrapper;
var addlClass = (userClass == undefined) ? "" : ", " + userClass;
var svgWidth = 78;
var svgHeight = 73;
var svgCode = '<polygon id="icon-star" points="39 .... 60"></polygon>';
var icon = '<'+wrapper+'>' +
'<svg viewBox="0 0 ' + svgWidth + ' ' + svgHeight + '" ' +
'class="svg-icon' + addlClass + '" ' +
svgConfig + '>' + svgCode + '</' + wrapper + '>';
return icon
}
});
Reference: https://github.com/meteor/meteor/tree/devel/packages/spacebars#helper-arguments
Your template helper registration looks broken, I think you are trying to achieve a simple thing using an overcomplicated way.
When you start using triple brackets syntax and writing HTML in your javascript, you know you are probably doing it wrong : you should probably use template inclusion to perform what you need.
First, we define the parent template, it will include a child template that we can configure using attributes (these attributes will act as the data context of the child template).
<template name="svgButton">
<button type="button">
{{> svgIcon class="svg-white"}}
</button>
</template>
Then we define the child template, we can use attributes passed from the parent template.
<template name="svgIcon">
<svg viewBox="0 0 {{width}} {{height}}" class="svg-icon {{class}}">
{{! warning, polygon is a self closing tag like img}}
<polygon id="icon-star" points="..." />
</svg>
</template>
We can define helpers that will either take the value of the data context if present, or a default value :
Template.svgIcon.helpers({
width:function(){
return this.width || 78;
},
height:function(){
return this.height || 73;
}
});
So we may include the child template using this form for advanced customization :
{{> svgIcon class="svg-whatever" width="16" height="16"}}
EDIT :
What happens when I have 20+ icon templates. Do I then have 20+
template helpers with repeatable functions (not DRY)?
This is the approach I would use :
First, define all your icon svg content as different templates.
<template name="svgIconStarContent">
<polygon id="icon-star" points="..."/>
</template>
{{! repeat 20 times...
but this is DRY compliant because each time this is a different icon}}
Then we can use UI.dynamic to include the correct template based on a parameter name.
https://www.discovermeteor.com/blog/blaze-dynamic-template-includes/
<template name="svgIcon">
<svg viewBox="0 0 {{width}} {{height}}" class="svg-icon {{class}}">
{{> UI.dynamic template=svgIconContent}}
</svg>
</template>
Finally, in the parent template, we can pass the name of the template we want to insert dynamically so the content of the icon may vary when invoked with different values.
{{> svgIcon svgIconContent="svgIconStarContent"}}

Resources