Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@sfgrp/svg-radial-menu

Package Overview
Dependencies
Maintainers
3
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sfgrp/svg-radial-menu - npm Package Compare versions

Comparing version 1.0.3 to 1.0.4

2

dist/svg-radial-menu.esm.js

@@ -1,1 +0,1 @@

class SVG{constructor(t){this.SVGElement=this.createSVGElement("svg",t)}createSVGElement(t,e={}){t=document.createElementNS("http://www.w3.org/2000/svg",t);return this.SetSVGAttributes(t,e),t}SetSVGAttributes(t,e){for(var i in e)t.setAttribute(i,`${e[i]}`)}parseAttributes(t){return Object.fromEntries(Object.entries(t).filter(([,t])=>t).map(([t,e])=>[[t.replace(/\B(?:([A-Z])(?=[a-z]))|(?:(?<=[a-z0-9])([A-Z]))/g,"-$1$2").toLowerCase()],e]))}createSVGCircle(t,e,i,s={}){var r=this.createSVGElement("circle",s);return this.SetSVGAttributes(r,Object.assign({cx:t,cy:e,r:i},s)),r}createSVGImage(t,e,i,s,r){const n=document.createElementNS("http://www.w3.org/2000/svg","image");return n.setAttribute("x",`${t}px`),n.setAttribute("y",`${e}px`),n.setAttribute("width",`${i}px`),n.setAttribute("height",`${s}px`),n.setAttribute("href",r),n}createSVGLink(t,e){const i=document.createElementNS("http://www.w3.org/2000/svg","a");return i.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",e),i.append(t),i}createSVGText(s,t,e,r={}){const i=e.split(" "),n=parseInt(`${r["font-size"]}`,10),h=1===i.length?n/2:n/2*-i.length+n;e=i.map((t,e)=>{const i=this.createSVGElement("tspan",r);e=e?n:h;return i.setAttribute("dy",`${e}px`),i.setAttribute("x",`${s}px`),i.removeAttribute("y"),i.textContent=t,i});return this.createSVGGroup(e,"text",{x:s,y:t,dy:0})}createSVGGroup(t,e="g",i={}){const s=this.createSVGElement(e,i);return t.forEach(t=>{s.appendChild(t)}),s}describeArc(t,e,i,s,r,n){const h=this.polarToCartesian(t,e,i,n),a=this.polarToCartesian(t,e,i,r),l=this.polarToCartesian(t,e,i+s,n),c=this.polarToCartesian(t,e,i+s,r),o=n-r<=180?"0":"1";return["M",l.x,l.y,"A",i+s,i+s,0,o,0,c.x,c.y,"L",a.x,a.y,"A",i,i,0,o,1,h.x,h.y,"L",l.x,l.y,"Z"].join(" ")}polarToCartesian(t,e,i,s){s=(s-90)*Math.PI/180;return{x:t+i*Math.cos(s),y:e+i*Math.sin(s)}}}class Segment extends SVG{constructor(t,e,i,s,r,n,h){super(h),this.backgroundColor="#FFFFFF",this.margin=0,this.textColor="#FFFFFF";var{sliceSize:a,margin:l}=h;this.options=h,this.slice=t,this._name=t.name,this.size=t.size||a,this.startFrom=s,this.radiusStart=r,this.radiusEnd=r+n,this.x=e,this.y=i,this.margin=l||this.margin,this.SVGAttributes=this.parseAttributes(t.svgAttributes||{}),this.defaultSVGAttributes=this.parseAttributes(h.svgAttributes||{}),360<=this.radiusEnd-this.radiusStart&&(this.radiusEnd=359.999,this.margin=0),this.SVGElement=this.createSlice(this.x,this.y,this.startFrom,this.size,this.radiusStart,this.radiusEnd,this.options)}toSVG(){return this.SVGElement}createSlice(t,e,i,s,r,n,h){var a=this.slice;const l=[];var c=s/2+i,o=(n-r)/2,e=this.polarToCartesian(t,e,this.margin,r+o),o=this.polarToCartesian(e.x,e.y,c,r+o),n=this.describeArc(e.x,e.y,i,s,r,n),n=this.createSVGElement("path",Object.assign({},this.getAttributes,{d:n}));return l.push(n),a.label&&(n=(null===(n=null==a?void 0:a.icon)||void 0===n?void 0:n.height)||0,l.push(this.createSVGText(o.x,o.y+n/2,a.label,Object.assign({},this.defaultSVGAttributes,this.SVGAttributes,{fill:this.SVGAttributes.color||this.defaultSVGAttributes.color})))),a.icon&&l.push(this.addIcon(a.icon,o)),o=this.createSVGGroup(l),a.link?this.createSVGLink(o,a.link):o}get name(){return this._name}get fontSize(){return parseInt(`${this.getAttributes["font-size"]||11}`,10)}get getAttributes(){return Object.assign({},this.defaultSVGAttributes,this.SVGAttributes)}addIcon(t,{x:e,y:i}){var{width:s,height:r,url:t}=t,i={x:e-s/2,y:this.slice.label?i-r/2-this.getTextSize(this.slice.label):i-r/2};return this.createSVGImage(i.x,i.y,s,r,t)}getTextSize(t){return t.split(" ").length*this.fontSize/2}}class MiddleButton extends SVG{constructor(t,e,i,s){super(s),this.backgroundColor="#FFFFFF",this.sliceMargin=4,this.textColor="#FFFFFF",this.options=s,this.middleButton=t,this.radius=t.radius||s.centerSize,this.x=e,this.y=i,this._name=this.middleButton.name,this.SVGAttributes=this.parseAttributes(t.svgAttributes||{}),this.defaultSVGAttributes=this.parseAttributes(s.svgAttributes||{}),this.SVGElement=this.createMiddleButton(this.x,this.y,this.radius,s)}toSVG(){return this.SVGElement}get name(){return this._name}get getAttributes(){return Object.assign({},this.defaultSVGAttributes,this.SVGAttributes)}createMiddleButton(t,e,i,s){var r=this.middleButton;const n=[];i=this.createSVGCircle(t,e,i,{fill:this.SVGAttributes.fill,color:this.textColor});return n.push(i),r.label&&n.push(this.createSVGText(t,e,r.label,Object.assign({},this.defaultSVGAttributes,this.SVGAttributes,{fill:this.SVGAttributes.color}))),r.icon&&n.push(this.addIcon(r.icon,{x:t,y:e})),e=this.createSVGGroup(n),r.link?this.createSVGLink(e,r.link):e}addIcon(t,{x:e,y:i}){var{width:s,height:r,url:n}=t,t=parseInt(this.getAttributes["font-size"].toString(),10),i={x:e-s/2,y:this.middleButton.label?i-r-t:i-r/2};return this.createSVGImage(i.x,i.y,s,r,n)}}class EventEmitter{constructor(){this.events={}}on(t,e){return"object"!=typeof this.events[t]&&(this.events[t]=[]),this.events[t].push(e),()=>this.removeListener(t,e)}removeListener(t,e){"object"!=typeof this.events[t]||-1<(e=this.events[t].indexOf(e))&&this.events[t].splice(e,1)}removeAllListeners(){Object.keys(this.events).forEach(t=>this.events[t].splice(0,this.events[t].length))}emit(t,...e){"object"==typeof this.events[t]&&[...this.events[t]].forEach(t=>t.apply(this,e))}once(t,e){const i=this.on(t,(...t)=>{i(),e.apply(this,t)});return i}}class RadialMenu extends EventEmitter{constructor(t,e){super(),this.SVGSlices=[],this.margin=0;var{centerSize:i,width:s,height:r,slices:n,sliceSize:h,middleButton:a,margin:l,css:c}=e;this.SVGObject=new SVG(Object.assign({width:`${s}px`,height:`${r}px`},c||{})),this.SVGElement=this.SVGObject.SVGElement,this.parentElement=t,this.options=e,this.width=s,this.height=r,this.slices=n,this.sliceSize=h,this.centerSize=i,this.middleButton=a||{},this.margin=l||this.margin,this.SVGAttributes=e.svgAttributes||{},this.generateMenu()}generateMenu(){let t;this.drawLevel(this.slices),this.SVGSlices.forEach(t=>{this.addEvents(t),this.SVGElement.appendChild(t.toSVG())}),this.middleButton&&(t=new MiddleButton(this.middleButton,this.width/2,this.height/2,this.options),this.addEvents(t),this.SVGElement.appendChild(t.toSVG())),this.parentElement.innerHTML="",this.parentElement.appendChild(this.SVGElement)}drawLevel(t,r=this.centerSize,n=0,e=360){const h=[];var i=t.filter(({radius:t})=>t).length;const a=(e-t.map(({radius:t})=>t||0).reduce((t,e)=>t+e,0)-n)/(t.length-i),l=this.width/2,c=this.height/2;t.forEach(t=>{var e=r,i=t.radius||a,s=t.slices;h.push(new Segment(t,l,c,e,n,i,this.options)),e=e+((null==t?void 0:t.size)||this.sliceSize)+this.margin,s&&this.drawLevel(s,e,n,n+i),n+=i}),this.SVGSlices=this.SVGSlices.concat([],h)}addEvents(e){const t=e.toSVG(),{name:i}=e;t.addEventListener("click",t=>{this.emit("click",{event:t,segmentObject:e,name:i})}),t.addEventListener("dbclick",t=>{this.emit("dbclick",{event:t,segmentObject:e,name:i})}),t.addEventListener("contextmenu",t=>{this.emit("contextmenu",{event:t,segmentObject:e,name:i})})}}export default RadialMenu;
class SVG{constructor(t){this.SVGElement=this.createSVGElement("svg",t)}createSVGElement(t,e={}){t=document.createElementNS("http://www.w3.org/2000/svg",t);return this.SetSVGAttributes(t,e),t}SetSVGAttributes(t,e){for(var i in e)t.setAttribute(i,`${e[i]}`)}parseAttributes(t){return Object.fromEntries(Object.entries(t).filter(([,t])=>t).map(([t,e])=>[[t.replace(/\B(?:([A-Z])(?=[a-z]))|(?:(?<=[a-z0-9])([A-Z]))/g,"-$1$2").toLowerCase()],e]))}createSVGCircle(t,e,i,s={}){var r=this.createSVGElement("circle",s);return this.SetSVGAttributes(r,Object.assign({cx:t,cy:e,r:i},s)),r}createSVGImage(t,e,i,s,r){const n=document.createElementNS("http://www.w3.org/2000/svg","image");return n.setAttribute("x",`${t}px`),n.setAttribute("y",`${e}px`),n.setAttribute("width",`${i}px`),n.setAttribute("height",`${s}px`),n.setAttribute("href",r),n}createSVGLink(t,e){const i=document.createElementNS("http://www.w3.org/2000/svg","a");return i.setAttributeNS("http://www.w3.org/1999/xlink","xlink:href",e),i.append(t),i}createSVGText(s,t,e,r={}){const i=e.split(" "),n=parseInt(`${r["font-size"]}`,10),h=1===i.length?n/2:n/2*-i.length+n;e=i.map((t,e)=>{const i=this.createSVGElement("tspan",r);e=e?n:h;return i.setAttribute("dy",`${e}px`),i.setAttribute("x",`${s}px`),i.removeAttribute("y"),i.textContent=t,i});return this.createSVGGroup(e,"text",{x:s,y:t,dy:0})}createSVGGroup(t,e="g",i={}){const s=this.createSVGElement(e,i);return t.forEach(t=>{s.appendChild(t)}),s}describeArc(t,e,i,s,r,n){const h=this.polarToCartesian(t,e,i,n),a=this.polarToCartesian(t,e,i,r),o=this.polarToCartesian(t,e,i+s,n),l=this.polarToCartesian(t,e,i+s,r),c=n-r<=180?"0":"1";return["M",o.x,o.y,"A",i+s,i+s,0,c,0,l.x,l.y,"L",a.x,a.y,"A",i,i,0,c,1,h.x,h.y,"L",o.x,o.y,"Z"].join(" ")}polarToCartesian(t,e,i,s){s=(s-90)*Math.PI/180;return{x:t+i*Math.cos(s),y:e+i*Math.sin(s)}}}class Segment extends SVG{constructor(t,e,i,s,r,n,h){super(h),this.backgroundColor="#FFFFFF",this.margin=0,this.textColor="#FFFFFF",this.innerPosition=2;var{sliceSize:a,margin:o}=h;this.options=h,this.slice=t,this._name=t.name,this.size=t.size||a,this.startFrom=s,this.radiusStart=r,this.radiusEnd=r+n,this.x=e,this.y=i,this.margin=o||this.margin,this.SVGAttributes=this.parseAttributes(t.svgAttributes||{}),this.defaultSVGAttributes=this.parseAttributes(h.svgAttributes||{}),this.innerPosition=t.innerPosition||h.innerPosition||this.innerPosition,360<=this.radiusEnd-this.radiusStart&&(this.radiusEnd=359.999,this.margin=0),this.SVGElement=this.createSlice(this.x,this.y,this.startFrom,this.size,this.radiusStart,this.radiusEnd,this.options)}toSVG(){return this.SVGElement}createSlice(t,e,i,s,r,n,h){var a=this.slice;const o=[];var l=s/this.innerPosition+i,c=(n-r)/2,e=this.polarToCartesian(t,e,this.margin,r+c),c=this.polarToCartesian(e.x,e.y,l,r+c),n=this.describeArc(e.x,e.y,i,s,r,n),n=this.createSVGElement("path",Object.assign({},this.getAttributes,{d:n}));return o.push(n),a.label&&(n=(null===(n=null==a?void 0:a.icon)||void 0===n?void 0:n.height)||0,o.push(this.createSVGText(c.x,c.y+n/2,a.label,Object.assign({},this.defaultSVGAttributes,this.SVGAttributes,{fill:this.SVGAttributes.color||this.defaultSVGAttributes.color})))),a.icon&&o.push(this.addIcon(a.icon,c)),c=this.createSVGGroup(o),a.link?this.createSVGLink(c,a.link):c}get name(){return this._name}get fontSize(){return parseInt(`${this.getAttributes["font-size"]||11}`,10)}get getAttributes(){return Object.assign({},this.defaultSVGAttributes,this.SVGAttributes)}addIcon(t,{x:e,y:i}){var{width:s,height:r,url:t}=t,i={x:e-s/2,y:this.slice.label?i-r/2-this.getTextSize(this.slice.label):i-r/2};return this.createSVGImage(i.x,i.y,s,r,t)}getTextSize(t){return t.split(" ").length*this.fontSize/2}}class MiddleButton extends SVG{constructor(t,e,i,s){super(s),this.backgroundColor="#FFFFFF",this.sliceMargin=4,this.textColor="#FFFFFF",this.options=s,this.middleButton=t,this.radius=t.radius||s.centerSize,this.x=e,this.y=i,this._name=this.middleButton.name,this.SVGAttributes=this.parseAttributes(t.svgAttributes||{}),this.defaultSVGAttributes=this.parseAttributes(s.svgAttributes||{}),this.SVGElement=this.createMiddleButton(this.x,this.y,this.radius,s)}toSVG(){return this.SVGElement}get name(){return this._name}get getAttributes(){return Object.assign({},this.defaultSVGAttributes,this.SVGAttributes)}createMiddleButton(t,e,i,s){var r=this.middleButton;const n=[];i=this.createSVGCircle(t,e,i,{fill:this.SVGAttributes.fill,color:this.textColor});return n.push(i),r.label&&n.push(this.createSVGText(t,e,r.label,Object.assign({},this.defaultSVGAttributes,this.SVGAttributes,{fill:this.SVGAttributes.color}))),r.icon&&n.push(this.addIcon(r.icon,{x:t,y:e})),e=this.createSVGGroup(n),r.link?this.createSVGLink(e,r.link):e}addIcon(t,{x:e,y:i}){var{width:s,height:r,url:n}=t,t=parseInt(this.getAttributes["font-size"].toString(),10),i={x:e-s/2,y:this.middleButton.label?i-r-t:i-r/2};return this.createSVGImage(i.x,i.y,s,r,n)}}class EventEmitter{constructor(){this.events={}}on(t,e){return"object"!=typeof this.events[t]&&(this.events[t]=[]),this.events[t].push(e),()=>this.removeListener(t,e)}removeListener(t,e){"object"!=typeof this.events[t]||-1<(e=this.events[t].indexOf(e))&&this.events[t].splice(e,1)}removeAllListeners(){Object.keys(this.events).forEach(t=>this.events[t].splice(0,this.events[t].length))}emit(t,...e){"object"==typeof this.events[t]&&[...this.events[t]].forEach(t=>t.apply(this,e))}once(t,e){const i=this.on(t,(...t)=>{i(),e.apply(this,t)});return i}}class RadialMenu extends EventEmitter{constructor(t,e){super(),this.innerPosition=2,this.SVGSlices=[],this.margin=0;var{centerSize:i,width:s,height:r,slices:n,sliceSize:h,middleButton:a,margin:o,css:l,innerPosition:c}=e;this.SVGObject=new SVG(Object.assign({width:`${s}px`,height:`${r}px`},l||{})),this.SVGElement=this.SVGObject.SVGElement,this.innerPosition=c||this.innerPosition,this.parentElement=t,this.options=e,this.width=s,this.height=r,this.slices=n,this.sliceSize=h,this.centerSize=i,this.middleButton=a||{},this.margin=o||this.margin,this.SVGAttributes=e.svgAttributes||{},this.generateMenu()}generateMenu(){let t;this.drawLevel(this.slices),this.SVGSlices.forEach(t=>{this.addEvents(t),this.SVGElement.appendChild(t.toSVG())}),this.middleButton&&(t=new MiddleButton(this.middleButton,this.width/2,this.height/2,this.options),this.addEvents(t),this.SVGElement.appendChild(t.toSVG())),this.parentElement.innerHTML="",this.parentElement.appendChild(this.SVGElement)}drawLevel(t,r=this.centerSize,n=0,e=360){const h=[];var i=t.filter(({radius:t})=>t).length;const a=(e-t.map(({radius:t})=>t||0).reduce((t,e)=>t+e,0)-n)/(t.length-i),o=this.width/2,l=this.height/2;t.forEach(t=>{var e=r,i=t.radius||a,s=t.slices;h.push(new Segment(t,o,l,e,n,i,this.options)),e=e+((null==t?void 0:t.size)||this.sliceSize)+this.margin,s&&this.drawLevel(s,e,n,n+i),n+=i}),this.SVGSlices=this.SVGSlices.concat([],h)}addEvents(e){const t=e.toSVG(),{name:i}=e;t.addEventListener("click",t=>{this.emit("click",{event:t,segmentObject:e,name:i})}),t.addEventListener("dbclick",t=>{this.emit("dbclick",{event:t,segmentObject:e,name:i})}),t.addEventListener("contextmenu",t=>{this.emit("contextmenu",{event:t,segmentObject:e,name:i})})}}export default RadialMenu;
{
"name": "@sfgrp/svg-radial-menu",
"version": "1.0.3",
"version": "1.0.4",
"description": "Library to create radial menus",

@@ -5,0 +5,0 @@ "main": "dist/svg-radial-menu.esm.js",

@@ -14,2 +14,3 @@ import { SVG } from './utils/svg'

centerSize: number
innerPosition: number = 2
middleButton: CircleButton

@@ -30,3 +31,3 @@ parentElement: HTMLElement

super()
const { centerSize, width, height, slices, sliceSize, middleButton, margin, css } = opts
const { centerSize, width, height, slices, sliceSize, middleButton, margin, css, innerPosition } = opts

@@ -41,2 +42,3 @@ this.SVGObject = new SVG({

this.innerPosition = innerPosition || this.innerPosition
this.parentElement = element

@@ -43,0 +45,0 @@ this.options = opts

@@ -19,2 +19,3 @@ import { Slice, SliceIcon, RadialMenuOptions, SVGAttribute } from './types'

private y: number
private innerPosition: number = 2

@@ -37,2 +38,3 @@ constructor (slice: Slice, x: number, y: number, startFrom: number, radiusStart: number, radiusSlice: number, opts: RadialMenuOptions) {

this.defaultSVGAttributes = this.parseAttributes(opts.svgAttributes || {})
this.innerPosition = slice.innerPosition || opts.innerPosition || this.innerPosition

@@ -54,3 +56,3 @@ if ((this.radiusEnd - this.radiusStart) >= 360) {

const elements: Array<SVGElement> = []
const middleSlice = (size / 2) + startFrom
const middleSlice = (size / this.innerPosition) + startFrom
const middleRadius = (radiusEnd - radiusStart) / 2

@@ -57,0 +59,0 @@ const distanceCoordinates = this.polarToCartesian(x, y, this.margin, radiusStart + middleRadius)

@@ -8,2 +8,3 @@ export type Slice = {

radius?: number
innerPosition?: number,
svgAttributes?: SVGAttribute,

@@ -19,2 +20,3 @@ slices?: Array<Slice>

margin?: number,
innerPosition?: number,
css: SVGAttribute,

@@ -21,0 +23,0 @@ middleButton?: CircleButton,

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc