From 6604fa29298b2bc1c1e40b979bd5080913fe694e Mon Sep 17 00:00:00 2001 From: DrMint Date: Thu, 24 Feb 2022 02:06:25 +0100 Subject: [PATCH] Completely replaced theming. Now using arbitrary theming --- src/components/AppLayout.tsx | 32 +- src/components/Button.tsx | 6 +- .../Chronology/ChronologyItemComponent.tsx | 8 +- .../Chronology/ChronologyYearComponent.tsx | 2 +- src/components/Content/ThumbnailHeader.tsx | 4 +- src/components/HorizontalLine.tsx | 2 +- src/components/InsetBox.tsx | 2 +- .../Library/LibraryContentPreview.tsx | 6 +- .../Library/LibraryItemsPreview.tsx | 6 +- src/components/Markdown/Markdawn.tsx | 2 +- src/components/Markdown/SceneBreak.tsx | 2 +- src/components/PanelComponents/NavOption.tsx | 6 +- src/components/Panels/MainPanel.tsx | 47 +- src/pages/editor.tsx | 6 +- src/pages/index.tsx | 8 +- src/pages/library/[slug].tsx | 12 +- src/tailwind.css | 18 +- tailwind.config.js | 436 ++---------------- 18 files changed, 120 insertions(+), 485 deletions(-) diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx index 93d4a1c..c1101c8 100644 --- a/src/components/AppLayout.tsx +++ b/src/components/AppLayout.tsx @@ -69,10 +69,10 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { const turnSubIntoContent = props.subPanel && !props.contentPanel; return ( -
+
@@ -81,7 +81,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { </Head> {/* Navbar */} - <div className="fixed inset-0 top-auto h-20 border-t-[1px] border-black dark:border-dark-black border-dotted grid grid-cols-[5rem_1fr_5rem] place-items-center desktop:hidden bg-light dark:bg-dark-light texture-paper-dots"> + <div className="fixed inset-0 top-auto h-20 border-t-[1px] border-black border-dotted grid grid-cols-[5rem_1fr_5rem] place-items-center desktop:hidden bg-light texture-paper-dots"> <span className="material-icons mt-[.1em] cursor-pointer" onClick={() => appLayout.setMainPanelOpen(true)} @@ -103,13 +103,13 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { {/* Content panel */} <div - className={`top-0 left-0 right-0 bottom-20 overflow-y-scroll bg-light dark:bg-dark-light texture-paper-dots ${contentPanelClass}`} + className={`top-0 left-0 right-0 bottom-20 overflow-y-scroll bg-light texture-paper-dots ${contentPanelClass}`} > {props.contentPanel ? ( props.contentPanel ) : ( <div className="grid place-content-center h-full"> - <div className="text-dark dark:text-dark-dark border-dark border-2 border-dotted rounded-2xl p-8 grid grid-flow-col place-items-center gap-9 opacity-40"> + <div className="text-dark border-dark border-2 border-dotted rounded-2xl p-8 grid grid-flow-col place-items-center gap-9 opacity-40"> <p className="text-4xl">❮</p> <p className="text-2xl w-64"> Select one of the options in the sidebar @@ -121,12 +121,12 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { {/* Background when navbar is opened */} <div - className={`fixed bg-shade dark:bg-dark-shade inset-0 transition-opacity duration-500 + className={`fixed bg-shade inset-0 transition-opacity duration-500 ${turnSubIntoContent ? "z-10" : ""} ${ (appLayout.mainPanelOpen || appLayout.subPanelOpen) && isMobile - ? "opacity-60 dark:opacity-60" - : "opacity-0 dark:opacity-0 pointer-events-none touch-none" + ? "opacity-60" + : "opacity-0 pointer-events-none touch-none" }`} onClick={() => { appLayout.setMainPanelOpen(false); @@ -137,7 +137,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { {/* Sub panel */} {props.subPanel ? ( <div - className={`${subPanelClass} border-r-[1px] mobile:border-r-0 mobile:border-l-[1px] border-black dark:border-dark-black border-dotted top-0 bottom-0 right-0 left-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 bg-light dark:bg-dark-light texture-paper-dots + className={`${subPanelClass} border-r-[1px] mobile:border-r-0 mobile:border-l-[1px] border-black border-dotted top-0 bottom-0 right-0 left-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 bg-light texture-paper-dots ${ turnSubIntoContent ? "mobile:translate-x-0 mobile:bottom-20 mobile:left-0 mobile:border-l-0" @@ -154,7 +154,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { {/* Main panel */} <div - className={`${mainPanelClass} border-r-[1px] border-black dark:border-dark-black border-dotted top-0 bottom-0 left-0 right-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 z-20 bg-light dark:bg-dark-light texture-paper-dots + className={`${mainPanelClass} border-r-[1px] border-black border-dotted top-0 bottom-0 left-0 right-12 overflow-y-scroll webkit-scrollbar:w-0 [scrollbar-width:none] transition-transform duration-300 z-20 bg-light texture-paper-dots ${appLayout.mainPanelOpen ? "" : "mobile:-translate-x-full"}`} > <MainPanel langui={props.langui} /> @@ -169,24 +169,24 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { appLayout.setMainPanelReduced(!appLayout.mainPanelReduced) } > - <Button className="material-icons bg-light dark:bg-dark-light !px-2"> + <Button className="material-icons bg-light !px-2"> {appLayout.mainPanelReduced ? "chevron_right" : "chevron_left"} </Button> </div> {/* Language selection background */} <div - className={`fixed bg-shade dark:bg-dark-shade inset-0 transition-all duration-500 z-20 grid place-content-center ${ + className={`fixed bg-shade inset-0 transition-all duration-500 z-20 grid place-content-center ${ appLayout.languagePanelOpen - ? "bg-opacity-60 dark:bg-opacity-60" - : "bg-opacity-0 dark:bg-opacity-0 pointer-events-none touch-none" + ? "bg-opacity-60" + : "bg-opacity-0 pointer-events-none touch-none" }`} onClick={() => { appLayout.setLanguagePanelOpen(false); }} > <div - className={`p-10 bg-light dark:bg-dark-light rounded-lg shadow-2xl shadow-shade dark:shadow-dark-shade grid gap-4 place-items-center transition-transform ${ + className={`p-10 bg-light rounded-lg shadow-2xl shadow-shade grid gap-4 place-items-center transition-transform ${ appLayout.languagePanelOpen ? "scale-100" : "scale-0" }`} > @@ -214,7 +214,7 @@ export default function AppLayout(props: AppLayoutProps): JSX.Element { delayShow={300} delayHide={100} disable={!appLayout.mainPanelReduced || isMobile || isCoarse} - className="drop-shadow-shade-xl dark:drop-shadow-dark-shade-xl !opacity-100 !bg-light dark:!bg-dark-light !rounded-lg after:!border-r-light text-left !text-black dark:!text-dark-black" + className="drop-shadow-shade-xl !opacity-100 !bg-light !rounded-lg after:!border-r-light text-left !text-black" /> </div> </div> diff --git a/src/components/Button.tsx b/src/components/Button.tsx index d0580ac..1106928 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -16,12 +16,12 @@ export default function Button(props: ButtonProps): JSX.Element { <div id={props.id} onClick={props.onClick} - className={`grid place-content-center place-items-center border-[1px] border-dark text-dark dark:text-dark-dark rounded-full px-4 pt-[0.4rem] pb-[0.5rem] transition-all ${ + className={`grid place-content-center place-items-center border-[1px] border-dark text-dark rounded-full px-4 pt-[0.4rem] pb-[0.5rem] transition-all ${ props.className } ${ props.active - ? "text-light dark:text-dark-light bg-black dark:bg-dark-black drop-shadow-black-lg dark:drop-shadow-dark-black-lg !border-black dark:!border-dark-black cursor-not-allowed" - : "cursor-pointer hover:text-light dark:hover:text-dark-light hover:bg-dark dark:hover:bg-dark-dark hover:drop-shadow-shade-lg dark:hover:drop-shadow-dark-shade-lg active:bg-black dark:active:bg-dark-black active:drop-shadow-black-lg dark:active:drop-shadow-dark-black-lg active:border-black dark:active:border-dark-black" + ? "text-light bg-black drop-shadow-black-lg !border-black cursor-not-allowed" + : "cursor-pointer hover:text-light hover:bg-dark hover:drop-shadow-shade-lg active:bg-black active:drop-shadow-black-lg active:border-black" }`} > {props.children} diff --git a/src/components/Chronology/ChronologyItemComponent.tsx b/src/components/Chronology/ChronologyItemComponent.tsx index dbd8310..8dd20bd 100644 --- a/src/components/Chronology/ChronologyItemComponent.tsx +++ b/src/components/Chronology/ChronologyItemComponent.tsx @@ -53,7 +53,7 @@ export default function ChronologyItemComponent( return ( <div - className="grid place-content-start grid-rows-[auto_1fr] grid-cols-[4em] py-4 px-8 rounded-2xl target:bg-mid dark:bg-dark-mid target:py-8 target:my-4" + className="grid place-content-start grid-rows-[auto_1fr] grid-cols-[4em] py-4 px-8 rounded-2xl target:bg-mid target:py-8 target:my-4" id={generateAnchor( props.item.attributes.year, props.item.attributes.month, @@ -71,7 +71,7 @@ export default function ChronologyItemComponent( "" )} - <p className="col-start-1 text-dark dark:text-dark-dark text-sm"> + <p className="col-start-1 text-dark text-sm"> {generateDate(props.item.attributes.month, props.item.attributes.day)} </p> @@ -86,7 +86,7 @@ export default function ChronologyItemComponent( <p className={ event.translations.length > 1 - ? "before:content-['-'] before:text-dark dark:before:text-dark-dark before:inline-block before:w-4 before:ml-[-1em] mt-2 whitespace-pre-line" + ? "before:content-['-'] before:text-dark before:inline-block before:w-4 before:ml-[-1em] mt-2 whitespace-pre-line" : "whitespace-pre-line" } > @@ -103,7 +103,7 @@ export default function ChronologyItemComponent( </> ))} - <p className="text-dark dark:text-dark-dark text-xs inline-grid place-items-center grid-flow-col gap-1"> + <p className="text-dark text-xs inline-grid place-items-center grid-flow-col gap-1"> {event.source.data ? ( "(" + event.source.data.attributes.name + ")" ) : ( diff --git a/src/components/Chronology/ChronologyYearComponent.tsx b/src/components/Chronology/ChronologyYearComponent.tsx index 4e50549..8136ac0 100644 --- a/src/components/Chronology/ChronologyYearComponent.tsx +++ b/src/components/Chronology/ChronologyYearComponent.tsx @@ -11,7 +11,7 @@ export default function ChronologyYearComponent( ): JSX.Element { return ( <div - className="target:bg-mid dark:bg-dark-mid rounded-2xl target:py-4 target:my-4" + className="target:bg-mid rounded-2xl target:py-4 target:my-4" id={props.items.length > 1 ? props.year.toString() : undefined} > {props.items.map((item, index) => ( diff --git a/src/components/Content/ThumbnailHeader.tsx b/src/components/Content/ThumbnailHeader.tsx index a616848..4f18163 100644 --- a/src/components/Content/ThumbnailHeader.tsx +++ b/src/components/Content/ThumbnailHeader.tsx @@ -26,7 +26,7 @@ export default function ThumbnailHeader( return ( <> <div className="grid place-items-center gap-12 mb-12"> - <div className="drop-shadow-shade-lg dark:drop-shadow-dark-shade-lg"> + <div className="drop-shadow-shade-lg"> {content.thumbnail.data ? ( <Img className=" rounded-xl" @@ -35,7 +35,7 @@ export default function ThumbnailHeader( priority /> ) : ( - <div className="w-full aspect-[4/3] bg-light dark:bg-dark-light rounded-xl"></div> + <div className="w-full aspect-[4/3] bg-light rounded-xl"></div> )} </div> <div className="grid place-items-center text-center"> diff --git a/src/components/HorizontalLine.tsx b/src/components/HorizontalLine.tsx index 69c3cc9..985e220 100644 --- a/src/components/HorizontalLine.tsx +++ b/src/components/HorizontalLine.tsx @@ -7,7 +7,7 @@ export default function HorizontalLine( ): JSX.Element { return ( <div - className={`h-0 w-full my-8 border-t-[3px] border-dotted border-black dark:border-dark-black ${props.className}`} + className={`h-0 w-full my-8 border-t-[3px] border-dotted border-black ${props.className}`} ></div> ); } diff --git a/src/components/InsetBox.tsx b/src/components/InsetBox.tsx index 4b3d8ce..83de892 100644 --- a/src/components/InsetBox.tsx +++ b/src/components/InsetBox.tsx @@ -8,7 +8,7 @@ export default function InsetBox(props: InsetBoxProps): JSX.Element { return ( <div id={props.id} - className={`w-full shadow-inner-sm shadow-shade dark:shadow-dark-shade bg-mid dark:bg-dark-mid rounded-xl p-8 ${props.className}`} + className={`w-full shadow-inner-sm shadow-shade bg-mid rounded-xl p-8 ${props.className}`} > {props.children} </div> diff --git a/src/components/Library/LibraryContentPreview.tsx b/src/components/Library/LibraryContentPreview.tsx index c9e9b69..fb8d6a4 100644 --- a/src/components/Library/LibraryContentPreview.tsx +++ b/src/components/Library/LibraryContentPreview.tsx @@ -21,7 +21,7 @@ export default function LibraryContentPreview( return ( <Link href={"/contents/" + item.slug} passHref> - <div className="drop-shadow-shade-xl dark:drop-shadow-dark-shade-xl cursor-pointer grid items-end fine:[--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform"> + <div className="drop-shadow-shade-xl cursor-pointer grid items-end fine:[--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform"> {item.thumbnail.data ? ( <Img className="rounded-md coarse:rounded-b-none" @@ -29,9 +29,9 @@ export default function LibraryContentPreview( quality={ImageQuality.Medium} /> ) : ( - <div className="w-full aspect-[3/2] bg-light dark:bg-dark-light rounded-lg"></div> + <div className="w-full aspect-[3/2] bg-light rounded-lg"></div> )} - <div className="linearbg-obi dark:linearbg-dark-obi fine:drop-shadow-shade-lg dark:fine:drop-shadow-dark-shade-lg fine:absolute coarse:rounded-b-md bottom-2 -inset-x-0.5 opacity-[var(--cover-opacity)] transition-opacity z-20 grid p-4 gap-2"> + <div className="linearbg-obi fine:drop-shadow-shade-lg fine:absolute coarse:rounded-b-md bottom-2 -inset-x-0.5 opacity-[var(--cover-opacity)] transition-opacity z-20 grid p-4 gap-2"> <div className="grid grid-flow-col gap-1 overflow-hidden place-content-start"> {item.type ? ( <Chip> diff --git a/src/components/Library/LibraryItemsPreview.tsx b/src/components/Library/LibraryItemsPreview.tsx index ca4507a..7281619 100644 --- a/src/components/Library/LibraryItemsPreview.tsx +++ b/src/components/Library/LibraryItemsPreview.tsx @@ -25,7 +25,7 @@ export default function LibraryItemsPreview( return ( <Link href={"/library/" + item.slug} passHref> <div - className={`drop-shadow-shade-xl dark:drop-shadow-dark-shade-xl cursor-pointer grid items-end hover:rounded-3xl fine:[--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform ${props.className}`} + className={`drop-shadow-shade-xl cursor-pointer grid items-end hover:rounded-3xl fine:[--cover-opacity:0] hover:[--cover-opacity:1] hover:scale-[1.02] transition-transform ${props.className}`} > {item.thumbnail.data ? ( <Img @@ -33,10 +33,10 @@ export default function LibraryItemsPreview( quality={ImageQuality.Medium} /> ) : ( - <div className="w-full aspect-[21/29.7] bg-light dark:bg-dark-light rounded-lg"></div> + <div className="w-full aspect-[21/29.7] bg-light rounded-lg"></div> )} - <div className="linearbg-obi dark:linearbg-dark-obi fine:drop-shadow-shade-lg dark:fine:drop-shadow-dark-shade-lg fine:absolute place-items-start bottom-2 -inset-x-0.5 opacity-[var(--cover-opacity)] transition-opacity z-20 grid p-4 gap-2"> + <div className="linearbg-obi fine:drop-shadow-shade-lg fine:absolute place-items-start bottom-2 -inset-x-0.5 opacity-[var(--cover-opacity)] transition-opacity z-20 grid p-4 gap-2"> {item.metadata && item.metadata.length > 0 ? ( <div className="flex flex-row gap-1"> {item.metadata[0].__typename === "ComponentMetadataOther" diff --git a/src/components/Markdown/Markdawn.tsx b/src/components/Markdown/Markdawn.tsx index 310b905..8b5259d 100644 --- a/src/components/Markdown/Markdawn.tsx +++ b/src/components/Markdown/Markdawn.tsx @@ -9,7 +9,7 @@ type ScenBreakProps = { export default function Markdawn(props: ScenBreakProps): JSX.Element { return ( <Markdown - className={`prose prose-p:text-justify text-black dark:text-dark-black ${props.className}`} + className={`prose prose-p:text-justify text-black ${props.className}`} options={{ overrides: { hr: { diff --git a/src/components/Markdown/SceneBreak.tsx b/src/components/Markdown/SceneBreak.tsx index 18220ac..a636120 100644 --- a/src/components/Markdown/SceneBreak.tsx +++ b/src/components/Markdown/SceneBreak.tsx @@ -6,7 +6,7 @@ export default function SceneBreak(props: ScenBreakProps): JSX.Element { return ( <div className={ - "h-0 text-center text-3xl text-dark dark:text-dark-dark mt-16 mb-20" + " " + props.className + "h-0 text-center text-3xl text-dark mt-16 mb-20" + " " + props.className } > * * * diff --git a/src/components/PanelComponents/NavOption.tsx b/src/components/PanelComponents/NavOption.tsx index 382495e..df91024 100644 --- a/src/components/PanelComponents/NavOption.tsx +++ b/src/components/PanelComponents/NavOption.tsx @@ -16,10 +16,10 @@ type NavOptionProps = { export default function NavOption(props: NavOptionProps): JSX.Element { const router = useRouter(); const isActive = router.asPath.startsWith(props.url); - const divActive = "bg-mid dark:bg-dark-mid shadow-inner-sm shadow-shade dark:shadow-dark-shade"; + const divActive = "bg-mid shadow-inner-sm shadow-shade"; const border = - "outline outline-mid dark:outline-dark-mid outline-2 outline-offset-[-2px] hover:outline-[transparent]"; - const divCommon = `gap-x-5 w-full rounded-2xl cursor-pointer p-4 hover:bg-mid dark:hover:bg-dark-mid hover:shadow-inner-sm hover:shadow-shade dark:hover:shadow-dark-shade hover:active:shadow-inner hover:active:shadow-shade dark:hover:active:shadow-dark-shade transition-all ${ + "outline outline-mid outline-2 outline-offset-[-2px] hover:outline-[transparent]"; + const divCommon = `gap-x-5 w-full rounded-2xl cursor-pointer p-4 hover:bg-mid hover:shadow-inner-sm hover:shadow-shade hover:active:shadow-inner hover:active:shadow-shade transition-all ${ props.border ? border : "" } ${isActive ? divActive : ""}`; diff --git a/src/components/Panels/MainPanel.tsx b/src/components/Panels/MainPanel.tsx index ebe80d7..4db6f4f 100644 --- a/src/components/Panels/MainPanel.tsx +++ b/src/components/Panels/MainPanel.tsx @@ -32,13 +32,8 @@ export default function MainPanel(props: MainPanelProps): JSX.Element { onClick={() => appLayout.setMainPanelOpen(false)} className={`${ appLayout.mainPanelReduced && isDesktop ? "w-12" : "w-1/2" - } cursor-pointer transition-[filter] colorize-black dark:colorize-dark-black hover:colorize-dark dark:hover:colorize-dark-dark`} - > - <SVG - src={"/icons/accords.svg"} - alt={"Logo of Accord's Library"} - /> - </div> + } aspect-square cursor-pointer transition-colors [mask:url('/icons/accords.svg')] ![mask-size:contain] ![mask-repeat:no-repeat] ![mask-position:center] bg-black hover:bg-dark mb-4`} + ></div> </Link> {appLayout.mainPanelReduced && isDesktop ? ( @@ -49,7 +44,9 @@ export default function MainPanel(props: MainPanelProps): JSX.Element { <div className={`flex ${ - appLayout.mainPanelReduced && isDesktop ? "mt-4 flex-col gap-3" : "flex-row" + appLayout.mainPanelReduced && isDesktop + ? "flex-col gap-3" + : "flex-row" } flex-wrap gap-2`} > <Button @@ -186,25 +183,13 @@ export default function MainPanel(props: MainPanelProps): JSX.Element { )} </p> <a - className="transition-[filter] colorize-black dark:colorize-dark-black hover:colorize-dark dark:hover:colorize-dark-dark" + className="transition-[filter] colorize-black hover:colorize-dark" href="https://creativecommons.org/licenses/by-sa/4.0/" > - <div className="mt-4 mb-8 grid grid-flow-col place-content-center gap-1"> - <SVG - className="w-6" - src={"/icons/creative-commons-brands.svg"} - alt={""} - /> - <SVG - className="w-6" - src={"/icons/creative-commons-by-brands.svg"} - alt={""} - /> - <SVG - className="w-6" - src={"/icons/creative-commons-sa-brands.svg"} - alt={""} - /> + <div className="mt-4 mb-8 grid grid-flow-col place-content-center gap-1 hover:[--theme-color-black:var(--theme-color-dark)]"> + <div className="w-6 aspect-square [mask:url('/icons/creative-commons-brands.svg')] ![mask-size:contain] ![mask-repeat:no-repeat] ![mask-position:center] bg-black" /> + <div className="w-6 aspect-square [mask:url('/icons/creative-commons-by-brands.svg')] ![mask-size:contain] ![mask-repeat:no-repeat] ![mask-position:center] bg-black" /> + <div className="w-6 aspect-square [mask:url('/icons/creative-commons-sa-brands.svg')] ![mask-size:contain] ![mask-repeat:no-repeat] ![mask-position:center] bg-black" /> </div> </a> <p> @@ -216,21 +201,17 @@ export default function MainPanel(props: MainPanelProps): JSX.Element { </p> <div className="mt-12 mb-4 grid h-4 grid-flow-col place-content-center gap-8"> <a - className="transition-[filter] colorize-black dark:colorize-dark-black hover:colorize-dark dark:hover:colorize-dark-dark" + className="transition-colors [mask:url('/icons/github-brands.svg')] ![mask-size:contain] ![mask-repeat:no-repeat] ![mask-position:center] w-10 aspect-square bg-black hover:bg-dark" href="https://github.com/Accords-Library" target="_blank" rel="noopener noreferrer" - > - <SVG className="w-10" src={"/icons/github-brands.svg"} alt={""} /> - </a> + ></a> <a - className="transition-[filter] colorize-black dark:colorize-dark-black hover:colorize-dark dark:hover:colorize-dark-dark" + className="transition-colors [mask:url('/icons/discord-brands.svg')] ![mask-size:contain] ![mask-repeat:no-repeat] ![mask-position:center] w-10 aspect-square bg-black hover:bg-dark" href="/discord" target="_blank" rel="noopener noreferrer" - > - <SVG className="w-10" src={"/icons/discord-brands.svg"} alt={""} /> - </a> + ></a> </div> </div> </div> diff --git a/src/pages/editor.tsx b/src/pages/editor.tsx index e72eef7..09d20be 100644 --- a/src/pages/editor.tsx +++ b/src/pages/editor.tsx @@ -43,7 +43,7 @@ export default function Editor(props: EditorProps): JSX.Element { <textarea id="editorTextArea" onInput={handleInput} - className="bg-mid dark:bg-dark-mid rounded-xl p-8 w-full font-monospace" + className="bg-mid rounded-xl p-8 w-full font-monospace" value={markdown} /> @@ -71,12 +71,12 @@ export default function Editor(props: EditorProps): JSX.Element { target.select(); event.preventDefault(); }} - className="bg-mid dark:bg-dark-mid rounded-xl p-8 w-full font-monospace" + className="bg-mid rounded-xl p-8 w-full font-monospace" /> </div> <div> <h2>Preview</h2> - <div className="bg-mid dark:bg-dark-mid rounded-xl p-8"> + <div className="bg-mid rounded-xl p-8"> <Markdawn className="max-w-full" text={markdown} /> </div> </div> diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 96d2958..f95e872 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -13,12 +13,8 @@ export default function Home(props: HomeProps): JSX.Element { const contentPanel = ( <ContentPanel autoformat> - <div className="grid place-items-center place-content-center w-full gap-5 text-center colorize-black dark:colorize-dark-black"> - <SVG - className="w-32 mobile:w-1/2" - src={"/icons/accords.svg"} - alt={"Logo of Accord's Library"} - /> + <div className="grid place-items-center place-content-center w-full gap-5 text-center"> + <div className="[mask:url('/icons/accords.svg')] [mask-size:contain] [mask-repeat:no-repeat] [mask-position:center] w-32 aspect-square mobile:w-[50vw] bg-black" /> <h1 className="text-5xl mb-0">Accord’s Library</h1> <h2 className="mt-0">Discover • Analyse • Translate • Archive</h2> </div> diff --git a/src/pages/library/[slug].tsx b/src/pages/library/[slug].tsx index 38847ea..49479a5 100644 --- a/src/pages/library/[slug].tsx +++ b/src/pages/library/[slug].tsx @@ -115,7 +115,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { const contentPanel = ( <ContentPanel width={ContentPanelWidthSizes.large}> <div className="grid place-items-center gap-12"> - <div className="drop-shadow-shade-xl dark:drop-shadow-dark-shade-xl w-full h-[50vh] mobile:h-[80vh] mb-16 relative cursor-pointer"> + <div className="drop-shadow-shade-xl w-full h-[50vh] mobile:h-[80vh] mb-16 relative cursor-pointer"> {item.thumbnail.data ? ( <Img image={item.thumbnail.data.attributes} @@ -125,7 +125,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { priority /> ) : ( - <div className="w-full aspect-[21/29.7] bg-light dark:bg-dark-light rounded-xl"></div> + <div className="w-full aspect-[21/29.7] bg-light rounded-xl"></div> )} </div> @@ -172,7 +172,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { key={galleryItem.id} className="relative aspect-square hover:scale-[1.02] transition-transform cursor-pointer" > - <div className="bg-light dark:bg-dark-light absolute inset-0 rounded-lg drop-shadow-shade-md dark:drop-shadow-dark-shade-md"></div> + <div className="bg-light absolute inset-0 rounded-lg drop-shadow-shade-md"></div> <Img className="rounded-lg" image={galleryItem.attributes} @@ -374,7 +374,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { <div id={content.attributes.slug} key={content.id} - className="grid gap-2 px-4 rounded-lg target:bg-mid dark:target:bg-dark-mid target:shadow-inner-sm target:shadow-shade dark:target:shadow-dark-shade target:h-auto target:py-3 target:my-2 target:[--displaySubContentMenu:grid] [--displaySubContentMenu:none]" + className="grid gap-2 px-4 rounded-lg target:bg-mid target:shadow-inner-sm target:shadow-shade target:h-auto target:py-3 target:my-2 target:[--displaySubContentMenu:grid] [--displaySubContentMenu:none]" > <div className="grid gap-4 place-items-center grid-cols-[auto_auto_1fr_auto_12ch] thin:grid-cols-[auto_auto_1fr_auto]"> <a href={`#${content.attributes.slug}`}> @@ -402,7 +402,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { ) )} </div> - <p className="border-b-2 h-4 w-full border-black dark:border-dark-black border-dotted opacity-30"></p> + <p className="border-b-2 h-4 w-full border-black border-dotted opacity-30"></p> <p> {content.attributes.range[0].__typename === "ComponentRangePageRange" @@ -425,7 +425,7 @@ export default function LibrarySlug(props: LibrarySlugProps): JSX.Element { )} </div> <div className="grid-flow-col place-content-start place-items-center gap-2 [display:var(--displaySubContentMenu)]"> - <span className="material-icons text-dark dark:text-dark-dark"> + <span className="material-icons text-dark"> subdirectory_arrow_right </span> diff --git a/src/tailwind.css b/src/tailwind.css index f3aaa09..6667ada 100644 --- a/src/tailwind.css +++ b/src/tailwind.css @@ -17,17 +17,17 @@ } a { - @apply transition-colors underline-offset-2 decoration-dotted underline decoration-dark dark:decoration-dark-dark hover:text-dark dark:hover:text-dark-dark; + @apply transition-colors underline-offset-2 decoration-dotted underline decoration-dark hover:text-dark; } *::selection { - @apply bg-dark dark:bg-dark-dark text-light dark:text-dark-light; + @apply bg-dark text-light; } /* SCROLLBARS STYLING */ * { - @apply [scrollbar-color:theme(colors.dark)_transparent] dark:[scrollbar-color:theme(colors.dark-dark)_transparent] [scrollbar-width:thin]; + @apply [scrollbar-color:theme(colors.dark)_transparent] [scrollbar-width:thin]; } *::-webkit-scrollbar { @@ -35,11 +35,11 @@ } *::-webkit-scrollbar-track { - @apply bg-light dark:bg-dark-light; + @apply bg-light; } *::-webkit-scrollbar-thumb { - @apply bg-dark dark:bg-dark-dark rounded-full border-[3px] border-solid border-light dark:border-dark-light; + @apply bg-dark rounded-full border-[3px] border-solid border-light; } /* CHANGE PROSE DEFAULTS */ @@ -54,11 +54,11 @@ .prose h6, .prose a, .prose strong { - @apply text-black dark:text-dark-black; + @apply text-black; } .prose a { - @apply transition-colors underline-offset-2 decoration-dotted underline decoration-dark dark:decoration-dark-dark hover:text-dark dark:hover:text-dark-dark; + @apply transition-colors underline-offset-2 decoration-dotted underline decoration-dark hover:text-dark; } .prose footer { @@ -70,12 +70,12 @@ } .prose footer > div:target { - @apply bg-mid dark:bg-dark-mid shadow-inner-sm shadow-shade dark:shadow-dark-shade; + @apply bg-mid shadow-inner-sm shadow-shade; } } @layer components { .texture-paper-dots { - @apply bg-paper-dots dark:bg-dark-paper-dots bg-blend-multiply dark:bg-blend-overlay bg-local bg-[length:10cm]; + @apply [background-image:var(--theme-texture-dots)] [background-blend-mode:var(--theme-texture-dots-blend)] bg-local bg-[length:10cm]; } } diff --git a/tailwind.config.js b/tailwind.config.js index 83e2064..f099e48 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -20,24 +20,25 @@ const breakThin = { max: "25rem" }; /* END CONFIG */ +function withOpacity(variableName) { + return ({ opacityValue }) => { + if (opacityValue) { + return `rgba(var(${variableName}), ${opacityValue})`; + } + return `rgb(var(${variableName}))`; + }; +} + module.exports = { darkMode: "class", content: ["./src/**/*.{tsx,ts}"], theme: { colors: { - light: `rgb(${light.r}, ${light.g}, ${light.b})`, - mid: `rgb(${mid.r}, ${mid.g}, ${mid.b})`, - dark: `rgb(${dark.r}, ${dark.g}, ${dark.b})`, - shade: `rgb(${shade.r}, ${shade.g}, ${shade.b})`, - black: `rgb(${black.r}, ${black.g}, ${black.b})`, - - // Dark mode - - "dark-light": `rgb(${dark_light.r}, ${dark_light.g}, ${dark_light.b})`, - "dark-mid": `rgb(${dark_mid.r}, ${dark_mid.g}, ${dark_mid.b})`, - "dark-dark": `rgb(${dark_dark.r}, ${dark_dark.g}, ${dark_dark.b})`, - "dark-shade": `rgb(${dark_shade.r}, ${dark_shade.g}, ${dark_shade.b})`, - "dark-black": `rgb(${dark_black.r}, ${dark_black.g}, ${dark_black.b})`, + light: withOpacity("--theme-color-light"), + mid: withOpacity("--theme-color-mid"), + dark: withOpacity("--theme-color-dark"), + shade: withOpacity("--theme-color-shade"), + black: withOpacity("--theme-color-black"), }, fontFamily: { body: ["Zen Maru Gothic"], @@ -51,10 +52,6 @@ module.exports = { coarse: { raw: "(pointer: coarse)" }, fine: { raw: "(pointer: fine)" }, }, - backgroundImage: { - "paper-dots": "url('/paper-dots.webp')", - "dark-paper-dots": "url('/paper-dots-dark.webp')", - }, extend: { boxShadow: { "inner-sm": "inset 0 1px 4px -2px", @@ -64,6 +61,30 @@ module.exports = { plugins: [ require("@tailwindcss/typography"), + // Colored Dropshadow + plugin(function ({ addUtilities }) { + addUtilities({ + ".set-theme-light": { + "--theme-color-light": `${light.r}, ${light.g}, ${light.b}`, + "--theme-color-mid": `${mid.r}, ${mid.g}, ${mid.b}`, + "--theme-color-dark": `${dark.r}, ${dark.g}, ${dark.b}`, + "--theme-color-shade": `${shade.r}, ${shade.g}, ${shade.b}`, + "--theme-color-black": `${black.r}, ${black.g}, ${black.b}`, + "--theme-texture-dots": `url("/paper-dots.webp")`, + "--theme-texture-dots-blend": `multiply`, + }, + ".set-theme-dark": { + "--theme-color-light": `${dark_light.r}, ${dark_light.g}, ${dark_light.b}`, + "--theme-color-mid": `${dark_mid.r}, ${dark_mid.g}, ${dark_mid.b}`, + "--theme-color-dark": `${dark_dark.r}, ${dark_dark.g}, ${dark_dark.b}`, + "--theme-color-shade": `${dark_shade.r}, ${dark_shade.g}, ${dark_shade.b}`, + "--theme-color-black": `${dark_black.r}, ${dark_black.g}, ${dark_black.b}`, + "--theme-texture-dots": `url("/paper-dots-dark.webp")`, + "--theme-texture-dots-blend": `overlay`, + }, + }); + }), + plugin(function ({ addVariant, e }) { addVariant("webkit-scrollbar", ({ modifySelectors, separator }) => { modifySelectors(({ className }) => { @@ -74,94 +95,33 @@ module.exports = { }); }), - // Colorization thanks to https://codepen.io/sosuke/pen/Pjoqqp - plugin(function ({ addUtilities }) { - addUtilities({ - ".colorize-light": { - filter: getFilterRecipe(light), - }, - ".colorize-mid": { - filter: getFilterRecipe(mid), - }, - ".colorize-dark": { - filter: getFilterRecipe(dark), - }, - ".colorize-black": { - filter: getFilterRecipe(black), - }, - - // Dark mode - - ".colorize-dark-light": { - filter: getFilterRecipe(dark_light), - }, - ".colorize-dark-mid": { - filter: getFilterRecipe(dark_mid), - }, - ".colorize-dark-dark": { - filter: getFilterRecipe(dark_dark), - }, - ".colorize-dark-black": { - filter: getFilterRecipe(dark_black), - }, - }); - }), - // Colored Dropshadow plugin(function ({ addUtilities }) { addUtilities({ ".drop-shadow-shade-md": { - filter: `drop-shadow(0 4px 3px rgb(${shade.r} ${shade.g} ${shade.b} / 0.15)) drop-shadow(0 2px 2px rgb(${shade.r} ${shade.g} ${shade.b} / 0.2))`, + filter: `drop-shadow(0 4px 3px rgba(var(--theme-color-shade), 0.15)) drop-shadow(0 2px 2px rgba(var(--theme-color-shade), 0.2))`, }, ".drop-shadow-shade-lg": { - filter: `drop-shadow(0 10px 8px rgb(${shade.r} ${shade.g} ${shade.b} / 0.2)) drop-shadow(0 4px 3px rgb(${shade.r} ${shade.g} ${shade.b} / 0.4))`, + filter: `drop-shadow(0 10px 8px rgba(var(--theme-color-shade), 0.2)) drop-shadow(0 4px 3px rgba(var(--theme-color-shade), 0.4))`, }, ".drop-shadow-shade-xl": { - filter: `drop-shadow(0 20px 13px rgb(${shade.r} ${shade.g} ${shade.b} / 0.25)) drop-shadow(0 8px 5px rgb(${shade.r} ${shade.g} ${shade.b} / 0.7))`, + filter: `drop-shadow(0 20px 13px rgba(var(--theme-color-shade), 0.25)) drop-shadow(0 8px 5px rgba(var(--theme-color-shade), 0.7))`, }, ".drop-shadow-shade-2xl": { - filter: `drop-shadow(0 25px 25px rgb(${shade.r} ${shade.g} ${shade.b} / 0.8))`, + filter: `drop-shadow(0 25px 25px rgba(var(--theme-color-shade), 0.8))`, }, ".drop-shadow-black-md": { - filter: `drop-shadow(0 4px 3px rgb(${black.r} ${black.g} ${black.b} / 0.15)) drop-shadow(0 2px 2px rgb(${black.r} ${black.g} ${black.b} / 0.2))`, + filter: `drop-shadow(0 4px 3px rgba(var(--theme-color-black), 0.15)) drop-shadow(0 2px 2px rgba(var(--theme-color-black), 0.2))`, }, ".drop-shadow-black-lg": { - filter: `drop-shadow(0 10px 8px rgb(${black.r} ${black.g} ${black.b} / 0.2)) drop-shadow(0 4px 3px rgb(${black.r} ${black.g} ${black.b} / 0.4))`, + filter: `drop-shadow(0 10px 8px rgba(var(--theme-color-black), 0.2)) drop-shadow(0 4px 3px rgba(var(--theme-color-black), 0.4))`, }, ".drop-shadow-black-xl": { - filter: `drop-shadow(0 20px 13px rgb(${black.r} ${black.g} ${black.b} / 0.25)) drop-shadow(0 8px 5px rgb(${black.r} ${black.g} ${black.b} / 0.7))`, + filter: `drop-shadow(0 20px 13px rgba(var(--theme-color-black), 0.25)) drop-shadow(0 8px 5px rgba(var(--theme-color-black), 0.7))`, }, ".drop-shadow-black-2xl": { - filter: `drop-shadow(0 25px 25px rgb(${black.r} ${black.g} ${black.b} / 0.8))`, - }, - - // Dark mode - - ".drop-shadow-dark-shade-md": { - filter: `drop-shadow(0 4px 3px rgb(${dark_shade.r} ${dark_shade.g} ${dark_shade.b} / 0.15)) drop-shadow(0 2px 2px rgb(${dark_shade.r} ${dark_shade.g} ${dark_shade.b} / 0.2))`, - }, - ".drop-shadow-dark-shade-lg": { - filter: `drop-shadow(0 10px 8px rgb(${dark_shade.r} ${dark_shade.g} ${dark_shade.b} / 0.2)) drop-shadow(0 4px 3px rgb(${dark_shade.r} ${dark_shade.g} ${dark_shade.b} / 0.4))`, - }, - ".drop-shadow-dark-shade-xl": { - filter: `drop-shadow(0 20px 13px rgb(${dark_shade.r} ${dark_shade.g} ${dark_shade.b} / 0.25)) drop-shadow(0 8px 5px rgb(${dark_shade.r} ${dark_shade.g} ${dark_shade.b} / 0.7))`, - }, - ".drop-shadow-dark-shade-2xl": { - filter: `drop-shadow(0 25px 25px rgb(${dark_shade.r} ${dark_shade.g} ${dark_shade.b} / 0.8))`, - }, - - ".drop-shadow-dark-black-md": { - filter: `drop-shadow(0 4px 3px rgb(${dark_black.r} ${dark_black.g} ${dark_black.b} / 0.15)) drop-shadow(0 2px 2px rgb(${dark_black.r} ${dark_black.g} ${dark_black.b} / 0.2))`, - }, - ".drop-shadow-dark-black-lg": { - filter: `drop-shadow(0 10px 8px rgb(${dark_black.r} ${dark_black.g} ${dark_black.b} / 0.2)) drop-shadow(0 4px 3px rgb(${dark_black.r} ${dark_black.g} ${dark_black.b} / 0.4))`, - }, - ".drop-shadow-dark-black-xl": { - filter: `drop-shadow(0 20px 13px rgb(${dark_black.r} ${dark_black.g} ${dark_black.b} / 0.25)) drop-shadow(0 8px 5px rgb(${dark_black.r} ${dark_black.g} ${dark_black.b} / 0.7))`, - }, - ".drop-shadow-dark-black-2xl": { - filter: `drop-shadow(0 25px 25px rgb(${dark_black.r} ${dark_black.g} ${dark_black.b} / 0.8))`, + filter: `drop-shadow(0 25px 25px rgba(var(--theme-color-black), 0.8))`, }, }); }), @@ -170,311 +130,9 @@ module.exports = { addUtilities({ ".linearbg-obi": { background: - "linear-gradient(to right, theme('colors.mid'), theme('colors.light') 3%, theme('colors.light') 97%, theme('colors.mid'))", - }, - ".linearbg-dark-obi": { - background: - "linear-gradient(to right, theme('colors.dark-mid'), theme('colors.dark-light') 3%, theme('colors.dark-light') 97%, theme('colors.dark-mid'))", + "linear-gradient(to right, rgb(var(--theme-color-mid)), rgb(var(--theme-color-light)) 3%, rgb(var(--theme-color-light)) 97%, rgb(var(--theme-color-mid)))", }, }); }), ], }; - -/* -The following is taken from https://codepen.io/sosuke/pen/Pjoqqp -Used for colorizing any element using filters. -*/ - -function getFilterRecipe(rgb) { - const color = new FilterColorTransform(rgb.r, rgb.g, rgb.b); - const solver = new Solver(color); - const result = solver.solve(); - return result; -} - -class FilterColorTransform { - constructor(r, g, b) { - this.set(r, g, b); - } - - set(r, g, b) { - this.r = this.clamp(r); - this.g = this.clamp(g); - this.b = this.clamp(b); - } - - hueRotate(angle = 0) { - angle = (angle / 180) * Math.PI; - const sin = Math.sin(angle); - const cos = Math.cos(angle); - - this.multiply([ - 0.213 + cos * 0.787 - sin * 0.213, - 0.715 - cos * 0.715 - sin * 0.715, - 0.072 - cos * 0.072 + sin * 0.928, - 0.213 - cos * 0.213 + sin * 0.143, - 0.715 + cos * 0.285 + sin * 0.14, - 0.072 - cos * 0.072 - sin * 0.283, - 0.213 - cos * 0.213 - sin * 0.787, - 0.715 - cos * 0.715 + sin * 0.715, - 0.072 + cos * 0.928 + sin * 0.072, - ]); - } - - grayscale(value = 1) { - this.multiply([ - 0.2126 + 0.7874 * (1 - value), - 0.7152 - 0.7152 * (1 - value), - 0.0722 - 0.0722 * (1 - value), - 0.2126 - 0.2126 * (1 - value), - 0.7152 + 0.2848 * (1 - value), - 0.0722 - 0.0722 * (1 - value), - 0.2126 - 0.2126 * (1 - value), - 0.7152 - 0.7152 * (1 - value), - 0.0722 + 0.9278 * (1 - value), - ]); - } - - sepia(value = 1) { - this.multiply([ - 0.393 + 0.607 * (1 - value), - 0.769 - 0.769 * (1 - value), - 0.189 - 0.189 * (1 - value), - 0.349 - 0.349 * (1 - value), - 0.686 + 0.314 * (1 - value), - 0.168 - 0.168 * (1 - value), - 0.272 - 0.272 * (1 - value), - 0.534 - 0.534 * (1 - value), - 0.131 + 0.869 * (1 - value), - ]); - } - - saturate(value = 1) { - this.multiply([ - 0.213 + 0.787 * value, - 0.715 - 0.715 * value, - 0.072 - 0.072 * value, - 0.213 - 0.213 * value, - 0.715 + 0.285 * value, - 0.072 - 0.072 * value, - 0.213 - 0.213 * value, - 0.715 - 0.715 * value, - 0.072 + 0.928 * value, - ]); - } - - multiply(matrix) { - const newR = this.clamp( - this.r * matrix[0] + this.g * matrix[1] + this.b * matrix[2] - ); - const newG = this.clamp( - this.r * matrix[3] + this.g * matrix[4] + this.b * matrix[5] - ); - const newB = this.clamp( - this.r * matrix[6] + this.g * matrix[7] + this.b * matrix[8] - ); - this.r = newR; - this.g = newG; - this.b = newB; - } - - brightness(value = 1) { - this.linear(value); - } - contrast(value = 1) { - this.linear(value, -(0.5 * value) + 0.5); - } - - linear(slope = 1, intercept = 0) { - this.r = this.clamp(this.r * slope + intercept * 255); - this.g = this.clamp(this.g * slope + intercept * 255); - this.b = this.clamp(this.b * slope + intercept * 255); - } - - invert(value = 1) { - this.r = this.clamp((value + (this.r / 255) * (1 - 2 * value)) * 255); - this.g = this.clamp((value + (this.g / 255) * (1 - 2 * value)) * 255); - this.b = this.clamp((value + (this.b / 255) * (1 - 2 * value)) * 255); - } - - hsl() { - // Code taken from https://stackoverflow.com/a/9493060/2688027, licensed under CC BY-SA. - const r = this.r / 255; - const g = this.g / 255; - const b = this.b / 255; - const max = Math.max(r, g, b); - const min = Math.min(r, g, b); - let h, - s, - l = (max + min) / 2; - - if (max === min) { - h = s = 0; - } else { - const d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - - case g: - h = (b - r) / d + 2; - break; - - case b: - h = (r - g) / d + 4; - break; - } - h /= 6; - } - - return { - h: h * 100, - s: s * 100, - l: l * 100, - }; - } - - clamp(value) { - if (value > 255) { - value = 255; - } else if (value < 0) { - value = 0; - } - return value; - } -} - -class Solver { - constructor(target) { - this.target = target; - this.targetHSL = target.hsl(); - this.reusedColor = new FilterColorTransform(0, 0, 0); - } - - solve() { - const result = this.solveNarrow(this.solveWide()); - return this.css(result.values); - } - - solveWide() { - const A = 5; - const c = 15; - const a = [60, 180, 18000, 600, 1.2, 1.2]; - - let best = { loss: Infinity }; - for (let i = 0; best.loss > 25 && i < 3; i++) { - const initial = [50, 20, 3750, 50, 100, 100]; - const result = this.spsa(A, a, c, initial, 1000); - if (result.loss < best.loss) { - best = result; - } - } - return best; - } - - solveNarrow(wide) { - const A = wide.loss; - const c = 2; - const A1 = A + 1; - const a = [0.25 * A1, 0.25 * A1, A1, 0.25 * A1, 0.2 * A1, 0.2 * A1]; - return this.spsa(A, a, c, wide.values, 500); - } - - spsa(A, a, c, values, iters) { - const alpha = 1; - const gamma = 0.16666666666666666; - - let best = null; - let bestLoss = Infinity; - const deltas = new Array(6); - const highArgs = new Array(6); - const lowArgs = new Array(6); - - for (let k = 0; k < iters; k++) { - const ck = c / Math.pow(k + 1, gamma); - for (let i = 0; i < 6; i++) { - deltas[i] = Math.random() > 0.5 ? 1 : -1; - highArgs[i] = values[i] + ck * deltas[i]; - lowArgs[i] = values[i] - ck * deltas[i]; - } - - const lossDiff = this.loss(highArgs) - this.loss(lowArgs); - for (let i = 0; i < 6; i++) { - const g = (lossDiff / (2 * ck)) * deltas[i]; - const ak = a[i] / Math.pow(A + k + 1, alpha); - values[i] = fix(values[i] - ak * g, i); - } - - const loss = this.loss(values); - if (loss < bestLoss) { - best = values.slice(0); - bestLoss = loss; - } - } - return { values: best, loss: bestLoss }; - - function fix(value, idx) { - let max = 100; - if (idx === 2 /* saturate */) { - max = 7500; - } else if (idx === 4 /* brightness */ || idx === 5 /* contrast */) { - max = 200; - } - - if (idx === 3 /* hue-rotate */) { - if (value > max) { - value %= max; - } else if (value < 0) { - value = max + (value % max); - } - } else if (value < 0) { - value = 0; - } else if (value > max) { - value = max; - } - return value; - } - } - - loss(filters) { - // Argument is array of percentages. - const color = this.reusedColor; - color.set(0, 0, 0); - - color.invert(filters[0] / 100); - color.sepia(filters[1] / 100); - color.saturate(filters[2] / 100); - color.hueRotate(filters[3] * 3.6); - color.brightness(filters[4] / 100); - color.contrast(filters[5] / 100); - - const colorHSL = color.hsl(); - return ( - Math.abs(color.r - this.target.r) + - Math.abs(color.g - this.target.g) + - Math.abs(color.b - this.target.b) + - Math.abs(colorHSL.h - this.targetHSL.h) + - Math.abs(colorHSL.s - this.targetHSL.s) + - Math.abs(colorHSL.l - this.targetHSL.l) - ); - } - - css(filters) { - function fmt(idx, multiplier = 1) { - return Math.round(filters[idx] * multiplier); - } - return ` - brightness(0) - saturate(100%) - invert(${fmt(0)}%) - sepia(${fmt(1)}%) - saturate(${fmt(2)}%) - hue-rotate(${fmt(3, 3.6)}deg) - brightness(${fmt(4)}%) - contrast(${fmt(5)}%); - `; - } -}