js-superellipse 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -0
- package/dist/superellipse.js +4228 -0
- package/dist/superellipse.min.js +46 -0
- package/package.json +20 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @module sj-superellipse
|
|
4
|
+
* @version 1.0.0
|
|
5
|
+
* @author f4n70m
|
|
6
|
+
* @license MIT
|
|
7
|
+
*
|
|
8
|
+
* @description
|
|
9
|
+
* Библиотека для применения суперэллипсов к произвольным DOM-элементам.
|
|
10
|
+
* Позволяет плавно изменять форму углов от вогнутых прямоугольных (-2) до выгнутых прямоугольных (2),
|
|
11
|
+
* проходя через скос (0), круглые углы (±G) и классический суперэллипс (1).
|
|
12
|
+
*
|
|
13
|
+
* Особенности:
|
|
14
|
+
* - Два режима работы: `clip-path` (легковесный) и `svg-layer` (полнофункциональный с поддержкой границ и теней).
|
|
15
|
+
* - Автоматическое отслеживание изменений размеров, стилей, видимости и атрибутов элемента.
|
|
16
|
+
* - Поддержка `border-radius`, `border`, `box-shadow`, `background` в режиме `svg-layer`.
|
|
17
|
+
* - Несколько способов инициализации: через селектор, элемент, коллекцию или глобальную функцию.
|
|
18
|
+
* - Умное кэширование стилей для минимизации перерисовок.
|
|
19
|
+
*
|
|
20
|
+
* @typicalname superellipse
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* // Инициализация элемента с режимом svg-layer (по умолчанию)
|
|
24
|
+
* const element = document.querySelector('.my-element');
|
|
25
|
+
* const controller = element.superellipseInit({
|
|
26
|
+
* curveFactor: 1.2,
|
|
27
|
+
* precision: 3
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* // Изменение коэффициента кривизны
|
|
31
|
+
* controller.setCurveFactor(0.8);
|
|
32
|
+
*
|
|
33
|
+
* // Переключение режима
|
|
34
|
+
* controller.switchMode('clip-path');
|
|
35
|
+
*
|
|
36
|
+
* // Инициализация всех элементов с классом .rounded
|
|
37
|
+
* superellipseInit('.rounded', { mode: 'clip-path' });
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* // Генерация только SVG-пути без привязки к DOM
|
|
41
|
+
* import { jsse_generateSuperellipsePath } from 'js-superellipse';
|
|
42
|
+
* const path = jsse_generateSuperellipsePath(200, 150, 20, 1.5);
|
|
43
|
+
* document.querySelector('path').setAttribute('d', path);
|
|
44
|
+
*/
|
|
45
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).Superellipse={})}(this,function(t){"use strict";const e={list:{},isSupport(t){if(void 0===this.list[t])try{const e=`selector(${t})`;this.list[t]=CSS.supports(e)}catch(e){this.list[t]=!1}return this.list[t]}},s={t:[],set(t){this.t.push(t),console.debug("[JSSE]","[DEBUG]",!0,"\n\t",{element:t})},debug(t,...e){t.element?this.t.includes(t.element)&&console.debug("[JSSE]",`[${t?.label??"DEBUG"}]`,...e,"\n\t",{element:t.element}):console.debug("[JSSE]",`[${t?.label??"DEBUG"}]`,...e)},warn(t,...e){t.element?this.t.includes(t.element)&&console.warn("[JSSE]",`[${t?.label??"DEBUG"}]`,...e,"\n\t",{element:t.element}):console.warn("[JSSE]",`[${t?.label??"DEBUG"}]`,...e)}};class i{i;h;o;l;constructor(t){this.i=t.combinator;const e=":root"===t.full;this.o=e||t.clean?t.clean:"*",this.h=e||t.clean?t.full:`*${t.full}`,this.l=[...new Set(t.pseudo)]}getCombinator(){return this.i}getFull(){return this.h}getClean(){return this.o}getPseudoList(){return this.pseudo}hasPseudo(t){return this.l.includes(t)}hasHover(){return this.hasPseudo(":hover")}}class r extends Array{static#t(t){return t instanceof i}push(...t){const e=t.filter(t=>r.#t(t));return super.push(...e)}unshift(...t){const e=t.filter(t=>r.#t(t));return super.unshift(...e)}splice(t,e,...s){const i=s.filter(t=>r.#t(t));return super.splice(t,e,...i)}getTarget(){return this[this.length-1]}getTriggerIndexList(){return this.reduce((t,e,s)=>(e.hasHover()&&t.push(s),t),[])}hasTrigger(){return this.getTriggerIndexList().length>0}targetIsTriggered(){return this.getTarget().hasHover()}}class h{u;_;p;m;S;v;T;L;constructor(t,e,s){this.u=s,this._=t,this.p=null,this.m=e,this.S=null,this.v=null,this.T=null,this.L=null}getSelector(){return this._}getStyles(){return null===this.S&&(this.S=this.C()),this.S}getFragments(){return null===this.p&&(this.p=this.M(this._)),this.p}matchMedia(){return!this.u||window.matchMedia(this.u).matches}getTriggerParts(){if(null===this.L){this.L=[];const t=this.getFragments(),e=t.getTriggerIndexList();for(const s of e){const e={parent:"",neighbor:null,child:null};for(let i=0;i<t.length;i++){const r=t[i];if(i<=s){if(e.parent+=r.getCombinator()+r.getClean(),i+1<t.length){const s=t[i+1],r=s.getCombinator();[" + "," ~ "].includes(r)&&(e.neighbor={combinator:r,clean:s.getClean()},i++)}}else e.child||(e.child=""),e.child+=r.getCombinator()+r.getClean()}this.L.push(e)}}return this.L}getTriggerFragments(){if(null===this.v){this.v=new r;const t=this.getFragments(),e=t.getTriggerIndexList();for(const s of e){const e=t[s];this.v.push(e)}}return this.v}C(){const t={};if(this.m.cssText){const e=this.m.cssText.split(";");for(const s of e){const e=s.indexOf(":");if(e>0){const i=s.substring(0,e).trim(),r=s.substring(e+1).trim();i&&r&&(t[i]=r)}}}return t}M(t){const e=t,s=new r;let h={combinator:"",full:"",clean:"",pseudo:[]},n="",o=0;for(;o<e.length;)if(":"===e[o])if(o>0&&":"===e[o+1]&&(""===h.combinator&&(h.combinator=" "),s.push(new i(h)),h={combinator:"",full:"",clean:"",pseudo:[]}),":"===e[o+1]||o>0&&":"===e[o-1])h.full+=e[o],h.clean+=e[o],o++;else{n+=e[o];let s=o+1;for(;s<e.length&&/[\w-]/.test(e[s]);)n+=e[s],s++;if("("===e[s]){n+=e[s];let i=1,r=s+1;for(;r<t.length&&i;)"("===t[r]?i++:")"===t[r]&&i--,n+=e[r],r++;h.pseudo.push(n),h.full+=n,n="",o=r}else h.pseudo.push(n),h.full+=n,n="",o=s}else if(" "===e[o]){s.push(new i(h));let t=" ";/[\>\~\+]/.test(e[o+1])&&" "===e[o+2]&&(t=e[o]+e[o+1]+e[o+2],o+=2),h={combinator:t,full:"",clean:"",pseudo:[]},o++}else h.full+=e[o],h.clean+=e[o],o++;return s.push(new i(h)),s}}class n extends Array{static#t(t){return t instanceof h}push(...t){const e=t.filter(t=>n.#t(t));return super.push(...e)}unshift(...t){const e=t.filter(t=>n.#t(t));return super.unshift(...e)}splice(t,e,...s){const i=s.filter(t=>n.#t(t));return super.splice(t,e,...i)}getSelectorsWithHover(){return this.filter(t=>t.getFragments().hasTrigger())}}const o=new WeakMap,a=new class{$;O;constructor(){this.$=null,this.O=!1}getSelectors(){return this.A(),this.$}getSelectorsHasHover(){return this.A(),this.$.getSelectorsWithHover()}getTargetSelectors(t,e={}){this.A();const s=this.R(),i=this.getSelectors();for(const r of i){const i=r.getFragments(),h=i.getTarget().getClean();if(!h)continue;const n=t.matches(h);i.hasTrigger(),n&&(!e?.selectorHasHover||e.selectorHasHover&&i.hasTrigger())&&s.push(r)}return s}reset(){this.$=null,this.O=!1}A(){this.O||(this.j(),this.O=!0)}j(){this.$=this.R(),this.I(),s.debug({label:"STYLESHEET"},"[LOADED]")}R(){return new n}I(){for(const t of document.styleSheets)try{const e=t.cssRules||t.rules;if(!e)continue;for(const i of e)if(i.type===CSSRule.STYLE_RULE)this.$.push(...this.H(i));else if(i.type===CSSRule.MEDIA_RULE)try{for(const t of i.cssRules)this.$.push(...this.H(t,i.media.mediaText))}catch(e){s.warn({label:"STYLESHEET"},`Error processing @media rules from ${t.href||"inline"}:`,e.message)}}catch(e){"SecurityError"===e.name?s.warn({label:"STYLESHEET"},"Cannot access stylesheet rules:",`\n${t.href||"inline / blob"}.`,"\nCause: CORS or file:// protocol.","\nTo fix this, use a local server (http://) or add the crossorigin attribute."):"InvalidAccessError"===e.name?s.warn({label:"STYLESHEET"},`The stylesheet ${t.href||"inline"} has not yet loaded or has invalid access.`):s.warn({label:"STYLESHEET"},`Unknown error reading ${t.href||"inline"}:`,e.message)}}H(t,e=!1){const s=[],i=t.selectorText,r=this.D(i),n=[...new Set(r)];for(const i of n)s.push(new h(i,t.style,e));return s}D(t){const e=[];let s="",i=0,r=!1,h=!1;for(let n=0;n<t.length;n++){const o=t[n];h?(s+=o,h=!1):"\\"!==o?'"'!==o&&"'"!==o?(r||("("===o?i++:")"===o&&i--),","!==o||0!==i||r?s+=o:(e.push(s.trim()),s="")):(r=!r,s+=o):(h=!0,s+=o)}return""!==s.trim()&&e.push(s.trim()),e}},l=new WeakMap,u={t:{},get(t){return this.t[t]},set(t,e){this.has(t)&&this.unset(t),this.t[t]={element:e,count:1},document.head.appendChild(e)},unset(t){this.t[t].element.remove(),delete this.t[t]},has(t){return void 0!==this.t[t]}},c={k:0,increment(){this.k++},decrement(){this.k--},get value(){return this.k}};function d(t,e,s){if(Math.abs(s)<1e-10)throw new Error("L2 не может быть нулевым");const i=(4*s-t*(4-3*e))/(3*s);return Math.min(i,1)}function _(){return 4/3*(Math.sqrt(2)-1)}function p(t,e,s,i,r=2){if(t<=0||e<=0)return"M0,0";("number"!=typeof s||isNaN(s))&&(s=0);const h=_(),n=8-4*Math.sqrt(2);let o=t>=e?t:e,a=Math.abs(i),l=i>=0?1:-1,u=t/2,c=e/2,p=Math.min(u,c),f=Math.min(s,p),g=Math.abs(u-c);u>=c?u=c+Math.min(p/4,g/4):c=u+Math.min(p/4,g/4);let m=Math.min(f,u),S=Math.min(f,c),v=0,y=0,E=0,b=0,T=0,L=0;if(0!==f){let t=1,e=u/m,s=c/S,i=l>0?Math.min(e,n):1,r=l>0?Math.min(s,n):1;d(t,h,i),d(t,h,r);let o,_,p=1/n*i,f=1/n*r,g=Math.max((Math.min(a,1)-h)/(1-h),0),w=1+(i-1)*g,C=1+(r-1)*g,M=0,$=0;if(a<=h)o=_=a;else{let e=d(t,h,w),s=d(t,h,C);if(a<=1)o=e,_=s;else{p=h+1/(i/n)*(1-h),f=h+1/(r/n)*(1-h);let e=Math.min((a-1)/(p-1),1),s=C+(n-C)*Math.min((a-1)/(f-1),1),l=d(t,h,w+(n-w)*e),u=d(t,h,s);o=Math.min(l,1),_=Math.min(u,1),a>p&&(M=(a-p)/(2-p)),a>f&&($=(a-f)/(2-f))}}E=w*(1-M),b=C*(1-$),T=w*M,L=C*$,v=E*o,y=b*_}let w,C=o,M=t/o,$=e/o,O=f/o,A=0,R=0,j={x:M,y:0},I={x:M,y:$},H={x:0,y:$};w=l>=0?["M",A,R+(L+b)*O,"L",A,R+b*O,"C",A,R+(b-y)*O,A+(E-v)*O,R,A+E*O,R,"L",A+(T+E)*O,R,"L",j.x-(T+E)*O,j.y,"L",j.x-E*O,j.y,"C",j.x-(E-v)*O,j.y,j.x,j.y+(b-y)*O,j.x,j.y+b*O,"L",j.x,j.y+(L+b)*O,"L",I.x,I.y-(L+b)*O,"L",I.x,I.y-b*O,"C",I.x,I.y-(b-y)*O,I.x-(E-v)*O,I.y,I.x-E*O,I.y,"L",I.x-(T+E)*O,I.y,"L",H.x+(T+E)*O,H.y,"L",H.x+E*O,H.y,"C",H.x+(E-v)*O,H.y,H.x,H.y-(b-y)*O,H.x,H.y-b*O,"L",H.x,H.y-(L+b)*O,"Z"]:["M",A,R+(L+b)*O,"L",A+T*O,R+(L+b)*O,"C",A+(T+v)*O,R+(L+b)*O,A+(T+E)*O,R+(L+y)*O,A+(T+E)*O,R+L*O,"L",A+(T+E)*O,R,"L",j.x-(T+E)*O,j.y,"L",j.x-(T+E)*O,j.y+L*O,"C",j.x-(T+E)*O,j.y+(L+y)*O,j.x-(T+v)*O,j.y+(L+b)*O,j.x-T*O,j.y+(L+b)*O,"L",j.x,j.y+(L+b)*O,"L",I.x,I.y-(L+b)*O,"L",I.x-T*O,I.y-(L+b)*O,"C",I.x-(T+v)*O,I.y-(L+b)*O,I.x-(T+E)*O,I.y-(L+y)*O,I.x-(T+E)*O,I.y-L*O,"L",I.x-(T+E)*O,I.y,"L",H.x+(T+E)*O,H.y,"L",H.x+(T+E)*O,H.y-L*O,"C",H.x+(T+E)*O,H.y-(L+y)*O,H.x+(T+v)*O,H.y-(L+b)*O,H.x+T*O,H.y-(L+b)*O,"L",H.x,H.y-(L+b)*O,"Z"];const x=w.map(t=>"number"==typeof t?function(t,e=2){const s=10**e;return(Math.round(t*s)/s).toFixed(e)}(t*C,r):t).join(" ");return x}class f{V;P;F;N={width:0,height:0};G;U;S;Y;B;constructor(t){this.V=t,this.F=!1,this.G=_(),this.U=2,this.j()}activate(){this.isActivated()||(s.debug({label:"MODE",element:this.V},`activate(${this.W()})`),this.J(),this.Z(!0),this.K(),this.X(),this.q())}deactivate(){this.isActivated()&&(s.debug({label:"MODE",element:this.V},`deactivate(${this.W()})`),this.Z(!1),this.tt(),this.q())}update(){s.debug({label:"MODE",element:this.V},"update()"),this.J(),this.X(),this.q()}updateSize(){this.et(),this.X(),this.q()}updateStyles(){s.debug({label:"MODE",element:this.V},"updateStyles()"),this.st(),this.X(),this.q()}updateCurveFactor(t){this.setCurveFactor(t),this.X(),this.q()}updatePrecision(t){this.setPrecision(t),this.X(),this.q()}setCurveFactor(t){this.G=t}setPrecision(t){this.U=t}getPath(){return this.Y}isActivated(){return this.F}destroy(){this.deactivate(),this.it(),this.rt()}j(){this.ht=Math.random().toString(36).slice(2,10),this.nt(),this.ot(),this.lt(),this.ut(),this.P=!0}Z(t){this.F=t,t?this.ct():this.dt()}J(){this.st(),this.et()}X(){this._t()}q(){this.ft()}W(){return"clip-path"}gt(){return{transition:"unset"}}St(){return{"border-radius":"0px"}}K(){}tt(){}ot(){this.V.setAttribute("data-jsse-mode",this.W())}it(){this.V.removeAttribute("data-jsse-mode")}ct(){this.V.setAttribute("data-jsse-activated",!0)}dt(){this.V.removeAttribute("data-jsse-activated")}vt(){this.V.setAttribute("data-jsse-reading",!0)}yt(){this.V.removeAttribute("data-jsse-reading")}Et(){const t=this.W();if(u.has(t))u.get(t).count++;else{const e=this.bt(t);u.set(t,e)}s.debug({label:"MODE",element:this.V},"[RESET STYLES]","INIT")}rt(){const t=this.W();if(!u.has(t))return;const e=u.get(t);e.count--,s.debug({label:"MODE",element:this.V},"[RESET STYLES]","[DESTROY]"),e.count<=0&&u.unset(t)}Tt(t){let e="";const s=this.St();e+=`*:hover [data-jsse-mode="${t}"][data-jsse-activated=true],`,e+=`[data-jsse-mode="${t}"][data-jsse-activated=true]:hover,`,e+=`[data-jsse-mode="${t}"][data-jsse-activated=true]`,e+="{";for(const t in s)""!==s[t]&&(e+=`\n\t${t}: ${s[t]} !important;`);e+="\n}",e+="\n";const i=this.gt();e+=`*:hover [data-jsse-mode="${t}"][data-jsse-reading=true],`,e+=`[data-jsse-mode="${t}"][data-jsse-reading=true]:hover,`,e+=`[data-jsse-mode="${t}"][data-jsse-reading=true]`,e+="{";for(const t in i)""!==i[t]&&(e+=`\n\t${t}: ${i[t]} !important;`);return e+="\n}",e}bt(t){const e=this.Tt(t),s=document.createElement("style");return s.setAttribute("id",`jsse__css_${t}`),s.textContent=e,s}st(){s.debug({label:"MODE",element:this.V},"_updateCapturedStyles()");const t=this.Lt();this.S.computed=t}Lt(t=!0){const e=this.V.hasAttribute("data-jsse-activated");e&&t&&this.dt(),this.vt();const s=this.wt();return e&&t&&this.ct(),this.yt(),s}wt(){const t={},e=getComputedStyle(this.V);for(const s of this.Ct())t[s]=e.getPropertyValue(s);return t}Mt(t){if("computed"in this.S&&t in this.S.computed)return this.S.computed[t]}Ct(){return Object.keys(this.St())}nt(){this.S=l.get(this.V),this.Et()}lt(){this.et()}et(){const t=this.V.getBoundingClientRect();this.N.width=t.width,this.N.height=t.height}ut(){this.$t()}$t(){this.B=this.V.style.getPropertyValue("clip-path")}_t(){this.Ot()}Ot(){if(!(this.N.width>0&&this.N.height>0))return void(this.Y="none");const t=this.Mt("border-radius"),e=t?parseFloat(t):0;this.Y=p(this.N.width,this.N.height,e,this.G,this.U)}ft(){this.isActivated()?this.At():this.Rt()}At(){if(this.Y&&"none"!==this.Y){const t=`path("${this.Y}")`;this.V.style.getPropertyValue("clip-path")!==t&&this.V.style.setProperty("clip-path",t)}else"none"!==this.V.style.getPropertyValue("clip-path")&&this.V.style.setProperty("clip-path","none")}Rt(){this.B?this.V.style.setProperty("clip-path",this.B):this.V.style.removeProperty("clip-path")}}class g extends f{jt={};It;constructor(t,e=!1){super(t,e),this.Ht(),this.xt()}q(){this.Dt(),this.ft()}W(){return"svg-layer"}St(){return{background:"none","border-color":"transparent","border-width":"","border-width":"0px","border-radius":"0px","box-shadow":"unset",position:"relative"}}kt(){return{position:"absolute",top:"0px",left:"0px",width:"100%",height:"100%","pointer-events":"none"}}Vt(){return["background","box-shadow"]}Pt(t,e){const s=this.Ct();for(const i of s){const s=t[i],r=e.style.getPropertyValue(i);void 0!==s?r!==s&&e.style.setProperty(i,s):""!==r&&e.style.removeProperty(i)}}Dt(){this.isActivated()&&(this.Ft(),this.Nt(),this.Gt())}Ft(){const t=this.Ut(),e=this.jt.svgLayerDiv;this.Pt(t,e)}Ut(){const t={},e=this.Vt();for(const s of e){const e=this.Mt(s);void 0!==e&&(t[s]=e)}return t}Nt(){const t=this.jt.svgLayerBorder,e=this.Mt("border-color");t.setAttribute("stroke",e);const s=this.Mt("border-width"),i=s?2*parseFloat(s):0;t.setAttribute("stroke-width",i);const r=this.Mt("border-style");this.Yt(r,t)}Bt(t,e){t.setAttribute("stroke-dasharray",e)}zt(t,e){t.setAttribute("stroke-linecap",e)}Wt(t,e){t.setAttribute("stroke-opacity",e)}Yt(t,e){switch(e.removeAttribute("stroke-dasharray"),e.removeAttribute("stroke-linecap"),e.removeAttribute("stroke-linejoin"),t){case"solid":break;case"dotted":this.Bt(e,"0, 8"),this.zt(e,"round");break;case"dashed":this.Bt(e,"10, 6");break;case"double":s.warn({label:"MODE SVG LAYER",element:this.V},"«border-style: double» is not supported");break;case"groove":this.Bt(e,"1, 2"),this.zt(e,"round");break;case"ridge":this.Bt(e,"3, 3");break;case"inset":this.Wt(e,"0.7");break;case"outset":this.Wt(e,"0.5");break;case"dash-dot":this.Bt(e,"15, 5, 5, 5");break;case"dash-dot-dot":this.Bt(e,"15, 5, 5, 5, 5, 5")}}Gt(){const t=this.Mt("box-shadow"),e=this.Jt(t),s=this.jt.svgLayer,i=this.jt.svgLayerGFilters,r=this.jt.svgLayerGShadows,h=this.jt.svgLayerPath;i.replaceChildren(),r.replaceChildren();const n=s.getAttribute("id"),o=h.getAttribute("id");for(let t=0;t<e.length;t++){if(e[t].inset)continue;const s=e[t];s.spreadRadius;const h=this.Zt("filter"),a=this.Zt("feGaussianBlur"),l=this.Zt("feOffset"),u=this.Zt("feFlood"),c=this.Zt("feComposite"),d=this.Zt("use"),_=`${n}__filter_${t}`,p=`${_}__blur`,f=`${_}__offset`,g=`${_}__color`,m=`${_}__shadow`,S=`${n}__shadow_${t}`;i.appendChild(h),h.setAttribute("id",_),h.setAttribute("x","-100%"),h.setAttribute("y","-100%"),h.setAttribute("width","300%"),h.setAttribute("height","300%"),h.appendChild(a),h.appendChild(l),h.appendChild(u),h.appendChild(c),a.setAttribute("in","SourceAlpha"),a.setAttribute("stdDeviation",s.blurRadius/2),a.setAttribute("result",p),l.setAttribute("dx",s.offsetX),l.setAttribute("dy",s.offsetY),l.setAttribute("in",p),l.setAttribute("result",f),u.style.setProperty("flood-color",s.color),u.setAttribute("result",g),c.setAttribute("in",g),c.setAttribute("in2",f),c.setAttribute("operator","in"),c.setAttribute("result",m),r.appendChild(d),d.setAttribute("href",`#${o}`),d.setAttribute("id",S),d.setAttribute("filter",`url(#${_})`)}}Jt(t){if(!t||"none"===t)return[];const e=[];let s="",i=0;for(let r of t)"("===r&&i++,")"===r&&i--,","===r&&0===i?(e.push(s.trim()),s=""):s+=r;return e.push(s.trim()),e.map(t=>{const e=t.match(/(?:rgba?\([^)]+\)|\S+)/g);if(!e)return null;const s={inset:!1,color:null,offsetX:0,offsetY:0,blurRadius:0,spreadRadius:0,originalColorFormat:null},i=e.indexOf("inset");-1!==i&&(s.inset=!0,e.splice(i,1));const r=e.find(t=>t.startsWith("rgb"));r&&(s.color=r,s.originalColorFormat=r,e.splice(e.indexOf(r),1));const h=e.map(t=>parseFloat(t)).filter(t=>!isNaN(t));return void 0!==h[0]&&(s.offsetX=h[0]),void 0!==h[1]&&(s.offsetY=h[1]),void 0!==h[2]&&(s.blurRadius=h[2]),void 0!==h[3]&&(s.spreadRadius=h[3]),s})}xt(){this.Kt(),this.Xt()}Zt(t){return document.createElementNS("http://www.w3.org/2000/svg",t)}qt(t){return document.createElement(t)}Xt(){if(this.jt.svgLayer)return;const t=this.ht,e=`jsse_${t}`,s=`jsse_${t}__clip`,i=`jsse_${t}__path`,r=`jsse_${t}__filters`,h=`jsse_${t}__shadows`,n=`jsse_${t}__div`,o=`jsse_${t}__border`,a=this.Zt("svg"),l=this.Zt("defs"),u=this.Zt("clipPath"),c=this.Zt("path"),d=this.Zt("g"),_=this.Zt("g"),p=this.Zt("foreignObject"),f=this.qt("div"),g=this.Zt("use");a.setAttribute("id",e),a.classList.add("jsse--svg-layer--bg"),a.setAttribute("viewBox",this.Qt()),a.setAttribute("preserveAspectRatio","none");const m=this.kt();for(const t in m)a.style.setProperty(t,m[t]);a.style.setProperty("overflow","visible"),a.appendChild(l),a.appendChild(_),a.appendChild(p),a.appendChild(g),l.appendChild(u),l.appendChild(d),u.setAttribute("id",s),u.appendChild(c),c.setAttribute("id",i),c.setAttribute("d",""),d.setAttribute("id",r),_.setAttribute("id",h),p.setAttribute("id",h),p.setAttribute("width","100%"),p.setAttribute("height","100%"),p.setAttribute("clip-path",`url(#${s})`),p.appendChild(f),f.setAttribute("id",n),f.style.setProperty("width","100%"),f.style.setProperty("height","100%"),g.setAttribute("id",o),g.setAttribute("href",`#${i}`),g.setAttribute("fill","none"),g.setAttribute("stroke",""),g.setAttribute("stroke-width","0"),g.setAttribute("clip-path",`url(#${s})`),this.jt.svgLayer=a,this.jt.svgLayerPath=c,this.jt.svgLayerGFilters=d,this.jt.svgLayerGShadows=_,this.jt.svgLayerDiv=f,this.jt.svgLayerBorder=g}Kt(){if(this.jt.innerWrapper)return;const t=this.qt("div");t.className="jsse--svg-layer--content",t.style.setProperty("position","relative"),this.jt.innerWrapper=t}K(){this.te(),this.ee()}tt(){this.se(),this.ie()}ee(){const t=this.jt.svgLayer;this.V.insertBefore(t,this.V.firstChild)}se(){const t=this.jt.svgLayer;t&&t.parentNode===this.V&&this.V.removeChild(t)}te(){const t=this.jt.innerWrapper,e=Array.from(this.V.childNodes);for(const s of e)t.appendChild(s);this.V.appendChild(t)}ie(){const t=this.jt.innerWrapper,e=Array.from(t.childNodes);for(const t of e)this.V.appendChild(t);this.V.removeChild(t)}Ht(){this.re()}_t(){super._t(),this.re()}re(){this.N.width>0&&this.N.height>0?this.It=`0 0 ${this.N.width} ${this.N.height}`:this.It="0 0 0 0"}Qt(){return this.It}At(){this.jt.svgLayer.setAttribute("viewBox",this.Qt());const t=this.jt.svgLayerPath;this.Y?t.setAttribute("d",this.Y):t.setAttribute("d","")}Rt(){this.jt.svgLayerPath.setAttribute("d",""),super.Rt()}}class m extends f{constructor(t,e=!1){super(t,e)}}class S{ht;he;ne;V;U;G;oe;ae;le;ue;ce;de=!1;_e;pe;fe;ge;me;Se;ve;ye;Ee;constructor(t,e={}){if(this.be(),this.Te()&&!e.force)return s.warn({label:"CONTROLLER",element:t},"The element is already initialized. Use {force:true} to recreate it."),this.Le();this.V=t;const i={mode:e.mode??"svg-layer",debug:e.debug??!1,curveFactor:e.curveFactor??_(),precision:e.precision??2};this.we(i.debug),s.debug({label:"CONTROLLER",element:this.V},"[SETTINGS]",i),this.G=i.curveFactor,this.U=i.precision,this.ve=!1,this.ye=!1,this._e=null,this.pe=null,this.fe=null,this.ge=null,this.Ce(),this.Me(),this.$e(),this.Oe(i.mode),this.Ae(),this.Re()}switchMode(t){return this.je(),this.Ie(),this.Oe(t),this.Ae(),this}isEnabled(){return this.ne.isActivated()}enable(){return this.Ae(),this}disable(){return this.je(),this}setCurveFactor(t){return this.G=t,this.ne.updateCurveFactor(t),this.He("update",{type:"curveFactor"}),this}setPrecision(t){return this.U=t,this.ne.updatePrecision(t),this}getPath(){return this.ne.getPath()}destroy(){return this.xe()}be(){this.ht=c.value,c.increment()}we(t){this.he=!!t,this.he&&s.set(this.V)}De(){return this.he}ke(){return"none"!==getComputedStyle(this.V).getPropertyValue("display")}xe(){this.Ve(),this.je(),this.Ie(),this.Pe(),this.Fe(),this.Ne(),this.Ge()}Ce(){this.Ee={update:[],activate:[],deactivate:[],error:[]}}on(t,e){return this.Ee[t]&&this.Ee[t].push(e),this}off(t,e){if(this.Ee[t]){const s=this.Ee[t].indexOf(e);-1!==s&&this.Ee[t].splice(s,1)}return this}He(t,e){this.Ee[t]&&this.Ee[t].forEach(s=>{try{s({type:t,data:e,timestamp:Date.now(),target:this.V})}catch(t){console.error("[JSSE] Event handler error:",t)}})}Oe(t){if("svg-layer"===t)this.ne=new g(this.V);else this.ne=new m(this.V);this.ne.setCurveFactor(this.G),this.ne.setPrecision(this.U)}Ie(){this.ne.destroy(),this.ne=null}Ae(){this.ne.activate(),this.Ue(),this.Ye(this.me),this.He("activate",{mode:this.ne.W()})}je(){this.ne.deactivate(),this.Be(),this.He("deactivate",{mode:this.ne.W()})}$e(){this.V.setAttribute("data-jsse-initiated",!0)}Pe(){this.V.removeAttribute("data-jsse-initiated")}Me(){l.get(this.V)||l.set(this.V,{})}Ne(){l.delete(this.V)}Le(){return o.get(this.V)}Te(){return!!this.Le()}Ge(){o.delete(this.V)}Ue(){this.me=this.ze(),s.debug({label:"STYLESHEET",element:this.V},"[TARGET]","[INIT]")}Fe(){this.me=null,this.Se=null,this.We(),s.debug({label:"STYLESHEET",element:this.V},"[TARGET]","[DESTROY]")}Ye(t){this.Se={};for(const e in t)this.Se[e]={in:t=>{this.Je(e,t)},out:t=>{this.Ze(e,t)},touchStart:t=>{this.Ke(e,t)},on:[],hovered:!1,touchCount:0},t[e].forEach(t=>{this.Se[e].on.push(t),this.Xe(t,e)});s.debug({label:"STYLESHEET",element:this.V},"[TARGET]","[EVENTS]",!0)}Be(){for(const t in this.Se)for(const e of this.Se[t].on)e&&e.removeEventListener&&this.qe(e,t);this.Se={},this.Qe&&(document.body.removeEventListener("touchend",this.Qe),this.Qe=null),s.debug({label:"STYLESHEET",element:this.V},"[TARGET]","[EVENTS]",!1)}Xe(t,e){t.addEventListener("mouseenter",this.Se[e].in),t.addEventListener("mouseleave",this.Se[e].out),t.addEventListener("touchstart",this.Se[e].touchStart),this.ts(),s.debug({label:"STYLESHEET",element:this.V},"[TRIGGER]","[EVENT]",!0,e)}ts(){this.Qe||(this.Qe=t=>{for(const e in this.Se){this.Se[e].touchCount>0&&this.es(e,t)}},document.body.addEventListener("touchend",this.Qe))}We(){this.Qe&&(document.body.removeEventListener("touchend",this.Qe),this.Qe=null)}qe(t,e){t.removeEventListener("mouseenter",this.Se[e].in),t.removeEventListener("mouseleave",this.Se[e].out),t.removeEventListener("touchstart",this.Se[e].touchStart),s.debug({label:"STYLESHEET",element:this.V},"[TRIGGER]","[EVENT]",!1,e)}Je(t,e){this.V.matches(t)&&this.Se[t]&&(this.Se[t].hovered=!0,s.debug({label:"HOVER",element:this.V},"[IN]",t,e),this.ss())}Ze(t,e){!this.V.matches(t)&&this.Se[t]&&this.Se[t]?.hovered&&(this.Se[t].hovered=!1,s.debug({label:"HOVER",element:this.V},"[OUT]",t,e),this.ss())}Ke(t,e){this.Se[t]&&void 0===this.Se[t]?.touchCount||(this.Se[t].touchCount++,1===this.Se[t].touchCount&&this.Je(t,e))}es(t,e){this.Se[t]&&void 0===this.Se[t]?.touchCount||(this.Se[t].touchCount--,0===this.Se[t].touchCount&&this.Ze(t,e))}ze(){const t={},e=a.getTargetSelectors(this.V,{selectorHasHover:!0});for(const s of e){const e=this.rs(s);if(e.length>0){t[s.getSelector()]=e}}return t}rs(t){const e=[],s=t.getTriggerParts();for(const t of s){const s=this.hs(t);e.push(...s)}return e}hs(t){if(t.neighbor){const i=`${t.neighbor.combinator}${t.neighbor.clean}`,r=`:has(${t.neighbor.combinator}*)`;return e.isSupport(r)?this.ns(t,i):(s.warn({label:"HOVER",element:this.V},"[FALLBACK] Using manual DOM traversal for:",i),this.ls(t.parent,i,t.child))}return Array.from(document.querySelectorAll(t.parent)).filter(e=>this.us(e,t.child))}ns(t,e){const s=`${t.parent}:has(${e})`,i=`${t.parent}${e}`,r=Array.from(document.querySelectorAll(s)),h=Array.from(document.querySelectorAll(i));return r.filter((e,s)=>{const i=h[s];return this.us(i,t.child)})}ls(t,e,s){const i=[],r=Array.from(document.querySelectorAll(t)),h=e.trim()[0],n=e.trim().substring(1).trim();for(const t of r){let e=[];if("+"===h){const s=t.nextElementSibling;s&&s.matches(n)&&(e=[s])}else if("~"===h){let s=t.nextElementSibling;for(;s;)s.matches(n)&&e.push(s),s=s.nextElementSibling}for(const r of e)if(this.us(r,s)){i.push(t);break}}return i}cs(t,e=document){return e.querySelectorAll(t)}us(t,e){if(!t.contains(this.V)&&t!==this.V)return!1;if(t===this.V)return!0;const s=this.cs(e,t);return Array.from(s).includes(this.V)}ds(){a.getTargetSelectors(this.V,{selectorHasHover:!0})}Re(){this.pe=new MutationObserver(()=>{this.ss()}),this.pe.observe(this.V,{attributes:!0,attributeFilter:["style","class"]}),"undefined"!=typeof IntersectionObserver&&(this.ge=new IntersectionObserver(t=>{this._s(t)}),this.ge.observe(this.V)),"undefined"!=typeof ResizeObserver&&(this._e=new ResizeObserver(()=>{this.ps()}),this._e.observe(this.V)),this.fe=new MutationObserver(()=>{this.fs()}),this.fe.observe(document.body,{childList:!0,subtree:!0})}Ve(){this.ue&&clearTimeout(this.ue),this.ce&&clearTimeout(this.ce),this._e&&this._e.disconnect(),this.pe&&this.pe.disconnect(),this.ge&&this.ge.disconnect(),this.fe&&this.fe.disconnect()}ss(){s.debug({label:"MUTATION",element:this.V},"[DETECT]",this.de?"self":"flow"),this.de||(null!==this.ue&&clearTimeout(this.ue),this.ue=setTimeout(()=>{this.ue=null,s.debug({label:"MUTATION",element:this.V},"[START]"),this.de=!0;try{s.debug({label:"MUTATION",element:this.V},"[UPDATE]"),this.ke()&&this.ve?(this.ne.update(),this.He("update",{type:"full"}),this.ve=!1):(this.ne.updateStyles(),this.He("update",{type:"styles"}))}finally{null!==this.ce&&clearTimeout(this.ce),this.ce=setTimeout(()=>{this.ce=null,s.debug({label:"MUTATION",element:this.V},"[END]"),this.de=!1},0)}},0))}ps(){if(this.ke())try{this.ne.updateSize(),this.He("update",{type:"size"})}finally{}else this.ve=!0}_s(t){if(t[0].isIntersecting&&this.ve)try{this.ne.update(),this.He("update",{type:"full"}),this.ve=!1}finally{}}fs(){document.body.contains(this.V)||this.xe()}}function v(t,e){if("string"==typeof t){const s=document.querySelectorAll(t),i=[];return s.forEach(t=>{t.superellipseInit(e),i.push(t.superellipse)}),i}if(t instanceof Element)return t.superellipseInit(e),t.superellipse;if(t instanceof NodeList||Array.isArray(t)){const s=[];for(let i=0;i<t.length;i++){const r=t[i];r instanceof Element&&(r.superellipseInit(e),s.push(r.superellipse))}return s}throw new Error("superellipseInit: первый аргумент должен быть селектором, элементом или коллекцией элементов")}Object.defineProperty(Element.prototype,"superellipse",{get(){return o.get(this)}}),Element.prototype.superellipseInit=function(t){let e=o.get(this);return e&&!t?.force?(s.warn({label:"API",element:this},"The element already has a controller. Use {force:true} to recreate it."),e):(e&&e.destroy(),e=new S(this,t),o.set(this,e),e)},"undefined"!=typeof window&&(window.superellipseInit=v),t.SuperellipseController=S,t.jsse_generateSuperellipsePath=p,t.superellipseInit=v});
|
|
46
|
+
//# sourceMappingURL=superellipse.min.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "js-superellipse",
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"description": "Superellipse shape for DOM elements",
|
|
5
|
+
"main": "dist/superellipse.js",
|
|
6
|
+
"module": "src/index.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "rollup -c",
|
|
9
|
+
"dev": "rollup -c -w"
|
|
10
|
+
},
|
|
11
|
+
"keywords": ["superellipse", "rounded corners", "svg", "clip-path"],
|
|
12
|
+
"author": "",
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@rollup/plugin-commonjs": "^25.0.0",
|
|
16
|
+
"@rollup/plugin-node-resolve": "^15.0.0",
|
|
17
|
+
"@rollup/plugin-terser": "^0.4.0",
|
|
18
|
+
"rollup": "^3.0.0"
|
|
19
|
+
}
|
|
20
|
+
}
|