PageSourceSearch

https://pockit.tools/assets/ColorPaletteGenerator-BS0ofVKD.js

js pockit.tools collected 2026-10-01 15:41:23 UTC 9,498 bytes, 8 lines download raw bytes

1import{j as t}from"./index-C_ektQUH.js";import{r as u}from"./react-vendor-xTTrI6pn.js";import{T as _}from"./ToolLayout-pC65h5R8.js";import{B as C}from"./Button-C8NIIl5W.js";import{L as Y}from"./Label-DAsFg_dD.js";import{S as D}from"./Select-lVWlUPVU.js";import{u as H}from"./i18n-vendor-DT53k9yW.js";import{aT as K,aH as q,aV as z,ai as V,U as Q,aE as X,aR as Z,av as ee,aK as te}from"./ui-vendor-CVpBiFJX.js";import"./utils-vendor-BAoJ1OuU.js";const ae=n=>{const c=parseInt(n.slice(1,3),16)/255,a=parseInt(n.slice(3,5),16)/255,s=parseInt(n.slice(5,7),16)/255,o=Math.max(c,a,s),d=Math.min(c,a,s);let x=0,m=0;const j=(o+d)/2;if(o!==d){const p=o-d;switch(m=j>.5?p/(2-o-d):p/(o+d),o){case c:x=((a-s)/p+(a<s?6:0))/6;break;case a:x=((s-c)/p+2)/6;break;case s:x=((c-a)/p+4)/6;break}}return[Math.round(x*360),Math.round(m*100),Math.round(j*100)]},l=(n,c,a)=>{c/=100,a/=100;const s=c*Math.min(a,1-a),o=d=>{const x=(d+n/30)%12,m=a-s*Math.max(Math.min(x-3,9-x,1),-1);return Math.round(255*m).toString(16).padStart(2,"0")};return`#${o(0)}${o(8)}${o(4)}`},se=n=>{const c=parseInt(n.slice(1,3),16),a=parseInt(n.slice(3,5),16),s=parseInt(n.slice(5,7),16);return`rgb(${c}, ${a}, ${s})`},T=(n,c)=>{const a=d=>{const x=[parseInt(d.slice(1,3),16),parseInt(d.slice(3,5),16),parseInt(d.slice(5,7),16)],[m,j,p]=x.map(N=>(N/=255,N<=.03928?N/12.92:Math.pow((N+.055)/1.055,2.4)));return .2126*m+.7152*j+.0722*p},s=a(n),o=a(c);return(Math.max(s,o)+.05)/(Math.min(s,o)+.05)},oe=()=>"#"+Math.floor(Math.random()*16777215).toString(16).padStart(6,"0"),re=(n,c)=>{const[a,s,o]=ae(n);switch(c){case"analogous":return[n,l((a+30)%360,s,o),l((a+60)%360,s,o),l((a-30+360)%360,s,o),l((a-60+360)%360,s,o)];case"complementary":return[n,l((a+180)%360,s,o),l(a,s,Math.min(o+20,100)),l((a+180)%360,s,Math.min(o+20,100)),l(a,s,Math.max(o-20,0))];case"triadic":return[n,l((a+120)%360,s,o),l((a+240)%360,s,o),l(a,s,Math.min(o+15,100)),l(a,s,Math.max(o-15,0))];case"tetradic":return[n,l((a+90)%360,s,o),l((a+180)%360,s,o),l((a+270)%360,s,o),l(a,s,Math.min(o+20,100))];case"split":return[n,l((a+150)%360,s,o),l((a+210)%360,s,o),l(a,s,Math.min(o+20,100)),l(a,s,Math.max(o-20,0))];case"monochromatic":return[l(a,s,90),l(a,s,70),l(a,s,50),l(a,s,30),l(a,s,10)];default:return[n]}},ne=[{id:"analogous",label:"Analogous"},{id:"complementary",label:"Complementary"},{id:"triadic",label:"Triadic"},{id:"tetradic",label:"Tetradic"},{id:"split",label:"Split-Complementary"},{id:"monochromatic",label:"Monochromatic"}],L="pockit_color_palettes";function ge(){const{t:n}=H(),[c,a]=u.useState("#3b82f6"),[s,o]=u.useState("#3b82f6"),[d,x]=u.useState("analogous"),[m,j]=u.useState([]),[p,N]=u.useState([!1,!1,!1,!1,!1]),[R,M]=u.useState(null),[k,S]=u.useState([]),I=u.useRef(null);u.useEffect(()=>{o(c.toUpperCase())},[c]),u.useEffect(()=>{try{const e=localStorage.getItem(L);e&&S(JSON.parse(e))}catch{}},[]),u.useEffect(()=>{localStorage.setItem(L,JSON.stringify(k))},[k]),u.useEffect(()=>{const e=re(c,d);j(r=>r.length===0?e:e.map((i,h)=>p[h]?r[h]:i))},[c,d]);const U=u.useCallback(()=>{const e=p[0]?c:oe();a(e)},[c,p]),G=e=>{N(r=>r.map((i,h)=>h===e?!i:i))},E=async e=>{await navigator.clipboard.writeText(e),M(e),setTimeout(()=>M(null),1500)},O=()=>{k.some(e=>JSON.stringify(e)===JSON.stringify(m))||S(e=>[[...m],...e].slice(0,20))},F=e=>{S(r=>r.filter((i,h)=>h!==e))},B=e=>{let r="";const i=["primary","secondary","accent","muted","background"];switch(e){case"css":r=`:root {
2${m.map((g,v)=>`  --color-${i[v]}: ${g};`).join(`
3`)}
4}`;break;case"scss":r=m.map((g,v)=>`$color-${i[v]}: ${g};`).join(`
5`);break;case"tailwind":r=`colors: {
6${m.map((g,v)=>`  ${i[v]}: '${g}',`).join(`
7`)}
8}`;break;case"json":r=JSON.stringify(Object.fromEntries(m.map((g,v)=>[i[v],g])),null,2);break}const h=new Blob([r],{type:"text/plain"}),y=URL.createObjectURL(h),b=document.createElement("a");b.href=y,b.download=`palette.${e==="tailwind"?"js":e}`,b.click(),URL.revokeObjectURL(y)},A=e=>{const r=e.target.files?.[0];if(!r)return;const i=new Image;i.onload=()=>{const h=document.createElement("canvas"),y=h.getContext("2d");h.width=100,h.height=100,y.drawImage(i,0,0,100,100);const b=y.getImageData(0,0,100,100).data,g=new Map;for(let f=0;f<b.length;f+=4){const w="#"+[b[f],b[f+1],b[f+2]].map(W=>W.toString(16).padStart(2,"0")).join("");g.set(w,(g.get(w)||0)+1)}const J=[...g.entries()].sort((f,w)=>w[1]-f[1]).slice(0,5).map(([f])=>f);
8j(J),N([!1,!1,!1,!1,!1])},i.src=URL.createObjectURL(r)},$=e=>T(e,"#ffffff"),P=e=>T(e,"#000000");return t.jsx(_,{toolId:"colorPaletteGenerator",children:t.jsxs("div",{className:"space-y-6",children:[t.jsxs("div",{className:"flex flex-wrap gap-4 items-end",children:[t.jsxs("div",{children:[t.jsx(Y,{children:n("tools.colorPaletteGenerator.ui.baseColor","Base Color")}),t.jsxs("div",{className:"flex gap-2 mt-1",children:[t.jsx("input",{type:"color",value:c,onChange:e=>a(e.target.value),className:"w-12 h-10 rounded cursor-pointer border-0"}),t.jsx("input",{type:"text",value:s,onChange:e=>{let r=e.target.value.toUpperCase();r.startsWith("#")||(r="#"+r),/^#[0-9A-F]{0,6}$/i.test(r)&&(o(r),/^#[0-9A-F]{6}$/i.test(r)&&a(r))},onBlur:()=>{/^#[0-9A-F]{6}$/i.test(s)||o(c.toUpperCase())},className:"w-28 px-2 py-2 rounded-xl border dark:bg-slate-800 dark:border-slate-700 uppercase text-sm font-mono",placeholder:"#3B82F6",maxLength:7})]})]}),t.jsx("div",{className:"w-44",children:t.jsx(D,{label:n("tools.colorPaletteGenerator.ui.harmonyType","Harmony"),value:d,onChange:e=>x(e),options:ne.map(e=>({value:e.id,label:n(`tools.colorPaletteGenerator.harmony.${e.id}`,e.label)}))})}),t.jsxs(C,{onClick:U,variant:"secondary",children:[t.jsx(K,{className:"w-4 h-4 mr-2"}),n("tools.colorPaletteGenerator.ui.generate","Generate")]}),t.jsxs(C,{onClick:()=>I.current?.click(),variant:"outline",children:[t.jsx(q,{className:"w-4 h-4 mr-2"}),n("tools.colorPaletteGenerator.ui.fromImage","From Image")]}),t.jsx("input",{ref:I,type:"file",accept:"image/*",onChange:A,className:"hidden"}),t.jsxs(C,{onClick:O,variant:"outline",children:[t.jsx(z,{className:"w-4 h-4 mr-2"}),n("tools.colorPaletteGenerator.ui.save","Save")]})]}),t.jsx("div",{className:"grid grid-cols-5 gap-2 md:gap-4",children:m.map((e,r)=>t.jsxs("div",{className:"relative group",children:[t.jsx("div",{className:"aspect-square rounded-xl shadow-lg transition-transform hover:scale-105",style:{backgroundColor:e}}),t.jsx("div",{className:"absolute inset-x-0 bottom-0 p-2 bg-black/50 rounded-b-xl opacity-0 group-hover:opacity-100 transition-opacity",children:t.jsxs("div",{className:"flex justify-center gap-1",children:[t.jsx("button",{onClick:()=>G(r),className:"p-1 hover:bg-white/20 rounded",title:p[r]?"Unlock":"Lock","aria-label":p[r]?"Unlock color":"Lock color",children:p[r]?t.jsx(V,{className:"w-4 h-4 text-white"}):t.jsx(Q,{className:"w-4 h-4 text-white"})}),t.jsx("button",{onClick:()=>E(e),className:"p-1 hover:bg-white/20 rounded",title:"Copy","aria-label":"Copy color code",children:R===e?t.jsx(X,{className:"w-4 h-4 text-green-400"}):t.jsx(Z,{className:"w-4 h-4 text-white"})})]})}),t.jsxs("div",{className:"mt-2 text-center",children:[t.jsx("span",{className:"text-sm font-mono uppercase",children:e}),t.jsx("div",{className:"text-xs text-slate-500",children:se(e)})]})]},r))}),t.jsxs("div",{className:"bg-slate-50 dark:bg-slate-800/50 rounded-xl p-4",children:[t.jsx("h3",{className:"font-medium mb-3",children:n("tools.colorPaletteGenerator.ui.contrast","Contrast Ratios (WCAG)")}),t.jsx("div",{className:"grid grid-cols-2 md:grid-cols-5 gap-2 text-sm",children:m.map((e,r)=>t.jsxs("div",{className:"p-2 rounded bg-white dark:bg-slate-900",children:[t.jsx("div",{className:"font-mono text-xs mb-1",children:e}),t.jsxs("div",{className:"flex justify-between",children:[t.jsx("span",{children:"vs ⬜"}),t.jsx("span",{className:$(e)>=4.5?"text-green-600":"text-red-500",children:$(e).toFixed(1)})]}),t.jsxs("div",{className:"flex justify-between",children:[t.jsx("span",{children:"vs ⬛"}),t.jsx("span",{className:P(e)>=4.5?"text-green-600":"text-red-500",children:P(e).toFixed(1)})]})]},r))})]}),t.jsxs("div",{className:"flex flex-wrap gap-2",children:[t.jsx("span",{className:"text-sm text-slate-500 self-center",children:n("tools.colorPaletteGenerator.ui.export","Export:")}),["css","scss","tailwind","json"].map(e=>t.jsxs(C,{onClick:()=>B(e),variant:"outline",size:"sm",children:[t.jsx(ee,{className:"w-3 h-3 mr-1"}),e.toUpperCase()]},e))]}),k.length>0&&t.jsxs("div",{className:"bg-slate-50 dark:bg-slate-800/50 rounded-xl p-4",children:[t.jsx("h3",{className:"font-medium mb-3",children:n("tools.colorPaletteGenerator.ui.favorites","Saved Palettes")}),t.jsx("div",{className:"space-y-2",children:k.map((e,r)=>t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsx("div",{className:"flex flex-1 gap-1",children:e.map((i,h)=>t.jsx("div",{className:"w-8 h-8 rounded cursor-pointer hover:scale-110 transition-transform",style:{backgroundColor:i},onClick:()=>{j(e),a(e[0])},title:i},h))}),t.jsx("button",{onClick:()=>F(r),className:"p-1 hover:bg-slate-200 dark:hover:bg-slate-700 rounded","aria-label":"Remove from favorites",children:t.jsx(te,{className:"w-4 h-4 text-slate-400"})})]},r))})]}),t.jsx("div",{className:"bg-emerald-50 dark:bg-emerald-900/20 border border-emerald-200 dark:border-emerald-800 rounded-xl p-3",children:t.jsxs("p",{className:"text-sm text-emerald-700 dark:text-emerald-300",children:["🔒 ",n("tools.colorPaletteGenerator.ui.securityNotice","All processing is done locally. Images are never uploaded.")]})})]})})}export{ge as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.