├── deploy
├── vite.config.main.js
└── vite.config.gh-pages.js
├── images
├── gphg.png
├── favicon.ico
├── favicon-16x16.png
├── favicon-32x32.png
├── apple-touch-icon.png
├── android-chrome-192x192.png
├── android-chrome-512x512.png
├── github-profile-header-generator-demo.webm
├── github-profile-header-generator-demo-poster.png
├── icons
│ ├── center-align.svg
│ ├── left-align.svg
│ └── right-align.svg
├── gphg.svg
├── github-logo-40.svg
└── github-logo-20.svg
├── social
├── social-preview.png
├── examples
│ ├── example-1.png
│ ├── example-2.png
│ ├── example-3.png
│ ├── example-4.png
│ └── example-5.png
├── repo-header-image.png
└── social-preview-small.png
├── public
├── images
│ ├── decorations
│ │ ├── js.png
│ │ ├── apple.png
│ │ ├── code.png
│ │ ├── css.png
│ │ ├── dino.png
│ │ ├── html.png
│ │ ├── idea.png
│ │ ├── tabs.png
│ │ ├── coding.png
│ │ ├── octocat.png
│ │ ├── rocket.png
│ │ ├── dev-badge.png
│ │ ├── dev-white.png
│ │ ├── my-octocat.png
│ │ ├── terminal.png
│ │ ├── binary-code.png
│ │ ├── dev-rainbow.png
│ │ ├── dino-border.png
│ │ ├── github-mark.png
│ │ ├── programming.png
│ │ ├── apple-thumbnail.png
│ │ ├── code-thumbnail.png
│ │ ├── coding-screen.png
│ │ ├── idea-thumbnail.png
│ │ ├── tabs-thumbnail.png
│ │ ├── terminal-circle.png
│ │ ├── coding-thumbnail.png
│ │ ├── headphones-cat-1.png
│ │ ├── headphones-cat-2.png
│ │ ├── octocat-thumbnail.png
│ │ ├── rocket-thumbnail.png
│ │ ├── dev-badge-thumbnail.png
│ │ ├── dev-white-thumbnail.png
│ │ ├── my-octocat-thumbnail.png
│ │ ├── terminal-thumbnail.png
│ │ ├── binary-code-thumbnail.png
│ │ ├── dev-rainbow-thumbnail.png
│ │ ├── github-mark-thumbnail.png
│ │ ├── programming-thumbnail.png
│ │ ├── coding-screen-thumbnail.png
│ │ └── terminal-circle-thumbnail.png
│ ├── icons
│ │ ├── loading.gif
│ │ ├── info.svg
│ │ ├── close.svg
│ │ ├── product-hunt.svg
│ │ ├── heart.svg
│ │ ├── heart-circle.svg
│ │ ├── moon.svg
│ │ ├── light-dark.svg
│ │ ├── light-dark-black.svg
│ │ ├── download.svg
│ │ ├── download-black.svg
│ │ ├── sun.svg
│ │ ├── random.svg
│ │ ├── random-black.svg
│ │ ├── reset.svg
│ │ └── reset-black.svg
│ ├── theme-previews
│ │ ├── theme-0-preview.png
│ │ ├── theme-1-preview.png
│ │ ├── theme-10-preview.png
│ │ ├── theme-11-preview.png
│ │ ├── theme-12-preview.png
│ │ ├── theme-13-preview.png
│ │ ├── theme-14-preview.png
│ │ ├── theme-15-preview.png
│ │ ├── theme-16-preview.png
│ │ ├── theme-17-preview.png
│ │ ├── theme-18-preview.png
│ │ ├── theme-19-preview.png
│ │ ├── theme-2-preview.png
│ │ ├── theme-20-preview.png
│ │ ├── theme-21-preview.png
│ │ ├── theme-22-preview.png
│ │ ├── theme-23-preview.png
│ │ ├── theme-3-preview.png
│ │ ├── theme-4-preview.png
│ │ ├── theme-5-preview.png
│ │ ├── theme-6-preview.png
│ │ ├── theme-7-preview.png
│ │ ├── theme-8-preview.png
│ │ └── theme-9-preview.png
│ └── patterns
│ │ ├── honeycomb-thumbnail.svg
│ │ ├── 4-point-stars-thumbnail.svg
│ │ ├── aztec-thumbnail.svg
│ │ ├── falling-triangles-thumbnail.svg
│ │ ├── overlapping-circles-thumbnail.svg
│ │ ├── squares-thumbnail.svg
│ │ ├── random-shapes-thumbnail.svg
│ │ ├── bubbles-thumbnail.svg
│ │ ├── squares-in-squares-thumbnail.svg
│ │ ├── bathroom-floor-thumbnail.svg
│ │ ├── brick-wall-thumbnail.svg
│ │ ├── temple-thumbnail.svg
│ │ ├── leaf-thumbnail.svg
│ │ ├── hideout-thumbnail.svg
│ │ ├── github-thumbnail.svg
│ │ ├── graph-paper-thumbnail.svg
│ │ ├── dalmatian-spots-thumbnail.svg
│ │ ├── jigsaw-thumbnail.svg
│ │ ├── lisbon-thumbnail.svg
│ │ ├── glamorous-thumbnail.svg
│ │ ├── circuit-board-thumbnail.svg
│ │ └── endless-constellation-thumbnail.svg
├── robots.txt
├── sitemap.xml
└── site.webmanifest
├── styles
├── index.scss
├── reset.scss
├── how-to.scss
├── toolbox-presets.scss
├── variables.scss
├── modals.scss
├── toolbox-decorations.scss
├── tabs.scss
├── toolbox-background.scss
├── toolbox-test-fonts.scss
└── toolbox-main.scss
├── vite.config.js
├── Dockerfile
├── .gitignore
├── docker-compose.yml
├── .github
├── SECURITY.md
├── pull_request_template.md
├── ISSUE_TEMPLATE
│ └── bug_report.md
├── workflows
│ └── gh-pages.yml
├── CONTRIBUTING.md
└── CODE_OF_CONDUCT.md
├── conf
└── default.conf
├── partials
├── toolbox
│ ├── presets.html
│ ├── result.html
│ ├── test-fonts.html
│ └── decorations.html
├── scripts.html
├── header.html
├── modals
│ ├── feedback.html
│ ├── special-message.html
│ └── info.html
├── how-to.html
├── footer.html
└── head.html
├── js
├── presets.js
├── helpers
│ ├── helpers.js
│ └── elements.js
├── toolbox-presets.js
├── toolbox-decorations.js
├── toolbox-background.js
├── toolbox-main.js
└── main.js
├── package.json
├── LICENSE
├── index.html
└── README.md
/deploy/vite.config.main.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | build: {
3 | emptyOutDir: true
4 | }
5 | }
--------------------------------------------------------------------------------
/images/gphg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/images/gphg.png
--------------------------------------------------------------------------------
/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/images/favicon.ico
--------------------------------------------------------------------------------
/images/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/images/favicon-16x16.png
--------------------------------------------------------------------------------
/images/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/images/favicon-32x32.png
--------------------------------------------------------------------------------
/social/social-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/social/social-preview.png
--------------------------------------------------------------------------------
/images/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/images/apple-touch-icon.png
--------------------------------------------------------------------------------
/social/examples/example-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/social/examples/example-1.png
--------------------------------------------------------------------------------
/social/examples/example-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/social/examples/example-2.png
--------------------------------------------------------------------------------
/social/examples/example-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/social/examples/example-3.png
--------------------------------------------------------------------------------
/social/examples/example-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/social/examples/example-4.png
--------------------------------------------------------------------------------
/social/examples/example-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/social/examples/example-5.png
--------------------------------------------------------------------------------
/social/repo-header-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/social/repo-header-image.png
--------------------------------------------------------------------------------
/public/images/decorations/js.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/js.png
--------------------------------------------------------------------------------
/public/images/icons/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/icons/loading.gif
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-Agent: *
2 | Allow: /
3 |
4 | Sitemap: https://leviarista.github.io/github-profile-header-generator/sitemap.xml
5 |
--------------------------------------------------------------------------------
/social/social-preview-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/social/social-preview-small.png
--------------------------------------------------------------------------------
/images/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/images/android-chrome-192x192.png
--------------------------------------------------------------------------------
/images/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/images/android-chrome-512x512.png
--------------------------------------------------------------------------------
/public/images/decorations/apple.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/apple.png
--------------------------------------------------------------------------------
/public/images/decorations/code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/code.png
--------------------------------------------------------------------------------
/public/images/decorations/css.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/css.png
--------------------------------------------------------------------------------
/public/images/decorations/dino.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/dino.png
--------------------------------------------------------------------------------
/public/images/decorations/html.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/html.png
--------------------------------------------------------------------------------
/public/images/decorations/idea.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/idea.png
--------------------------------------------------------------------------------
/public/images/decorations/tabs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/tabs.png
--------------------------------------------------------------------------------
/public/images/decorations/coding.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/coding.png
--------------------------------------------------------------------------------
/public/images/decorations/octocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/octocat.png
--------------------------------------------------------------------------------
/public/images/decorations/rocket.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/rocket.png
--------------------------------------------------------------------------------
/public/images/decorations/dev-badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/dev-badge.png
--------------------------------------------------------------------------------
/public/images/decorations/dev-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/dev-white.png
--------------------------------------------------------------------------------
/public/images/decorations/my-octocat.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/my-octocat.png
--------------------------------------------------------------------------------
/public/images/decorations/terminal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/terminal.png
--------------------------------------------------------------------------------
/public/images/decorations/binary-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/binary-code.png
--------------------------------------------------------------------------------
/public/images/decorations/dev-rainbow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/dev-rainbow.png
--------------------------------------------------------------------------------
/public/images/decorations/dino-border.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/dino-border.png
--------------------------------------------------------------------------------
/public/images/decorations/github-mark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/github-mark.png
--------------------------------------------------------------------------------
/public/images/decorations/programming.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/programming.png
--------------------------------------------------------------------------------
/public/images/decorations/apple-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/apple-thumbnail.png
--------------------------------------------------------------------------------
/public/images/decorations/code-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/code-thumbnail.png
--------------------------------------------------------------------------------
/public/images/decorations/coding-screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/coding-screen.png
--------------------------------------------------------------------------------
/public/images/decorations/idea-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/idea-thumbnail.png
--------------------------------------------------------------------------------
/public/images/decorations/tabs-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/tabs-thumbnail.png
--------------------------------------------------------------------------------
/public/images/decorations/terminal-circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/terminal-circle.png
--------------------------------------------------------------------------------
/public/images/decorations/coding-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/coding-thumbnail.png
--------------------------------------------------------------------------------
/public/images/decorations/headphones-cat-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/headphones-cat-1.png
--------------------------------------------------------------------------------
/public/images/decorations/headphones-cat-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/headphones-cat-2.png
--------------------------------------------------------------------------------
/public/images/decorations/octocat-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/octocat-thumbnail.png
--------------------------------------------------------------------------------
/public/images/decorations/rocket-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/rocket-thumbnail.png
--------------------------------------------------------------------------------
/images/github-profile-header-generator-demo.webm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/images/github-profile-header-generator-demo.webm
--------------------------------------------------------------------------------
/public/images/decorations/dev-badge-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/dev-badge-thumbnail.png
--------------------------------------------------------------------------------
/public/images/decorations/dev-white-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/dev-white-thumbnail.png
--------------------------------------------------------------------------------
/public/images/decorations/my-octocat-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/my-octocat-thumbnail.png
--------------------------------------------------------------------------------
/public/images/decorations/terminal-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/terminal-thumbnail.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-0-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-0-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-1-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-1-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-10-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-10-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-11-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-11-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-12-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-12-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-13-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-13-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-14-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-14-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-15-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-15-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-16-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-16-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-17-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-17-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-18-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-18-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-19-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-19-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-2-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-2-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-20-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-20-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-21-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-21-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-22-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-22-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-23-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-23-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-3-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-3-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-4-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-4-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-5-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-5-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-6-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-6-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-7-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-7-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-8-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-8-preview.png
--------------------------------------------------------------------------------
/public/images/theme-previews/theme-9-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/theme-previews/theme-9-preview.png
--------------------------------------------------------------------------------
/public/images/decorations/binary-code-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/binary-code-thumbnail.png
--------------------------------------------------------------------------------
/public/images/decorations/dev-rainbow-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/dev-rainbow-thumbnail.png
--------------------------------------------------------------------------------
/public/images/decorations/github-mark-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/github-mark-thumbnail.png
--------------------------------------------------------------------------------
/public/images/decorations/programming-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/programming-thumbnail.png
--------------------------------------------------------------------------------
/images/github-profile-header-generator-demo-poster.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/images/github-profile-header-generator-demo-poster.png
--------------------------------------------------------------------------------
/public/images/decorations/coding-screen-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/coding-screen-thumbnail.png
--------------------------------------------------------------------------------
/public/images/decorations/terminal-circle-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/leviarista/github-profile-header-generator/HEAD/public/images/decorations/terminal-circle-thumbnail.png
--------------------------------------------------------------------------------
/images/icons/center-align.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/images/icons/left-align.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/images/icons/right-align.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/public/images/icons/info.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/styles/index.scss:
--------------------------------------------------------------------------------
1 | @use "reset";
2 | @use "variables";
3 | @use "main";
4 | @use "how-to";
5 | @use "toolbox-presets";
6 | @use "toolbox-main";
7 | @use "toolbox-background";
8 | @use "toolbox-decorations";
9 | @use "toolbox-test-fonts";
10 | @use "tabs";
11 | @use "modals";
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 | import injectHTML from 'vite-plugin-html-inject';
3 |
4 | export default defineConfig({
5 | build: {
6 | emptyOutDir: true
7 | },
8 | plugins: [
9 | injectHTML(),
10 | ],
11 | });
12 |
--------------------------------------------------------------------------------
/public/images/icons/close.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/deploy/vite.config.gh-pages.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 | import injectHTML from 'vite-plugin-html-inject';
3 |
4 | export default defineConfig({
5 | base: '/github-profile-header-generator/',
6 | build: {
7 | emptyOutDir: true
8 | },
9 | plugins: [
10 | injectHTML(),
11 | ],
12 | });
13 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # Build
2 | FROM node:20-alpine AS build
3 |
4 | WORKDIR /usr/src/app
5 |
6 | COPY package.json package-lock.json ./
7 |
8 | RUN npm install
9 |
10 | COPY . .
11 |
12 | RUN npm run build
13 |
14 | # Setup nginx
15 | FROM nginx:1.21.6-alpine
16 | COPY conf/default.conf /etc/nginx/conf.d/
17 | COPY --from=build /usr/src/app/dist /usr/share/nginx/html
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '2'
2 |
3 | services:
4 | web:
5 | build:
6 | dockerfile: Dockerfile
7 | context: .
8 | image: github-profile-header-generator:latest
9 | container_name: github-profile-header-generator
10 | ports:
11 | - 8008:80
12 | restart: always
13 | mem_limit: 256m
14 | logging:
15 | options:
16 | "max-size": 2048m
17 |
18 |
--------------------------------------------------------------------------------
/public/images/patterns/honeycomb-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.github/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | | Version | Supported |
6 | | ------- | ------------------ |
7 | | 2.0.0 | :white_check_mark: |
8 | | < 2.0.0 | :x: |
9 |
10 | ## Reporting a Vulnerability
11 |
12 | Please create a new issue with all the information you can share and assign it to me @leviarista
13 |
14 | Thanks for contributing to the project's security. I appreciate it.
15 |
--------------------------------------------------------------------------------
/public/images/icons/product-hunt.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/public/images/icons/heart.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/public/images/patterns/4-point-stars-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/icons/heart-circle.svg:
--------------------------------------------------------------------------------
1 | ionicons-v5-f
--------------------------------------------------------------------------------
/styles/reset.scss:
--------------------------------------------------------------------------------
1 | html {
2 | box-sizing: border-box;
3 | font-size: 14px;
4 | }
5 |
6 | * {
7 | border: none;
8 | }
9 |
10 | *,
11 | *:before,
12 | *:after {
13 | box-sizing: inherit;
14 | }
15 |
16 | body,
17 | h1,
18 | h2,
19 | h3,
20 | h4,
21 | h5,
22 | h6,
23 | p,
24 | ol,
25 | ul {
26 | margin: 0;
27 | padding: 0;
28 | font-weight: normal;
29 | }
30 |
31 | html, body {
32 | min-height: 100%;
33 | height: 100%;
34 | }
35 | @media (max-width: 768px) {
36 | body {
37 | height: auto;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/public/sitemap.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 | https://leviarista.github.io/github-profile-header-generator/
12 | 2025-10-27T02:50:07+00:00
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/public/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Github Profile Header Generator",
3 | "short_name": "A simple but nice header image generator for your Github profile",
4 | "icons": [
5 | {
6 | "src": "/android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "/android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
--------------------------------------------------------------------------------
/public/images/patterns/aztec-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
--------------------------------------------------------------------------------
/conf/default.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80;
3 | sendfile on;
4 | default_type application/octet-stream;
5 | gzip on;
6 | gzip_http_version 1.1;
7 | gzip_disable "MSIE [1-6]\.";
8 | gzip_min_length 1100;
9 | gzip_vary on;
10 | gzip_proxied expired no-cache no-store private auth;
11 | gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
12 | gzip_comp_level 9;
13 |
14 | root /usr/share/nginx/html;
15 |
16 | location / {
17 | try_files $uri $uri/ /index.html =404;
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/partials/toolbox/presets.html:
--------------------------------------------------------------------------------
1 |
2 |
Choose a preset theme or customize your own with the options above.
3 |
You can use it for your repo banners too!
4 |
5 |
14 |
--------------------------------------------------------------------------------
/js/presets.js:
--------------------------------------------------------------------------------
1 | import presets from "./data/presets.json";
2 | import { updateBanner, updateUIOptions } from "./banner";
3 |
4 | function getAllPresets() {
5 | return presets;
6 | }
7 |
8 | function getPreset(index) {
9 | return presets[index];
10 | }
11 |
12 | function getRandomPreset() {
13 | let random = Math.floor(Math.random() * presets.length);
14 | return presets[random];
15 | }
16 |
17 | function setPreset(preset, ignoreSave = null) {
18 | updateUIOptions(preset);
19 | updateBanner({ ...preset, ignoreSave });
20 | }
21 |
22 | export {
23 | getAllPresets,
24 | getPreset,
25 | getRandomPreset,
26 | setPreset,
27 | };
28 |
--------------------------------------------------------------------------------
/partials/scripts.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/public/images/icons/moon.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/partials/header.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | # Pull Request Title
2 |
3 | ## Description
4 |
5 | > Summary why you opened this PR, you may add the benefits this PR provides.
6 |
7 | ## Changes
8 |
9 | > Please describe your changes, if needed attach screenshots.
10 | 1. Fix ...
11 | 2. Refactor ...
12 | 3. Update ...
13 | 4. Implement ...
14 |
15 | ## Screenshots
16 | (_If applicable_)
17 |
18 | | Picture Name |
19 | | :-------------------------: |
20 | | _Insert your picture link_ |
21 |
22 | ## Related Issues
23 |
24 | > Please add any related issue(s):
25 |
26 | This PR:
27 | - Fixes [Issue ticket name](Issue ticket link)
28 | - Implements [Issue ticket name](Issue ticket link)
29 |
30 | ## Aditional information
31 |
32 | > Provide any additional information that might be useful.
33 |
--------------------------------------------------------------------------------
/js/helpers/helpers.js:
--------------------------------------------------------------------------------
1 | const isLocalDevelopment = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
2 |
3 | const queryString = window.location.search;
4 | const urlParams = new URLSearchParams(queryString);
5 | const isDevOptions = urlParams.get('devOptions');
6 |
7 | function saveImageOnLocalStorage(img) {
8 | var canvas = document.createElement('canvas');
9 | var ctx = canvas.getContext('2d');
10 |
11 | canvas.width = img.width;
12 | canvas.height = img.height;
13 | ctx.drawImage(img, 0, 0, img.width, img.height);
14 |
15 | var dataURL = canvas.toDataURL('image/png');
16 | localStorage.setItem('savedImage', dataURL);
17 | }
18 |
19 | export {
20 | isLocalDevelopment,
21 | isDevOptions,
22 | saveImageOnLocalStorage
23 | };
24 |
--------------------------------------------------------------------------------
/images/gphg.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/patterns/falling-triangles-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/public/images/patterns/overlapping-circles-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/partials/modals/feedback.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Feedback
7 |
8 | Questions? Comments? Issues? I will be glad to hear you.
9 |
10 |
11 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/js/helpers/elements.js:
--------------------------------------------------------------------------------
1 | function getMainElements() {
2 | const bannerImageContainer = document.querySelector('.header-image-container');
3 | const bannerImage = document.querySelector('#github-header-image');
4 | const bannerTitle = bannerImage.querySelector('.title');
5 | const bannerSubtitle = bannerImage.querySelector('.subtitle');
6 |
7 | const toolbox = document.querySelector('.toolbox');
8 | const toolboxBackground = document.querySelector('.toolbox-background');
9 | const toolboxDecorations = document.querySelector('.toolbox-decorations');
10 | const toolboxPresets = document.querySelector('.toolbox-presets');
11 |
12 | return {
13 | bannerImageContainer,
14 | bannerImage,
15 | bannerTitle,
16 | bannerSubtitle,
17 | toolbox,
18 | toolboxDecorations,
19 | toolboxBackground,
20 | toolboxPresets
21 | }
22 | }
23 |
24 | export { getMainElements };
--------------------------------------------------------------------------------
/styles/how-to.scss:
--------------------------------------------------------------------------------
1 | .how-to-section {
2 | margin-top: 2rem;
3 | margin-bottom: 25px;
4 | text-align: center;
5 | flex-grow: 1;
6 |
7 | .title {
8 | font-family: "Kalam", sans-serif;
9 | }
10 |
11 | li {
12 | list-style-position: inside;
13 | margin-top: 10px;
14 |
15 | .demo {
16 | margin-top: 10px;
17 | }
18 |
19 | a {
20 | text-decoration: underline;
21 | }
22 |
23 | .code {
24 | margin: auto;
25 | margin-top: 5px;
26 | width: fit-content;
27 | padding: 5px 10px;
28 | background-color: #22272e;
29 | border-radius: 5px;
30 |
31 | code {
32 | font-size: 0.9rem;
33 | }
34 | }
35 | }
36 | }
37 |
38 | @media (max-width: 768px) {
39 | .how-to-section {
40 | margin-top: 25px;
41 | margin-bottom: 25px;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "github-profile-header-generator",
3 | "version": "2.1.0",
4 | "description": "A simple but nice header image generator for your Github profile",
5 | "scripts": {
6 | "dev": "vite",
7 | "build": "vite build",
8 | "preview": "vite preview",
9 | "build:gh-pages": "cp deploy/vite.config.gh-pages.js vite.config.js && vite build"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/leviarista/github-profile-header-generator.git"
14 | },
15 | "author": "Leví Arista",
16 | "license": "MIT",
17 | "bugs": {
18 | "url": "https://github.com/leviarista/github-profile-header-generator/issues"
19 | },
20 | "homepage": "https://github.com/leviarista/github-profile-header-generator#readme",
21 | "devDependencies": {
22 | "sass": "^1.89.2",
23 | "vite": "^7.0.3",
24 | "vite-plugin-html-inject": "^1.1.2"
25 | },
26 | "dependencies": {
27 | "@zumer/snapdom": "^1.9.7"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Report any bug you find
4 | title: "[Bug] "
5 | labels: bug
6 | assignees: leviarista
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to 'x' section
16 | 2. Select these options: ...
17 | 3. Click on 'x'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, please add screenshots to help explain your problem.
25 | Also, if possible, a screenshot of your browser console will help.
26 |
27 | ** Device information**
28 | - Device type (desktop, mobile phone, tablet, ...)
29 | - Operating System
30 | - Browser (if you include your version will be helpful)
31 | - Any relevant browser extension installed?
32 |
33 | **Additional context**
34 | Add any other context about the problem here.
35 |
--------------------------------------------------------------------------------
/public/images/patterns/squares-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Leví Arista
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/js/toolbox-presets.js:
--------------------------------------------------------------------------------
1 | import { getAllPresets, setPreset } from "./presets";
2 | import { getMainElements } from "./helpers/elements"
3 |
4 | const themes = getAllPresets();
5 | const { toolboxPresets } = getMainElements();
6 |
7 | document.addEventListener('DOMContentLoaded', function () {
8 | if (toolboxPresets) {
9 | toolboxPresets.querySelectorAll('.theme-button-white')[0].addEventListener('click', (e) => {
10 | document.querySelector('.tab .tablinks[data-name="main-section"]').click();
11 | })
12 |
13 | themes.forEach(theme => {
14 | const div = document.createElement('div');
15 | div.classList.add('theme-button');
16 | div.setAttribute('role', 'button')
17 |
18 | const img = document.createElement('img');
19 | img.src = './images/theme-previews/' + theme.previewImage;
20 | img.alt = 'Theme image';
21 |
22 | img.addEventListener('click', (e) => {
23 | setPreset(theme);
24 | });
25 |
26 | div.appendChild(img);
27 |
28 | toolboxPresets.appendChild(div);
29 | })
30 | }
31 | });
--------------------------------------------------------------------------------
/.github/workflows/gh-pages.yml:
--------------------------------------------------------------------------------
1 | name: Build and Deploy for GH Pages
2 | on:
3 | push:
4 | branches:
5 | - main
6 | paths-ignore:
7 | - '**/*.md'
8 | pull_request:
9 | types: [opened, synchronize, reopened, closed]
10 | branches:
11 | - main
12 | paths-ignore:
13 | - '**/*.md'
14 | jobs:
15 | build-and-deploy:
16 | concurrency: ci-${{ github.ref }} # Recommended if you intend to make multiple deployments in quick succession.
17 | runs-on: ubuntu-latest
18 | steps:
19 | - name: Checkout 🛎️
20 | uses: actions/checkout@v3
21 |
22 | - name: Install and Build 🔧 # This example project is built using npm and outputs the result to the 'build' folder. Replace with the commands required to build your project, or remove this step entirely if your site is pre-built.
23 | run: |
24 | npm ci
25 | npm run build:gh-pages
26 |
27 | - name: Deploy 🚀
28 | uses: JamesIves/github-pages-deploy-action@v4.2.5
29 | with:
30 | branch: gh-pages # The branch the action should deploy to.
31 | folder: dist # The folder the action should deploy.
32 |
--------------------------------------------------------------------------------
/public/images/patterns/random-shapes-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/patterns/bubbles-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/partials/how-to.html:
--------------------------------------------------------------------------------
1 |
2 | How to use it?
3 |
4 |
5 | Create a nice github header image.
6 |
8 | Github Profile Header Generator Demo
9 |
10 |
11 |
12 | Create your GitHub profile README following
13 |
15 | this guide .
16 |
17 |
18 | Upload your header to your profile/projecy repo.
19 |
20 | Add this line to your README:
21 | 
22 |
23 |
24 |
25 | You can use it for your repo banners too!
26 |
--------------------------------------------------------------------------------
/partials/modals/special-message.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Good news!
7 |
8 |
Jesus loves you
9 |
10 |
11 |
16 |
17 |
18 |
19 |
20 | For God so loved the world, that he gave his only Son, that whoever believes in him should not
21 | perish but have eternal life.
22 |
23 |
24 |
25 |
John 3:16
26 |
27 |
--------------------------------------------------------------------------------
/public/images/patterns/squares-in-squares-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/public/images/patterns/bathroom-floor-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/images/github-logo-40.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/images/github-logo-20.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/public/images/icons/light-dark.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/public/images/icons/light-dark-black.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/styles/toolbox-presets.scss:
--------------------------------------------------------------------------------
1 | #presets-section {
2 | text-align: center;
3 | padding: 0;
4 |
5 | .toolbox-presets {
6 | padding: 10px;
7 | display: flex;
8 | justify-content: center;
9 | flex-wrap: wrap;
10 | gap: 1rem;
11 |
12 | .theme-button {
13 | width: 185px;
14 | display: flex;
15 | cursor: pointer;
16 |
17 | img {
18 | max-width: 100%;
19 | object-fit: contain;
20 | transition: all ease-in-out 300ms;
21 |
22 | &:hover {
23 | filter: drop-shadow(0px 0px 5px rgba(255, 255, 255, 0.5));
24 | }
25 | }
26 |
27 | &-white {
28 | min-height: 45px;
29 | display: flex;
30 | justify-content: center;
31 | align-items: center;
32 | background: rgba(255, 255, 255, 0.15);
33 | border: 1px solid rgb(255, 255, 255, 0.5);
34 | border-radius: 5px;
35 |
36 | &:hover {
37 | filter: drop-shadow(0px 0px 5px rgba(255, 255, 255, 0.5));
38 | }
39 | }
40 | }
41 | }
42 | }
43 |
44 | @media (max-width: 768px) {
45 | #presets-section {
46 |
47 | .toolbox-presets {
48 | padding: 0;
49 | gap: 10px;
50 |
51 | .theme-button {
52 | width: 165px;
53 | }
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/partials/modals/info.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
Info & Credits
7 |
8 | Many of the patterns are here thanks to
9 | Hero Patterns
10 |
11 | and
12 |
13 | SVGBackgrounds.com
14 |
15 |
16 |
17 | Code icons created by Freepik - Flaticon
19 |
20 |
21 | This website is not affiliated, associated, authorized, endorsed by, or in any way officially
22 | connected with GitHub, or any of its subsidiaries or its affiliates. The official GitHub website can
23 | be found at
24 |
25 | https://github.com
26 |
27 | The name “GitHub” as well as related names, marks, emblems and images are registered trademarks
28 | of GitHub.
29 |
30 |
31 |
--------------------------------------------------------------------------------
/partials/toolbox/result.html:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
24 |
25 |
27 | Display
28 |
29 |
31 | Miniature
32 |
33 |
34 |
38 |
39 |
--------------------------------------------------------------------------------
/styles/variables.scss:
--------------------------------------------------------------------------------
1 | :root {
2 | --button-border-radius: 7px;
3 | --input-border-radius: 7px;
4 | --background-color: linear-gradient(180deg,
5 | #675494 0%,
6 | #605fa1 32.6%,
7 | #4e6db3 68.54%,
8 | #4078c0 100%);
9 | --text-color: white;
10 | --paddings: 3rem;
11 | --github-dark-mode-color: #0d1117;
12 | --github-light-mode-color: white;
13 | --main-font-familiy: "Red Hat Display", Arial, Helvetica, sans-serif;
14 |
15 |
16 | }
17 |
18 | [data-theme="dark"] {
19 | // --background-color: linear-gradient(180deg, #2A2142 0%, #2F3E6F 50%, #1A2A54 100%);
20 | // --background-color: linear-gradient(180deg, #201932 0%, #222c50 50%, #131e3c 100%);
21 | // --background-color: linear-gradient(180deg, #1B1B2F 0%, #121224 60%, #0A0A1A 100%);
22 | // --background-color: linear-gradient(180deg, #111110 0%, #1A1A1A 40%, #2E2E3A 100%);
23 | // --background-color: linear-gradient(180deg, #0d0a14 0%, #151b31 75%, #131e3c 100%);
24 | // --background-color: linear-gradient(180deg, #3b2e5a 0%, #4b3b7a 40%, #1a1a1a 100%);
25 | // --background-color: linear-gradient(180deg, #1e1436 0%, #2a1e4a 40%, #0a0a0a 100%);
26 | // --background-color: linear-gradient(180deg, #1A1924 0%, #2A2D40 50%, #0F1017 100%);
27 | // --background-color: linear-gradient(180deg, #121212 0%, #2F3E50 50%, #10192a 100%);
28 | --background-color: linear-gradient(180deg, #111110 0%, #1e2732 50%, #111110 100%);
29 |
30 | // --text-color: white;
31 | --text-color: #f5f5f5;
32 |
33 | .tab {
34 | background-color: #1b3050;
35 | }
36 | }
37 |
38 | @media (max-width: 768px) {
39 | :root {
40 | --paddings: 1rem;
41 | }
42 | }
--------------------------------------------------------------------------------
/public/images/patterns/brick-wall-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/partials/footer.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/patterns/temple-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/styles/modals.scss:
--------------------------------------------------------------------------------
1 | .modal {
2 | position: fixed;
3 | background-color: rgba(0, 0, 0, 0.7);
4 | top: 0;
5 | right: 0;
6 | bottom: 0;
7 | left: 0;
8 | z-index: 999;
9 | visibility: hidden;
10 | opacity: 0;
11 | pointer-events: none;
12 | transition: all 0.25s;
13 |
14 | &:target {
15 | visibility: visible;
16 | opacity: 1;
17 | pointer-events: auto;
18 | }
19 |
20 | &>div {
21 | width: 450px;
22 | margin-top: 15px;
23 | max-width: calc(100% - 30px);
24 | position: absolute;
25 | top: 50%;
26 | left: 50%;
27 | transform: translate(-50%, -50%);
28 | padding: 2em;
29 | background: var(--background-color);
30 | box-shadow: 0px 0px 5px rgba(255, 255, 255, 0.5), 0px 0px 10px rgba(0, 0, 0, 0.25);
31 | border-radius: var(--button-border-radius);
32 | }
33 |
34 | .modal-title {
35 | font-size: 1.2rem;
36 | }
37 |
38 | .modal-info-text {
39 | border-top: solid 1px rgba(255, 255, 255, 0.5);
40 | font-size: 12px;
41 | }
42 |
43 | a {
44 | font-weight: 700;
45 | }
46 | }
47 |
48 | .modal-close {
49 | position: absolute;
50 | right: 15px;
51 | top: 15px;
52 | }
53 |
54 | #feedback-modal {
55 | input {
56 | width: calc(50% - 2px);
57 | margin-bottom: 5px;
58 | }
59 | textarea{
60 | width: 100%;
61 |
62 | &::-webkit-scrollbar {
63 | width: 14px;
64 | cursor: pointer;
65 | }
66 |
67 | &::-webkit-scrollbar-track {
68 | background: rgba(0, 0, 0, 0.1);
69 | // -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.1);
70 | }
71 |
72 | &::-webkit-scrollbar-thumb {
73 | border-radius: var(--input-border-radius);
74 | background-color: rgba(255, 255, 255, 0.75);
75 | //
76 | }
77 | }
78 | button {
79 | display: block;
80 | margin-left: auto
81 | }
82 | }
--------------------------------------------------------------------------------
/styles/toolbox-decorations.scss:
--------------------------------------------------------------------------------
1 | .toolbox-decorations {
2 | box-sizing: border-box;
3 | max-width: 550px;
4 | margin: auto;
5 |
6 | > div {
7 | display: flex;
8 | align-items: center;
9 | justify-content: center;
10 | flex-wrap: wrap;
11 |
12 | &:not(:last-child) {
13 | margin-bottom: 15px;
14 | }
15 | }
16 |
17 | .decorations-buttons {
18 | button {
19 | width: 70px;
20 | height: 70px;
21 | padding: 0;
22 | margin-left: 5px;
23 | margin-bottom: 5px;
24 | display: flex;
25 | align-items: center;
26 | justify-content: center;
27 | transition: all ease-in-out 300ms;
28 |
29 | img {
30 | max-width: 50px;
31 | max-height: 50px;
32 | // border-radius: var(--input-border-radius);
33 | }
34 |
35 | &:hover {
36 | box-shadow: 0px 0px 5px 2px rgba(255, 255, 255, 0.25);
37 | }
38 |
39 | &.selected {
40 | border: solid white 2px;
41 | }
42 | }
43 | }
44 |
45 | .decorations-upload {
46 | flex-direction: column;
47 |
48 | input {
49 | margin-top: 5px;
50 | }
51 |
52 | .myoctocats-tip {
53 | margin-top: 10px;
54 | margin-bottom: 10px;
55 | padding: 20px;
56 | // border: 2px solid rgb(255, 255, 255, 0.5);
57 | border-radius: var(--input-border-radius);
58 | font-size: 0.9rem;
59 | // text-transform: uppercase;
60 | // text-align: center;
61 | line-height: 1.5;
62 | background: rgba(255, 255, 255, 0.15);
63 |
64 | a {
65 | font-weight: 700;
66 | text-decoration: underline;
67 | }
68 | }
69 | }
70 | }
71 |
72 | @media (max-width: 768px) {
73 | .toolbox-decorations {
74 | .decorations-buttons {
75 | button {
76 | margin-bottom: 5px;
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to contribute
2 |
3 | Glad to hear you're interested in contributing to the project!. Thank you so much.
4 | These are some ways how you can help:
5 |
6 | > ℹ️ After cloning the repo, please add `/?devOptions=1` in the URL, so you can see additional options for development mode
7 | > Also the hostname should be either `localhost`or `127.0.0.1`.
8 |
9 | #### Issues
10 | You can check the [Issues](https://github.com/rails/rails/issues) section and start working on some of the existing tickets.
11 |
12 | #### Bugs
13 | If you find a bug, please [create a new issue](https://github.com/leviarista/github-profile-header-generator/issues/new/choose).
14 |
15 | #### Presets
16 | Create more presets/themes:
17 | - Open the browser console.
18 | - Create your theme and copy the printed theme values from the console.
19 | - Click the "miniature" option and save the image, add it to `public/images/theme-previews/`.
20 | - Use the previuos console values to insert a new item on `/js/data/presets.json`.
21 | - Add a property called `"previewImage"` with the name of the miniature image.
22 | - For example: `"previewImage": "my-theme-preview.png"`
23 | - That's it!
24 |
25 | #### Add Background patterns
26 | - Go to `/js/data/patterns.js`, add a new case block with an appropriate name in the `getPattern` function.
27 | - After choosing a new pattern in SVG format, paste the SVG code of the image into the return value.
28 | - Change the `fill` and `fill-opacity` values that the function receives, for example:
29 | - `fill="#F12AA34"` -> `fill='%23${color}'`
30 | - `fill-opacity=0.5` -> `fill-opacity='${opacity}'`
31 | - [Optional] Add a predefined size in the getPatternDefaultSize function.
32 | - Create an appropriate thumbnail file and add it to `/public/images/patterns/`.
33 | - Go to `/partials/toolbox/background.html` and add a new button element in the `"patterns-buttons"` div section.
34 |
35 | #### Add new decorations
36 | - Place an image on `/public/images/decorations/`.
37 | - Go to `/partials/toolbox/decorations.html` and add a new button element in the `"decorations-buttons"` div section.
38 |
39 | #### Ideas or suggestions
40 | - Share them in the [discussions](https://github.com/leviarista/github-profile-header-generator/discussions) section.
41 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
20 |
21 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/js/toolbox-decorations.js:
--------------------------------------------------------------------------------
1 | import { updateBanner } from "./banner";
2 | import { getMainElements } from "./helpers/elements";
3 | import { saveImageOnLocalStorage } from "./helpers/helpers";
4 |
5 | /* ************** Elements ************** */
6 |
7 | const {
8 | toolboxDecorations,
9 | } = getMainElements();
10 |
11 | /* ************** Decorations inputs ************** */
12 |
13 | function setDecorationSize() {
14 | let selectedDecorationSize = toolboxDecorations.querySelector('.decorations-size-inputs input#decoration-size-input').value;
15 |
16 | updateBanner({
17 | decorationSize: selectedDecorationSize,
18 | });
19 | }
20 |
21 | toolboxDecorations.querySelectorAll('.decorations-size-inputs input[type="range"]')
22 | .forEach(input => {
23 | input.addEventListener('input', (e) => {
24 | e.target.nextElementSibling.value = e.target.value
25 | setDecorationSize();
26 | });
27 | })
28 |
29 | /* ************** Decorations ************** */
30 |
31 | toolboxDecorations.querySelectorAll('.decorations-buttons button')
32 | .forEach(button => {
33 | button.addEventListener('click', (e) => {
34 | const element = e.target.tagName.toLowerCase() === 'img' ?
35 | e.target.parentNode :
36 | e.target;
37 | const decorationValue = element.getAttribute('data-decoration-value');
38 | updateBanner({
39 | decoration: decorationValue,
40 | decorationLocal: false
41 | });
42 | setDecorationSize();
43 | });
44 | })
45 |
46 | /* ************** Upload decoration ************** */
47 |
48 | toolboxDecorations.querySelector('#decoration-upload-input')
49 | .addEventListener('change', () => {
50 | const file = toolboxDecorations.querySelector('#decoration-upload-input').files[0];
51 |
52 | let reader = new FileReader();
53 | reader.readAsDataURL(file);
54 | reader.onload = function (e) {
55 | updateBanner({
56 | decoration: this.result,
57 | decorationLocal: true
58 | });
59 |
60 | const decoration = document.querySelector('.img-decoration');
61 | saveImageOnLocalStorage(decoration);
62 | }
63 | })
64 |
65 | /* ************** ************** ************** */
66 |
--------------------------------------------------------------------------------
/public/images/icons/download.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
--------------------------------------------------------------------------------
/public/images/icons/download-black.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
--------------------------------------------------------------------------------
/public/images/patterns/leaf-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Github Profile Header Generator
4 |
5 | ## What is it?
6 |
7 | A simple but nice header image generator for your __Github profile Readme__.
8 | You can use it for your __repo banners__ too!
9 |
10 | [Create my banner!](https://leviarista.github.io/github-profile-header-generator/)
11 |
12 | ## How to use it?
13 |
14 | 1. Create a nice github header image.
15 | 2. Create your GitHub profile README following [this guide](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/customizing-your-profile/managing-your-profile-readme).
16 | 3. Upload your header to your profile repo.
17 | 4. Add this line to your README:
18 | ```Markdown
19 | 
20 | ```
21 |
22 | ## Examples
23 |
24 | 
25 | 
26 | 
27 | 
28 | 
29 |
30 | ## Features list
31 |
32 | - Edit title and subtitle texts.
33 | - Choose colors for text, background and borders.
34 | - Set dimensions and padding.
35 | - Align text and decorations.
36 | - Change fonts.
37 | - Set the size and radius of the border.
38 | - Set background pattern image, its color, size and opacity.
39 | - Add decorations.
40 | - Upload your own decoration, octocat or profile pic.
41 | - Toogle between Github dark and light mode.
42 | - Download image as png.
43 | - Choose from predefined presets or get a random one.
44 |
45 | ## Tech used
46 |
47 | - [Vite](https://vitejs.dev/)
48 | - [snapdom](https://zumerlab.github.io/snapdom/)
49 |
50 | ## Get started
51 |
52 | - `npm run dev`- starts dev server
53 | - `npm run build` - builds for production
54 | - `npm run preview` - locally previews production build
55 |
56 | ## Get started with Docker
57 |
58 | ```bash
59 | docker-compose up -d --build --force-recreate
60 | ```
61 |
62 | ## Contributing
63 |
64 | Check out our [Contributing guide](https://github.com/leviarista/github-profile-header-generator/blob/main/.github/CONTRIBUTING.md)
65 |
--------------------------------------------------------------------------------
/public/images/icons/sun.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/public/images/icons/random.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/public/images/icons/random-black.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
--------------------------------------------------------------------------------
/public/images/patterns/hideout-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
11 |
14 |
17 |
20 |
23 |
26 |
29 |
32 |
35 |
38 |
41 |
42 |
--------------------------------------------------------------------------------
/public/images/patterns/github-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/images/patterns/graph-paper-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/partials/toolbox/test-fonts.html:
--------------------------------------------------------------------------------
1 |
5 |
6 |
Hey! I'm Leví Arista. username/project - red-hat-display
7 |
8 |
9 |
10 |
11 |
Hey! I'm Leví Arista. username/project - ubuntu
12 |
13 |
14 |
Hey! I'm Leví Arista. username/project - poppins
15 |
Hey! I'm Leví Arista. username/project - anonymous-pro
16 |
Hey! I'm Leví Arista. username/project - source-code-pro
17 |
18 |
19 |
20 |
Hey! I'm Leví Arista. username/project - quattrocento
21 |
Hey! I'm Leví Arista. username/project - della-respira
22 |
Hey! I'm Leví Arista. username/project - lancelot
23 |
Hey! I'm Leví Arista. username/project - life-savers
24 |
Hey! I'm Leví Arista. username/project - athiti
25 |
Hey! I'm Leví Arista. username/project - electrolize
26 |
Hey! I'm Leví Arista. username/project - passero-one
27 |
Hey! I'm Leví Arista. username/project - pixelify-sans
28 |
Hey! I'm Leví Arista. username/project - kalam
29 |
Hey! I'm Leví Arista. username/project - playball
30 |
Hey! I'm Leví Arista. username/project - orbitron
31 |
32 |
33 |
--------------------------------------------------------------------------------
/styles/tabs.scss:
--------------------------------------------------------------------------------
1 | /* Style the tab */
2 | .tab {
3 | position: fixed;
4 | left: 50%;
5 | transform: translateX(calc(-50% + 190px));
6 | padding: 0 2px 2px 2px;
7 | width: fit-content;
8 | margin: 0 auto;
9 | display: grid;
10 | grid-template-columns: repeat(4, auto);
11 | gap: 2px;
12 | justify-content: center;
13 | color: var(--text-color);
14 | background: #6E5494;
15 | border-radius: 0 0 10px 10px;
16 | box-shadow: 0px 0px 5px 2px rgba(255, 255, 255, 0.25);
17 | // overflow: hidden;
18 | z-index: 10;
19 | user-select: none;
20 | }
21 |
22 | /* Style the buttons that are used to open the tab content */
23 | .tab button {
24 | background-color: inherit;
25 | border: none;
26 | outline: none;
27 | cursor: pointer;
28 | padding: 1rem 2rem;
29 | transition: 0.3s;
30 | color: rgb(240, 240, 240);
31 | border-radius: 0 0 9px 9px;
32 | font-weight: bold;
33 | }
34 |
35 | /* Change background color of buttons on hover */
36 | .tab button:hover {
37 | background-color: rgba(255, 255, 255, 0.15);
38 | }
39 |
40 | /* Create an active/current tablink class */
41 | .tab button.active {
42 | background-color: rgba(255, 255, 255, 0.15);
43 | // border-top-left-radius: 7px;
44 | // border-top-right-radius: 7px;
45 | }
46 |
47 | /* Style the tab content */
48 | .tabcontent {
49 | width: 100%;
50 | // max-width: calc(1280px - 296px - 24px);
51 | margin: auto;
52 | margin-top: calc(1rem + 2rem + 0.5rem);
53 | max-width: calc(850px);
54 | padding: 0.5rem 1rem 0.5rem 1rem;
55 | overflow: auto;
56 | }
57 |
58 | .tabcontent {
59 | animation: fadeEffect 1s;
60 | /* Fading effect takes 1 second */
61 | }
62 |
63 | /* Go from zero to full opacity */
64 | @keyframes fadeEffect {
65 | from {
66 | opacity: 0;
67 | }
68 |
69 | to {
70 | opacity: 1;
71 | }
72 | }
73 |
74 | @media (max-width: 850px) {
75 | .tab {
76 | button {
77 | padding: 10px 1rem;
78 | }
79 | }
80 | }
81 |
82 | @media (max-width: 768px) {
83 | .tab {
84 | position: static;
85 | width: 100%;
86 | transform: translateX(calc(0));
87 | display: grid;
88 | grid-template-columns: repeat(4, auto);
89 | gap: 1px;
90 | border-radius: 0;
91 | padding: 1px;
92 | overflow: auto;
93 |
94 | button {
95 | padding: 10px;
96 | border-radius: 0;
97 | }
98 | }
99 |
100 | .tabcontent {
101 | height: auto;
102 | margin-top: 1rem;
103 | }
104 | }
105 |
106 | @media (max-width: 360px) {
107 | .tab {
108 | width: 100%;
109 | margin: 0;
110 | left: 0;
111 | transform: translateX(calc(0));
112 | display: grid;
113 | grid-template-columns: repeat(4, auto);
114 | border-radius: 0;
115 | padding: 1px;
116 | overflow: auto;
117 |
118 | button {
119 | padding: 10px;
120 | border-radius: 0;
121 | }
122 | }
123 |
124 | }
--------------------------------------------------------------------------------
/styles/toolbox-background.scss:
--------------------------------------------------------------------------------
1 | .toolbox-background {
2 | box-sizing: border-box;
3 |
4 | > div {
5 | display: flex;
6 | align-items: center;
7 | justify-content: center;
8 | flex-wrap: wrap;
9 |
10 | &:not(:last-child) {
11 | margin-bottom: 15px;
12 | }
13 | }
14 |
15 | .bg-color-selectors {
16 | > div {
17 | display: flex;
18 | align-items: center;
19 |
20 | &:not(:last-child) {
21 | margin-right: 15px;
22 | }
23 | }
24 |
25 | input {
26 | margin-left: 5px;
27 | cursor: pointer;
28 | padding: 0;
29 | }
30 | }
31 |
32 | .border-inputs {
33 | div {
34 | display: flex;
35 | align-items: flex-start;
36 |
37 | &:not(:last-child) {
38 | margin-right: 15px;
39 | }
40 |
41 | input {
42 | cursor: pointer;
43 | }
44 | }
45 | }
46 |
47 | .pattern-inputs {
48 | div {
49 | display: flex;
50 | align-items: flex-start;
51 |
52 | &:not(:last-child) {
53 | margin-right: 15px;
54 | }
55 |
56 | &:first-child {
57 | align-items: center;
58 | }
59 |
60 | #pattern-color-selector {
61 | padding: 0;
62 | }
63 |
64 | input {
65 | margin-left: 5px;
66 | cursor: pointer;
67 | }
68 | }
69 | }
70 |
71 | .patterns-buttons {
72 | max-width: 550px;
73 | margin: auto;
74 | display: grid;
75 | grid-template-columns: repeat(auto-fill, 70px);
76 | gap: 5px;
77 |
78 | button {
79 | width: 70px;
80 | height: 70px;
81 | padding: 0;
82 | display: flex;
83 | align-items: center;
84 | justify-content: center;
85 | transition: all ease-in-out 300ms;
86 |
87 | img {
88 | width: 100%;
89 | max-width: 55px;
90 | max-height: 55px;
91 | }
92 |
93 | &:hover {
94 | box-shadow: 0px 0px 5px 2px rgba(255, 255, 255, 0.25);
95 | }
96 |
97 | &.selected {
98 | border: solid white 2px;
99 | }
100 | }
101 | }
102 | }
103 |
104 | @media (max-width: 768px) {
105 | .toolbox-background {
106 | .border-inputs {
107 | > div {
108 | &:not(:last-child) {
109 | margin-bottom: 10px;
110 | }
111 | }
112 | }
113 |
114 | .pattern-inputs {
115 | input {
116 | &:not(:last-child) {
117 | margin-bottom: 15px;
118 | }
119 | }
120 | }
121 |
122 | // .patterns-buttons {
123 | // button {
124 | // margin-bottom: 5px;
125 | // }
126 | // }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/public/images/patterns/dalmatian-spots-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/public/images/patterns/jigsaw-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/public/images/patterns/lisbon-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/styles/toolbox-test-fonts.scss:
--------------------------------------------------------------------------------
1 | .tablinks[data-name="test-fonts-section"] {
2 | position: fixed;
3 | right: 0;
4 | transform: translateX(100%);
5 | z-index: 100
6 | }
7 |
8 | #test-fonts-section {
9 | font-size: 20px;
10 | padding: 50px 0 100px 50px;
11 | background-color: #222;
12 | color: white;
13 | }
14 |
15 | .red-hat-display {
16 | font-family: "Red Hat Display", sans-serif;
17 | font-optical-sizing: auto;
18 | font-weight: 400;
19 | font-style: normal;
20 | }
21 |
22 | .kalam {
23 | font-family: "Kalam", cursive;
24 | font-weight: 400;
25 | font-style: normal;
26 | }
27 |
28 | .poppins {
29 | font-family: "Poppins", sans-serif;
30 | font-weight: 400;
31 | font-style: normal;
32 | }
33 |
34 |
35 | .maven-pro {
36 | font-family: "Maven Pro", sans-serif;
37 | font-optical-sizing: auto;
38 | font-weight: 400;
39 | font-style: normal;
40 | }
41 |
42 | .athiti {
43 | font-family: "Athiti", sans-serif;
44 | font-weight: 400;
45 | font-style: normal;
46 | }
47 |
48 | .ubuntu-sans {
49 | font-family: "Ubuntu Sans", sans-serif;
50 | font-optical-sizing: auto;
51 | font-weight: 400;
52 | font-style: normal;
53 | font-variation-settings:
54 | "wdth" 100;
55 | }
56 |
57 | .ubuntu {
58 | font-family: "Ubuntu", sans-serif;
59 | font-weight: 400;
60 | font-style: normal;
61 | }
62 |
63 | .istok-web {
64 | font-family: "Istok Web", sans-serif;
65 | font-weight: 400;
66 | font-style: normal;
67 | }
68 |
69 |
70 | .courgette {
71 | font-family: "Courgette", cursive;
72 | font-weight: 400;
73 | font-style: normal;
74 | }
75 |
76 | .quattrocento {
77 | font-family: "Quattrocento", serif;
78 | font-weight: 400;
79 | font-style: normal;
80 | }
81 |
82 | .della-respira {
83 | font-family: "Della Respira", serif;
84 | font-weight: 400;
85 | font-style: normal;
86 | }
87 |
88 | .lato {
89 | font-family: "Lato", sans-serif;
90 | font-weight: 400;
91 | font-style: normal;
92 | }
93 |
94 | .martel {
95 | font-family: "Martel", serif;
96 | font-weight: 400;
97 | font-style: normal;
98 | }
99 |
100 | .lancelot {
101 | font-family: "Lancelot", serif;
102 | font-weight: 400;
103 | font-style: normal;
104 | }
105 |
106 | .playball {
107 | font-family: "Playball", cursive;
108 | font-weight: 400;
109 | font-style: normal;
110 | }
111 |
112 |
113 | .life-savers {
114 | font-family: "Life Savers", serif;
115 | font-weight: 400;
116 | font-style: normal;
117 | }
118 |
119 | .anonymous-pro {
120 | font-family: "Anonymous Pro", monospace;
121 | font-weight: 400;
122 | font-style: normal;
123 | }
124 |
125 | .inconsolata {
126 | font-family: "Inconsolata", monospace;
127 | font-optical-sizing: auto;
128 | font-weight: 400;
129 | font-style: normal;
130 | font-variation-settings:
131 | "wdth" 100;
132 | }
133 |
134 | .fira-code {
135 | font-family: "Fira Code", monospace;
136 | font-optical-sizing: auto;
137 | font-weight: 400;
138 | font-style: normal;
139 | }
140 |
141 | .open-sans {
142 | font-family: "Open Sans", sans-serif;
143 | font-optical-sizing: auto;
144 | font-weight: 400;
145 | font-style: normal;
146 | font-variation-settings:
147 | "wdth" 100;
148 | }
149 |
150 | .playwrite-hu {
151 | font-family: "Playwrite HU", cursive;
152 | font-optical-sizing: auto;
153 | font-weight: 400;
154 | font-style: normal;
155 | }
156 |
157 |
158 | .dancing-script {
159 | font-family: "Dancing Script", cursive;
160 | font-optical-sizing: auto;
161 | font-weight: 400;
162 | font-style: normal;
163 | }
164 |
165 | .passero-one {
166 | font-family: "Passero One", sans-serif;
167 | font-weight: 400;
168 | font-style: normal;
169 | }
170 |
171 | .pixelify-sans {
172 | font-family: "Pixelify Sans", sans-serif;
173 | font-optical-sizing: auto;
174 | font-weight: 400;
175 | font-style: normal;
176 | }
177 |
178 | .electrolize {
179 | font-family: "Electrolize", sans-serif;
180 | font-weight: 400;
181 | font-style: normal;
182 | }
183 |
184 | .source-code-pro {
185 | font-family: "Source Code Pro", monospace;
186 | font-optical-sizing: auto;
187 | font-weight: 400;
188 | font-style: normal;
189 | }
--------------------------------------------------------------------------------
/public/images/icons/reset.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/public/images/icons/reset-black.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/js/toolbox-background.js:
--------------------------------------------------------------------------------
1 | import { getSavedThemeProp, updateBanner } from './banner';
2 | import { getPatternDefaultSize } from './data/patterns';
3 | import { getMainElements } from './helpers/elements';
4 |
5 | /* ************** Elements ************** */
6 |
7 | const {
8 | toolboxBackground,
9 | } = getMainElements();
10 |
11 | let selectedPattern = getSavedThemeProp('pattern');
12 | let selectedPatternOpacity;
13 | let selectedPatternColor;
14 | let selectedPatternSize;
15 |
16 | /* ************** Color selectors ************** */
17 |
18 | function setBgColorValues() {
19 | let bgColorSelector = toolboxBackground.querySelector('.bg-color-selectors input#background-bg-color-selector');
20 | let borderColorSelector = toolboxBackground.querySelector('.bg-color-selectors input#border-color-selector');
21 |
22 | updateBanner({
23 | background: bgColorSelector.value,
24 | borderColor: borderColorSelector.value,
25 | });
26 |
27 | let mainTabBgColorSelector = document.querySelector('.color-selectors-container input#main-bg-color-selector');
28 | mainTabBgColorSelector.value = bgColorSelector.value;
29 | }
30 |
31 | toolboxBackground.querySelectorAll('.bg-color-selectors input')
32 | .forEach(input => {
33 | input.addEventListener('input', (e) => {
34 | setBgColorValues();
35 | });
36 | })
37 |
38 | /* ************** Border Inputs ************** */
39 |
40 | function setBorderValues() {
41 | let borderInput = toolboxBackground.querySelector('.border-inputs input#border-input');
42 | let borderRadiusInput = toolboxBackground.querySelector('.border-inputs input#border-radius-input');
43 | let borderColorSelector = toolboxBackground.querySelector('.bg-color-selectors input#border-color-selector');
44 |
45 | updateBanner({
46 | borderColor: borderColorSelector.value,
47 | borderSize: borderInput.value,
48 | borderRadius: borderRadiusInput.value
49 | });
50 | }
51 |
52 | toolboxBackground.querySelectorAll('.border-inputs input')
53 | .forEach(input => {
54 | input.addEventListener('input', (e) => {
55 | e.target.nextElementSibling.value = e.target.value
56 | setBorderValues();
57 | });
58 | })
59 |
60 | /* ************** Pattern inputs ************** */
61 |
62 | function setPatternValues() {
63 | selectedPatternOpacity = toolboxBackground.querySelector('.pattern-inputs input#pattern-opacity-input').value;
64 | selectedPatternSize = toolboxBackground.querySelector('.pattern-inputs input#pattern-size-input').value;
65 | }
66 |
67 | toolboxBackground.querySelectorAll('.pattern-inputs input[type="range"]')
68 | .forEach(input => {
69 | input.addEventListener('input', (e) => {
70 | e.target.nextElementSibling.value = e.target.value
71 | setPatternValues();
72 | setPatternBackground();
73 | });
74 | })
75 |
76 | toolboxBackground.querySelectorAll('.pattern-inputs input[type="color"]')
77 | .forEach(input => {
78 | input.addEventListener('input', (e) => {
79 | setPatternBackground();
80 | });
81 | })
82 |
83 | /* ************** Patterns ************** */
84 |
85 | function setPatternBackground() {
86 | const selectedPatternColor = toolboxBackground.querySelector('.pattern-inputs input#pattern-color-selector').value;
87 |
88 | updateBanner({
89 | pattern: selectedPattern,
90 | patternColor: selectedPatternColor,
91 | patternOpacity: selectedPatternOpacity,
92 | patternSize: selectedPatternSize
93 | });
94 | }
95 |
96 | toolboxBackground.querySelectorAll('.patterns-buttons button')
97 | .forEach(button => {
98 | button.addEventListener('click', (e) => {
99 | const element = e.target.tagName.toLowerCase() === 'img' ?
100 | e.target.parentNode :
101 | e.target;
102 | const patternValue = element.getAttribute('data-pattern-value');
103 | selectedPattern = patternValue;
104 | setPatternDefaultSize(patternValue);
105 | setPatternValues();
106 | setPatternBackground();
107 | });
108 | })
109 |
110 | function setPatternDefaultSize(patternValue) {
111 | selectedPatternSize = getPatternDefaultSize(patternValue);
112 | toolboxBackground.querySelector('.pattern-inputs #pattern-size-input').value = selectedPatternSize;
113 | toolboxBackground.querySelector('.pattern-inputs #pattern-size-input').nextElementSibling.innerHTML = selectedPatternSize;
114 | }
115 |
116 | /* ************** ************** ************** */
--------------------------------------------------------------------------------
/public/images/patterns/glamorous-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
11 |
13 |
15 |
18 |
21 |
24 |
26 |
28 |
31 |
34 |
37 |
38 |
--------------------------------------------------------------------------------
/public/images/patterns/circuit-board-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/js/toolbox-main.js:
--------------------------------------------------------------------------------
1 | import { updateBanner } from './banner';
2 | import { getMainElements } from './helpers/elements';
3 |
4 | /* ************** Elements ************** */
5 |
6 | const {
7 | bannerImageContainer,
8 | bannerImage,
9 | toolbox,
10 | } = getMainElements();
11 |
12 | /* ************** Info text inputs ************** */
13 |
14 | toolbox.querySelectorAll('.text-inputs input')
15 | .forEach(input => {
16 | input.addEventListener('click', () => input.select());
17 |
18 | input.addEventListener('keyup', (e) => {
19 | let titleInput = toolbox.querySelector('.text-inputs input#title-input');
20 | let subtitleInput = toolbox.querySelector('.text-inputs input#subtitle-input');
21 |
22 | updateBanner({
23 | title: titleInput.value,
24 | subtitle: subtitleInput.value
25 | });
26 | });
27 | })
28 |
29 | /* ************** Color selectors ************** */
30 |
31 | function setColorValues() {
32 | let bgColorSelector = toolbox.querySelector('.color-selectors-container input#main-bg-color-selector');
33 | let titleColorSelector = toolbox.querySelector('.color-selectors-container input#title-color-selector');
34 | let subtitleColorSelector = toolbox.querySelector('.color-selectors-container input#subtitle-color-selector');
35 |
36 | updateBanner({
37 | background: bgColorSelector.value,
38 | titleColor: titleColorSelector.value,
39 | subtitleColor: subtitleColorSelector.value,
40 | });
41 |
42 | let backgroundTabBgColorSelector = document.querySelector('.bg-color-selectors input#background-bg-color-selector');
43 | backgroundTabBgColorSelector.value = bgColorSelector.value;
44 | }
45 |
46 | toolbox.querySelectorAll('.color-selectors-container input')
47 | .forEach(input => {
48 | input.addEventListener('input', (e) => {
49 | setColorValues();
50 | });
51 | })
52 |
53 | /* ************** Size inputs ************** */
54 |
55 | function setSizeValues() {
56 | let widthInput = toolbox.querySelector('.size-inputs input#width-input');
57 | let heightInput = toolbox.querySelector('.size-inputs input#height-input');
58 |
59 | if (Number(widthInput.value) > bannerImageContainer.clientWidth) {
60 | bannerImage.style.zoom = bannerImageContainer.clientWidth / widthInput.value;
61 | } else {
62 | bannerImage.style.zoom = 1;
63 | }
64 | bannerImage.style.width = `${widthInput.value}px`;
65 | bannerImage.style.height = `${heightInput.value}px`;
66 | }
67 |
68 | function setPaddingValues() {
69 | let paddingInput = toolbox.querySelector('.size-inputs input#paddings-input');
70 |
71 | updateBanner({ padding: paddingInput.value });
72 | }
73 |
74 | toolbox.querySelectorAll('.size-inputs input')
75 | .forEach(input => {
76 | if (['width-input', 'height-input'].includes(input.id)) {
77 | input.addEventListener('click', () => input.select());
78 |
79 | input.addEventListener('keyup', (e) => {
80 | setSizeValues();
81 | });
82 | } else if (input.id = 'paddings-input') {
83 | input.addEventListener('input', (e) => {
84 | e.target.nextElementSibling.value = e.target.value
85 | setPaddingValues();
86 | });
87 | }
88 | })
89 |
90 | /* ************** Align buttons ************** */
91 |
92 | toolbox.querySelectorAll('.align-buttons button')
93 | .forEach(button => {
94 | button.addEventListener('click', (e) => {
95 | const element = e.target.tagName.toLowerCase() === 'img' ?
96 | e.target.parentNode :
97 | e.target;
98 | const alignValue = element.getAttribute('data-align-value');
99 |
100 | updateBanner({
101 | textAlign: alignValue
102 | });
103 |
104 | });
105 | })
106 |
107 | /* ************** Font Selectors ************** */
108 |
109 | toolbox.querySelectorAll('.font-selectors-container')
110 | .forEach(button => {
111 | button.addEventListener('change', (e) => {
112 | let titleFontSelect = toolbox.querySelector('.font-selectors-container #title-font-selector');
113 | let subtitleFontSelect = toolbox.querySelector('.font-selectors-container #subtitle-font-selector');
114 |
115 | updateBanner({
116 | titleFont: titleFontSelect.value,
117 | subtitleFont: subtitleFontSelect.value,
118 | });
119 | });
120 | })
121 |
122 | /* ************** Font Size inputs ************** */
123 |
124 | function setFontSizeValues() {
125 | let titleFontSizeInput = toolbox.querySelector('.font-size-inputs input#title-font-size-input');
126 | let subtitleFontSizeInput = toolbox.querySelector('.font-size-inputs input#subtitle-font-size-input');
127 |
128 | updateBanner({
129 | titleFontSize: titleFontSizeInput.value,
130 | subtitleFontSize: subtitleFontSizeInput.value,
131 | });
132 | }
133 |
134 | toolbox.querySelectorAll('.font-size-inputs input')
135 | .forEach(input => {
136 | input.addEventListener('input', (e) => {
137 | e.target.nextElementSibling.value = e.target.value
138 | setFontSizeValues();
139 | });
140 | })
141 |
142 | /* ************** ************** ************** */
143 |
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of any condition.
7 |
8 | We pledge to act and interact in ways that contribute to an open, welcoming, inclusive, and healthy community.
9 |
10 | ## Our Standards
11 |
12 | Examples of behavior that contributes to a positive environment for our
13 | community include:
14 |
15 | * Demonstrating empathy and kindness toward other people
16 | * Being respectful of differing opinions, viewpoints, and experiences
17 | * Giving and gracefully accepting constructive feedback
18 | * Accepting responsibility and apologizing to those affected by our mistakes,
19 | and learning from the experience
20 | * Focusing on what is best not just for us as individuals, but for the
21 | overall community
22 |
23 | Examples of unacceptable behavior include:
24 |
25 | * The use of sexualized language or imagery, and sexual attention or
26 | advances of any kind
27 | * Trolling, insulting or derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or email
30 | address, without their explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Enforcement Responsibilities
35 |
36 | Community leaders are responsible for clarifying and enforcing our standards of
37 | acceptable behavior and will take appropriate and fair corrective action in
38 | response to any behavior that they deem inappropriate, threatening, offensive,
39 | or harmful.
40 |
41 | Community leaders have the right and responsibility to remove, edit, or reject
42 | comments, commits, code, wiki edits, issues, and other contributions that are
43 | not aligned to this Code of Conduct, and will communicate reasons for moderation
44 | decisions when appropriate.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies within all community spaces, and also applies when
49 | an individual is officially representing the community in public spaces.
50 | Examples of representing our community include using an official e-mail address,
51 | posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event.
53 |
54 | ## Enforcement
55 |
56 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
57 | reported to the community leaders responsible for enforcement at
58 | levi.arista@gmail.com.
59 | All complaints will be reviewed and investigated promptly and fairly.
60 |
61 | All community leaders are obligated to respect the privacy and security of the
62 | reporter of any incident.
63 |
64 | ## Enforcement Guidelines
65 |
66 | Community leaders will follow these Community Impact Guidelines in determining
67 | the consequences for any action they deem in violation of this Code of Conduct:
68 |
69 | ### 1. Correction
70 |
71 | **Community Impact**: Use of inappropriate language or other behavior deemed
72 | unprofessional or unwelcome in the community.
73 |
74 | **Consequence**: A private, written warning from community leaders, providing
75 | clarity around the nature of the violation and an explanation of why the
76 | behavior was inappropriate. A public apology may be requested.
77 |
78 | ### 2. Warning
79 |
80 | **Community Impact**: A violation through a single incident or series
81 | of actions.
82 |
83 | **Consequence**: A warning with consequences for continued behavior. No
84 | interaction with the people involved, including unsolicited interaction with
85 | those enforcing the Code of Conduct, for a specified period of time. This
86 | includes avoiding interactions in community spaces as well as external channels
87 | like social media. Violating these terms may lead to a temporary or
88 | permanent ban.
89 |
90 | ### 3. Temporary Ban
91 |
92 | **Community Impact**: A serious violation of community standards, including
93 | sustained inappropriate behavior.
94 |
95 | **Consequence**: A temporary ban from any sort of interaction or public
96 | communication with the community for a specified period of time. No public or
97 | private interaction with the people involved, including unsolicited interaction
98 | with those enforcing the Code of Conduct, is allowed during this period.
99 | Violating these terms may lead to a permanent ban.
100 |
101 | ### 4. Permanent Ban
102 |
103 | **Community Impact**: Demonstrating a pattern of violation of community
104 | standards, including sustained inappropriate behavior, harassment of an
105 | individual, or aggression toward or disparagement of classes of individuals.
106 |
107 | **Consequence**: A permanent ban from any sort of public interaction within
108 | the community.
109 |
110 | ## Attribution
111 |
112 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
113 | version 2.0, available at
114 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
115 |
116 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
117 | enforcement ladder](https://github.com/mozilla/diversity).
118 |
119 | [homepage]: https://www.contributor-covenant.org
120 |
121 | For answers to common questions about this code of conduct, see the FAQ at
122 | https://www.contributor-covenant.org/faq. Translations are available at
123 | https://www.contributor-covenant.org/translations.
124 |
--------------------------------------------------------------------------------
/partials/head.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Github Profile Header Generator
6 |
7 |
8 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
28 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
41 |
43 |
45 |
46 |
48 |
49 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
66 |
67 |
68 |
93 |
--------------------------------------------------------------------------------
/public/images/patterns/endless-constellation-thumbnail.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/partials/toolbox/decorations.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/styles/toolbox-main.scss:
--------------------------------------------------------------------------------
1 | .toolbox-container {
2 | .result-box {
3 | // height: 300px;
4 | padding: 2rem 2rem 0.5rem 2rem;
5 | background: var(--github-dark-mode-color);
6 | transition: 0.5s ease;
7 | user-select: none;
8 | position: relative;
9 | z-index: 20;
10 | border-bottom: solid 1px #373737;
11 |
12 | &.light-mode {
13 | background: var(--github-light-mode-color);
14 |
15 | .dark-mode-button,
16 | .randomize-button,
17 | .reset-button {
18 | color: black !important;
19 |
20 | &:hover {
21 | // box-shadow: 0px 0px 5px 2px rgba(255, 255, 255, 0.25);
22 | text-shadow: 0px 0px 10px #929292 !important;
23 | }
24 | }
25 | }
26 |
27 | .header-image-container {
28 | width: 100%;
29 | flex-grow: 1;
30 | // max-width: calc(1280px - 296px - 24px);
31 | max-width: calc(850px);
32 | margin: auto;
33 | width: 100%;
34 | filter: drop-shadow(0px 0px 5px rgba(125, 125, 125, 0.5));
35 | }
36 |
37 | #github-header-image {
38 | width: 100%;
39 | height: 230px;
40 | padding: 25px;
41 | position: relative;
42 | display: flex;
43 | align-items: flex-start;
44 | justify-content: center;
45 | flex-direction: column;
46 | background-color: #62518d;
47 | color: white;
48 | border-radius: 7px;
49 | margin: 0 auto;
50 | border: none;
51 | overflow: hidden;
52 | background-size: 200px;
53 | transition: 0.25s ease;
54 |
55 | .title,
56 | .subtitle {
57 | transition: 0.25s ease;
58 | white-space: nowrap;
59 | }
60 |
61 | // Ensure Electrolize font loads properly
62 | .title[style*="Electrolize"],
63 | .subtitle[style*="Electrolize"] {
64 | font-family: "Electrolize", monospace !important;
65 | }
66 |
67 | img {
68 | transition: 0.15s;
69 | }
70 | }
71 |
72 | .options-container {
73 | max-width: calc(850px);
74 | margin: auto;
75 | user-select: none;
76 | display: flex;
77 | align-items: center;
78 | gap: 35px;
79 | justify-content: space-between;
80 | // flex-wrap: wrap;
81 | padding: 1rem 0 0.5rem 0;
82 | overflow: auto;
83 |
84 | >div:first-child {
85 | display: flex;
86 | gap: 2rem;
87 | }
88 |
89 | .dark-mode-button,
90 | .randomize-button,
91 | .download-button,
92 | .reset-button {
93 | background-color: transparent;
94 | display: flex;
95 | gap: 7px;
96 | justify-content: center;
97 | align-items: center;
98 | width: fit-content;
99 | height: 35px;
100 | // border: 1px solid #ffffff;
101 | // border-radius: var(--button-border-radius);
102 | color: var(--text-color);
103 | // text-transform: uppercase;
104 | text-align: center;
105 | font-weight: 600;
106 | white-space: nowrap;
107 | transition: all 0.25s ease-in-out;
108 | cursor: pointer;
109 |
110 | img {
111 | transition: all ease 500ms;
112 | }
113 |
114 | &:hover {
115 | // box-shadow: 0px 0px 5px 2px rgba(255, 255, 255, 0.25);
116 | text-shadow: 0px 0px 10px rgb(255, 255, 255);
117 |
118 | img {
119 | transform: scale(1.2);
120 | }
121 | }
122 | }
123 |
124 | .download-button,
125 | .display-button,
126 | .miniature-button {
127 | background-color: #2D8655 !important;
128 | // border: 1px solid #ffffff;
129 | border-radius: var(--button-border-radius);
130 | padding: 5px 15px;
131 | }
132 | }
133 | }
134 |
135 | .toolbox-tools {
136 | height: calc(100vh - 230px - 3rem - 35px - 1rem);
137 | overflow: auto;
138 | padding: 1rem 1rem 4rem 1rem;
139 | }
140 |
141 | .toolbox {
142 | box-sizing: border-box;
143 |
144 | >div {
145 | display: flex;
146 | align-items: center;
147 | justify-content: center;
148 | flex-wrap: wrap;
149 |
150 | &:not(:last-child) {
151 | margin-bottom: 15px;
152 | }
153 | }
154 |
155 | .text-inputs {
156 | justify-content: space-between;
157 |
158 | input {
159 | text-align: center;
160 | width: calc(50% - 7.5px);
161 | }
162 | }
163 |
164 | .color-selectors-container {
165 | div {
166 | display: flex;
167 | align-items: center;
168 |
169 | &:not(:last-child) {
170 | margin-right: 15px;
171 | }
172 |
173 | input {
174 | margin-left: 5px;
175 | cursor: pointer;
176 | padding: 0;
177 | }
178 | }
179 | }
180 |
181 | .size-inputs {
182 | >div {
183 | &:not(:last-child) {
184 | margin-right: 15px;
185 | }
186 |
187 | input {
188 | width: 70px;
189 | margin-left: 5px;
190 | }
191 | }
192 |
193 | .paddings-input {
194 | width: 100px;
195 | }
196 | }
197 |
198 | .align-buttons {
199 | button {
200 | margin-left: 5px;
201 | }
202 | }
203 |
204 | .font-selectors-container {
205 | column-gap: 1rem;
206 | row-gap: 0.5rem;
207 |
208 | select {
209 | cursor: pointer;
210 | margin-left: 5px;
211 |
212 | option {
213 | color: black;
214 | }
215 | }
216 | }
217 |
218 | .font-size-inputs {
219 | display: flex;
220 |
221 | div {
222 | display: flex;
223 | align-items: flex-start;
224 |
225 | &:not(:last-child) {
226 | margin-right: 15px;
227 | }
228 |
229 | input {
230 | cursor: pointer;
231 | }
232 | }
233 | }
234 | }
235 | }
236 |
237 | @media (max-width: 768px) {
238 | .toolbox-container {
239 | input {
240 | margin-bottom: 5px;
241 | }
242 |
243 | .result-box {
244 | padding: 2rem 1rem 0.5rem 1rem;
245 |
246 | #github-header-image {
247 | height: 230px;
248 | }
249 |
250 | .options-container {
251 | gap: 10px;
252 |
253 | >div:first-child {
254 | gap: 10px;
255 | }
256 | }
257 | }
258 |
259 | .toolbox-tools {
260 | height: calc(100vh - 230px - 3rem - 35px - 2rem - 2rem);
261 | min-height: 300px;
262 | }
263 |
264 | .toolbox {
265 | .text-inputs {
266 | input {
267 | width: 100%;
268 | // &:not(:last-child) {
269 | // margin-bottom: 10px;
270 | // }
271 | }
272 | }
273 |
274 | .font-size-inputs {
275 | input {
276 | &:not(:last-child) {
277 | margin-bottom: 15px;
278 | }
279 | }
280 | }
281 | }
282 | }
283 | }
284 |
285 | @media (max-width: 410px) {
286 | .toolbox-container {
287 | .result-box {
288 | .options-container {
289 | flex-wrap: wrap;
290 | gap: 10px;
291 | justify-content: center;
292 |
293 | >div:first-child {
294 | gap: 10px;
295 | }
296 | }
297 | }
298 | }
299 |
300 | }
--------------------------------------------------------------------------------
/js/main.js:
--------------------------------------------------------------------------------
1 | import { snapdom } from '@zumer/snapdom';
2 | import { getMainElements } from './helpers/elements';
3 | import { isDevOptions, isLocalDevelopment } from './helpers/helpers';
4 | import { getAllPresets, getRandomPreset, setPreset } from './presets';
5 |
6 | /* ************** Elements ************** */
7 |
8 | const {
9 | bannerImageContainer,
10 | bannerImage,
11 | toolbox,
12 | } = getMainElements();
13 |
14 | /* ************** Options ************** */
15 |
16 | const initialTheme = {
17 | textAlign: "center",
18 | ...getAllPresets()[15],
19 | background: "#62518d",
20 | borderSize: 5,
21 | decoration: 'dino-border.png',
22 | subtitleColor: "#FFF2B3",
23 | titleFont: 'Red Hat Display',
24 | subtitleFont: 'Kalam'
25 | }
26 |
27 | // Init
28 | toolbox.querySelector('.size-inputs input#width-input').value = bannerImageContainer.clientWidth;
29 | document.addEventListener("DOMContentLoaded", (event) => {
30 | const theme = localStorage.getItem('theme');
31 | if (theme)
32 | setPreset(JSON.parse(theme), true);
33 | else
34 | setPreset(initialTheme);
35 | });
36 |
37 | // Demo reset after ended
38 | document.querySelector('.how-to-section video.demo').onended = (e) => e.target.currentTime = 0;
39 |
40 | // Decoration
41 |
42 | const imageDecorationContainer = document.querySelector('.img-decoration-container');
43 | const imgDecorationElement = document.createElement('img');
44 | imgDecorationElement.className = 'img-decoration';
45 | imgDecorationElement.style.position = 'absolute';
46 | imgDecorationElement.style.bottom = 'calc(50%)';
47 | imgDecorationElement.style.transform = 'translateY(50%)'
48 | imgDecorationElement.style.left = 'auto';
49 | imgDecorationElement.style.right = '25px';
50 | imgDecorationElement.style.width = '0px';
51 | imgDecorationElement.alt = 'Header image decoration'
52 | imageDecorationContainer.appendChild(imgDecorationElement)
53 |
54 | /* ************** Header image options ************** */
55 |
56 | // Download button
57 | document.querySelector('.download-button')
58 | .addEventListener('click', async () => {
59 | document.querySelector('.download-button img').src = './images/icons/loading.gif'
60 |
61 | try {
62 | await snapdom.download(
63 | bannerImage,
64 | {
65 | embedFonts: true,
66 | format: 'png',
67 | filename: 'github-header-banner',
68 | scale: 2
69 | });
70 | document.querySelector('.download-button img').src = './images/icons/download.svg'
71 | } catch (error) {
72 | console.error('Image capture or download failed:', error);
73 | }
74 | })
75 |
76 | // For local development
77 | document.addEventListener("DOMContentLoaded", (event) => {
78 | const displayButton = document.querySelector('.display-button');
79 | const miniatureButton = document.querySelector('.miniature-button');
80 | const testFontsTab = document.querySelector('.tablinks[data-name="test-fonts-section"]');
81 |
82 | if (isLocalDevelopment && isDevOptions == 1) {
83 | const el = document.querySelector('#github-header-image');
84 | const container = document.querySelector('.header-image-container')
85 |
86 | if (displayButton) {
87 | displayButton.style.display = "block";
88 |
89 | displayButton.addEventListener('click', async () => {
90 | const png = await snapdom.toPng(el, { embedFonts: true });
91 |
92 | const prevImage = container.children[1];
93 | if (prevImage) container.removeChild(prevImage);
94 |
95 | container.appendChild(png);
96 | document.querySelector('.toolbox-container .toolbox-tools').style.height = 'calc(100vh - 230px - 3rem - 35px - 1rem - 230px)'
97 | })
98 | }
99 | if (miniatureButton) {
100 | miniatureButton.style.display = "block";
101 | // console.log('Running on localhost! display appending image option ...');
102 |
103 | miniatureButton.addEventListener('click', async () => {
104 | const png = await snapdom.toPng(el, { embedFonts: true, scale: 0.25 });
105 |
106 | const prevImage = container.children[1];
107 | if (prevImage) container.removeChild(prevImage);
108 |
109 | container.appendChild(png);
110 | document.querySelector('.toolbox-container .toolbox-tools').style.height = 'calc(100vh - 230px - 3rem - 35px - 1rem - 46px)'
111 | })
112 | }
113 | if (testFontsTab) {
114 | // testFontsTab.style.display = "block"
115 | }
116 | }
117 | });
118 |
119 | // Toogle Dark Mode button
120 | document.querySelector('.dark-mode-button')
121 | .addEventListener('click', (e) => {
122 | let resultBox = document.querySelector('.result-box');
123 | const toogleDarkModeButton = document.querySelector('.dark-mode-button');
124 | const toogleRandomizeButton = document.querySelector('.randomize-button');
125 | const toogleResetButton = document.querySelector('.reset-button');
126 | const toogleDownloadButton = document.querySelector('.download-button');
127 |
128 | const size = 20;
129 |
130 | resultBox.classList.toggle('light-mode');
131 | if (resultBox.className.includes('light')) {
132 | toogleDarkModeButton.innerHTML = ` Light`
133 | toogleRandomizeButton.innerHTML = ` Random`
134 | toogleResetButton.innerHTML = ` Reset`
135 | toogleDownloadButton.innerHTML = ` Download`
136 | } else {
137 | toogleDarkModeButton.innerHTML = ` Dark`
138 | toogleRandomizeButton.innerHTML = ` Random`
139 | toogleResetButton.innerHTML = ` Reset`
140 | toogleDownloadButton.innerHTML = ` Download`
141 | }
142 | });
143 |
144 | // Randomize
145 | document.querySelector('.randomize-button')
146 | .addEventListener('click', (e) => {
147 | const theme = getRandomPreset();
148 | setPreset(theme);
149 | });
150 |
151 | document.querySelector('.reset-button')
152 | .addEventListener('click', (e) => {
153 | const darkMode = localStorage.getItem('darkMode');
154 | localStorage.clear();
155 | localStorage.setItem('darkMode', darkMode);
156 | setPreset(initialTheme);
157 | });
158 |
159 | /* ************** Tabs ************** */
160 |
161 | function openTab(e, name) {
162 | let i, tabcontent, tablinks;
163 |
164 | tabcontent = document.getElementsByClassName("tabcontent");
165 | for (i = 0; i < tabcontent.length; i++) {
166 | tabcontent[i].style.display = "none";
167 | }
168 |
169 | tablinks = document.getElementsByClassName("tablinks");
170 | for (i = 0; i < tablinks.length; i++) {
171 | tablinks[i].className = tablinks[i].className.replace(" active", "");
172 | }
173 |
174 | document.getElementById(name).style.display = "block";
175 | e.currentTarget.className += " active";
176 | }
177 |
178 | document.querySelectorAll('.tab .tablinks')
179 | .forEach(button => {
180 | button.addEventListener('click', (e) => {
181 | const name = e.target.getAttribute('data-name');
182 | localStorage.setItem('openTab', name)
183 | openTab(e, name);
184 | });
185 | })
186 |
187 | // Saved tab
188 | document.addEventListener("DOMContentLoaded", (event) => {
189 | const openTab = localStorage.getItem('openTab');
190 | if (openTab) {
191 | document.querySelector(`[data-name="${openTab}"]`).click();
192 | } else {
193 | document.getElementById("defaultOpenTag").click();
194 | }
195 | });
196 |
197 | /* ************** Dark Mode ************** */
198 |
199 | function setLightMode() {
200 | localStorage.setItem('darkMode', 0);
201 | document.documentElement.setAttribute("data-theme", "light");
202 | document.querySelector('#light-mode-btn').classList.add('selected');
203 | document.querySelector('#dark-mode-btn').classList.remove('selected');
204 | }
205 | function setDarkMode() {
206 | localStorage.setItem('darkMode', 1);
207 | document.documentElement.setAttribute("data-theme", "dark");
208 | document.querySelector('#light-mode-btn').classList.remove('selected');
209 | document.querySelector('#dark-mode-btn').classList.add('selected');
210 | }
211 |
212 | document.addEventListener("DOMContentLoaded", (event) => {
213 | const localDarkMode = localStorage.getItem('darkMode');
214 | if (localDarkMode && localDarkMode == 1){
215 | document.querySelector('#dark-mode-btn').classList.add('selected');
216 | } else {
217 | document.querySelector('#light-mode-btn').classList.add('selected');
218 | }
219 | document.querySelector('#light-mode-btn').onclick = setLightMode;
220 | document.querySelector('#dark-mode-btn').onclick = setDarkMode;
221 | });
222 |
223 | /* ************** ************** ************** */
224 |
--------------------------------------------------------------------------------