仿照linktree做的个人主页

你可以访问这里查看: https://hoytzhang.com

pc-hoytzhang.webp

实现的效果:

  • 随机显示背景图像
  • 从背景图像提取主要颜色设置为按钮的颜色
  • 适配移动端
  • 点击项目按钮展开/收缩项目

下面是代码,当然还有一个去除JS的代码,一起附在下面,可能需要你手动设置按钮颜色

附带JS的版本

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>My page</title>
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
        <style>
            @font-face {
                font-family: 'Opposans';
                src: url('opposans.woff2') format('woff2');
                font-weight: normal;
                font-style: normal;
            }
            html, body {
                height: 100%;
                margin: 0;
                overflow: hidden;
            }
            #buttonContainer hr {
                border: none;
                border-top: 2px dashed #007bff;
                margin: 10px 10px;
            }
            body {
                font-family: 'Opposans', Arial, sans-serif;
                display: flex;
                flex-direction: column;
                justify-content: center;
                align-items: center;
                background-size: cover;
                background-position: center;
                background-repeat: no-repeat;
                transition: background 0.5s;
            }
            .container {
                text-align: center;
                backdrop-filter: blur(20px);
                border-radius: 20px;
                padding: 30px;
                width: 90%;
                max-width: 400px;
                box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);
            }
            h1 {
                color: white;
                padding: 0;
                margin: 0;
            }
            .link {
                display: flex;
                align-items: center;
                justify-content: flex-start;
                color: white;
                padding: 15px;
                margin: 10px 0;
                text-decoration: none;
                border-radius: 30px;
                transition: background 0.3s;
            }
            .link i {
                padding: 0px;
                width: 1.2rem;
                height: 1.2rem;
                font-size: 1.2rem;
                margin-right: 10px;
            }
            .social-media {
                margin: 20px;
                display: flex;
                justify-content: center;
            }
            .social-icon {
                background-color: rgba(255, 255, 255, 0.2);
                color: white;
                border-radius: 50%;
                width: 2.5rem;
                height: 2.5rem;
                display: flex;
                justify-content: center;
                align-items: center;
                margin: 0 10px;
                font-size: 1.2rem;
                transition: background 0.3s;
                text-decoration: none;
            }
            .social-icon:hover {
                background-color: rgba(255, 255, 255, 0.4);
            }
            footer {
                margin-top: 20px;
                font-size: 0.8em;
                color: white;
            }

            @media (max-width: 600px) {
                .container {
                    backdrop-filter: none;
                    box-shadow: none;
                }
            }
        </style>
    </head>
    <body>

    <div class="container">
        <h1>Name here</h1>
        <div class="social-media">
            <a class="social-icon" href="https://github.com/username" target="_blank"><i class="fa-brands fa-github"></i></a>
            <a class="social-icon" href="https://x.com/username" target="_blank"><i class="fa-brands fa-x-twitter"></i></a>
            <a class="social-icon" href="https://instagram.com/username" target="_blank"><i class="fa-brands fa-instagram"></i></a>
            <a class="social-icon" href="https://t.me/username" target="_blank"><i class="fa-brands fa-telegram"></i></a>
        </div>
        <a class="link" href="https://myblog.com"><i class="fas fa-scroll"></i>Blog</a>
        <a class="link" href="mailto:m@username.com"><i class="fas fa-envelope"></i>Hire me</a>
        <a class="link" href="/" id="dynamicButtonLink"><i class="fa-solid fa-file-code"></i>Projects</a>
        <div id="buttonContainer" style="display: none;">
            <hr>
            <a class="link" href="https://username.site"><i class="fas fa-link"></i>Projects name</a>
            <a class="link" href="https://github.com/username/Projects1/"><i class="fab fa-github"></i>Projects1</a>
            <a class="link" href="https://github.com/username/Projects2/"><i class="fab fa-github"></i>Projects2</a>
        </div>
    </div>

    <footer>
        <p>© 2024 Name</p>
    </footer>

    <canvas id="myCanvas" style="display:none;"></canvas>

    <script>
        const backgrounds = [
            '1.webp',
            '2.webp',
            '3.webp',
            '4.webp',
            '5.webp',
            '6.webp',
            '7.webp',
            '8.webp',
            '9.webp',
            '10.webp',
            '11.webp',
            '12.webp',
            '13.webp',
            '14.webp',
            '15.webp',
            '16.webp',
            '17.webp',
            '18.webp'
        ];

        const randomIndex = Math.floor(Math.random() * backgrounds.length);
        const backgroundImage = backgrounds[randomIndex];
        document.body.style.backgroundImage = `url(${backgroundImage})`;

        const canvas = document.getElementById('myCanvas');

        function getImageColor(canvas, img) {
            canvas.width = img.width;
            canvas.height = img.height;

            const context = canvas.getContext("2d");
            context.drawImage(img, 0, 0, canvas.width, canvas.height);

            const data = context.getImageData(0, 0, img.width, img.height).data;
            let r = 0, g = 0, b = 0;

            const pixelCount = img.width * img.height;
            for (let i = 0; i < data.length; i += 4) {
                r += data[i];     // R
                g += data[i + 1]; // G
                b += data[i + 2]; // B
            }
            r = Math.round(r / pixelCount);
            g = Math.round(g / pixelCount);
            b = Math.round(b / pixelCount);

            return `rgb(${r}, ${g}, ${b})`;
        }

        function lightenColor(rgb, percent) {
            const rgbValues = rgb.match(/\d+/g).map(Number);
            const r = Math.min(255, Math.round(rgbValues[0] + (255 - rgbValues[0]) * percent));
            const g = Math.min(255, Math.round(rgbValues[1] + (255 - rgbValues[1]) * percent));
            const b = Math.min(255, Math.round(rgbValues[2] + (255 - rgbValues[2]) * percent));
            return `rgb(${r}, ${g}, ${b})`;
        }

        const img = new Image();
        img.crossOrigin = 'anonymous';
        img.src = backgroundImage;

        img.onload = function() {
            const rgbColor = getImageColor(canvas, img);

            const links = document.querySelectorAll('.link');
            links.forEach(link => {
                link.style.backgroundColor = rgbColor;
                link.style.color = 'white';

                const hoverColor = lightenColor(rgbColor, 0.2);
                link.addEventListener('mouseover', () => {
                    link.style.backgroundColor = hoverColor;
                });
                link.addEventListener('mouseout', () => {
                    link.style.backgroundColor = rgbColor;
                });
            });
            const hr = document.querySelector('#buttonContainer hr');
            hr.style.borderTop = `2px dashed ${rgbColor}`;
            const socialIcons = document.querySelectorAll('.social-icon');
            socialIcons.forEach(icon => {
                icon.style.backgroundColor = rgbColor;

                const hoverColor = lightenColor(rgbColor, 0.2);
                icon.addEventListener('mouseover', () => {
                    icon.style.backgroundColor = hoverColor;
                });
                icon.addEventListener('mouseout', () => {
                    icon.style.backgroundColor = rgbColor;
                });
            });

            const footer = document.querySelector('footer');
            footer.style.color = rgbColor;
        };
        document.getElementById('dynamicButtonLink').addEventListener('click', function(event) {
            event.preventDefault();

            const buttonContainer = document.getElementById('buttonContainer');

            if (buttonContainer.style.display === 'none') {
                buttonContainer.style.display = 'block';
            } else {
                buttonContainer.style.display = 'none';
            }
        });
    </script>

    </body>
    </html>

去除JS的版本

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>My page</title>
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css">
        <style>
            @font-face {
                font-family: 'Opposans';
                src: url('opposans.woff2') format('woff2');
                font-weight: normal;
                font-style: normal;
            }
            html, body {
                height: 100%;
                margin: 0;
                overflow: hidden;
            }
            #buttonContainer hr {
                border: none;
                border-top: 2px dashed #007bff;
                margin: 10px 10px;
            }
            body {
                font-family: 'Opposans', Arial, sans-serif;
                display: flex;
                flex-direction: column;
                justify-content: center;
                align-items: center;
                background-size: cover;
                background-position: center;

                background-repeat: no-repeat;
                transition: background 0.5s;
            }
            .container {
                text-align: center;
                backdrop-filter: blur(20px);
                border-radius: 20px;
                padding: 30px;
                width: 90%;
                max-width: 400px;
                box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);
            }
            h1 {
                color: white;
                padding: 0;
                margin: 0;
            }
            .link {
                display: flex;
                align-items: center;
                justify-content: flex-start;
                color: white;
                padding: 15px;
                margin: 10px 0;
                text-decoration: none;
                border-radius: 30px;
                transition: background 0.3s;
            }
            .link i {
                padding: 0px;
                width: 1.2rem;
                height: 1.2rem;
                font-size: 1.2rem;
                margin-right: 10px;
            }
            .social-media {
                margin: 20px;
                display: flex;
                justify-content: center;
            }
            .social-icon {
                background-color: rgba(255, 255, 255, 0.2);
                color: white;
                border-radius: 50%;
                width: 2.5rem;
                height: 2.5rem;
                display: flex;
                justify-content: center;
                align-items: center;
                margin: 0 10px;
                font-size: 1.2rem;
                transition: background 0.3s;
                text-decoration: none;
            }
            .social-icon:hover {
                background-color: rgba(255, 255, 255, 0.4);
            }
            footer {
                margin-top: 20px;
                font-size: 0.8em;
                color: white;
            }

            @media (max-width: 600px) {
                .container {
                    backdrop-filter: none;
                    box-shadow: none;
                }
            }
        </style>
    </head>
    <body>

    <div class="container">
        <h1>Name here</h1>
        <div class="social-media">
            <a class="social-icon" href="https://github.com/username" target="_blank"><i class="fa-brands fa-github"></i></a>
            <a class="social-icon" href="https://x.com/username" target="_blank"><i class="fa-brands fa-x-twitter"></i></a>
            <a class="social-icon" href="https://instagram.com/username" target="_blank"><i class="fa-brands fa-instagram"></i></a>
            <a class="social-icon" href="https://t.me/username" target="_blank"><i class="fa-brands fa-telegram"></i></a>
        </div>
        <a class="link" href="https://myblog.com"><i class="fas fa-scroll"></i>Blog</a>
        <a class="link" href="mailto:m@username.com"><i class="fas fa-envelope"></i>Hire me</a>
        <a class="link" href="/" id="dynamicButtonLink"><i class="fa-solid fa-file-code"></i>Projects</a>
        <hr>
        <a class="link" href="https://username.site"><i class="fas fa-link"></i>Projects name</a>
        <a class="link" href="https://github.com/username/Projects1/"><i class="fab fa-github"></i>Projects1</a>
        <a class="link" href="https://github.com/username/Projects2/"><i class="fab fa-github"></i>Projects2</a>
    </div>

    <footer>
        <p>© 2024 Name</p>
    </footer>

    </body>
    </html>

## 附加随机图像
> 如果你想要一个每次打开都会展示不一样的背景图像的页面,你可以使用下面的代码。如果你不想使用代码里的随机图像方案,你可以查看我的另一篇文章,里面有其他可选择的随机图像api:https://banzhuanriji.com/frontend/random-image.html

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Name</title>
        <link rel="stylesheet" href="https://s4.zstatic.net/ajax/libs/font-awesome/6.7.2/css/all.min.css">
        <style>
            @font-face {
                font-family: 'Opposans';
                src: url('opposans.woff2') format('woff2');
                font-weight: normal;
                font-style: normal;
            }
            html, body {
                height: 100%;
                margin: 0;
                overflow: hidden;
            }
            #buttonContainer hr {
                border: none;
                border-top: 2px dashed #007bff;
                margin: 10px 10px;
            }
            body {
                font-family: 'Opposans', Arial, sans-serif;
                display: flex;
                flex-direction: column;
                justify-content: center;
                align-items: center;
                background-size: cover;
                background-position: center;
                background-repeat: no-repeat;
                transition: background 0.5s;
            }
            .container {
                text-align: center;
                backdrop-filter: blur(20px);
                border-radius: 20px;
                padding: 30px;
                width: 90%;
                max-width: 400px;
                box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);
            }
            h1 {
                color: white;
                padding: 0;
                margin: 0;
            }
            .link {
                display: flex;
                align-items: center;
                justify-content: flex-start;
                color: white;
                padding: 15px;
                margin: 10px 0;
                text-decoration: none;
                border-radius: 30px;
                transition: background 0.3s;
            }
            .link i {
                padding: 0px;
                width: 1.2rem;
                height: 1.2rem;
                font-size: 1.2rem;
                margin-right: 10px;
            }
            .social-media {
                margin: 20px;
                display: flex;
                justify-content: center;
            }
            .social-icon {
                background-color: rgba(255, 255, 255, 0.2);
                color: white;
                border-radius: 50%;
                width: 3rem;
                height: 3rem;
                display: flex;
                justify-content: center;
                align-items: center;
                margin: 0 10px;
                font-size: 1.2rem;
                transition: background 0.3s;
                text-decoration: none;
            }
            .social-icon:hover {
                background-color: rgba(255, 255, 255, 0.4);
            }
            footer {
                margin-top: 20px;
                font-size: 0.8em;
                color: white;
            }

            @media (max-width: 600px) {
                .container {
                    backdrop-filter: none;
                    box-shadow: none;
                }
            }
        </style>
    </head>
    <body>

    <div class="container">
        <h1>Name</h1>
        <div class="social-media">
            <a class="social-icon" href="https://github.com/username" target="_blank"><i class="fa-brands fa-github"></i></a>
            <a class="social-icon" href="https://x.com/username" target="_blank"><i class="fa-brands fa-x-twitter"></i></a>
            <a class="social-icon" href="https://instagram.com/username" target="_blank"><i class="fa-brands fa-instagram"></i></a>
            <a class="social-icon" href="https://t.me/username" target="_blank"><i class="fa-brands fa-telegram"></i></a>
        </div>
        <a class="link" href="https://name.com"><i class="fas fa-scroll"></i>Blog</a>
        <a class="link" href="/"><i class="fas fa-envelope"></i>Hire me</a>
        <a class="link" href="/" id="dynamicButtonLink"><i class="fa-solid fa-file-code"></i>Projects</a>
        <div id="buttonContainer" style="display: none;">
            <hr>
            <a class="link" href="https://github.com/username/Project1/"><i class="fab fa-github"></i>Project1</a>
            <a class="link" href="https://github.com/username/Project2/"><i class="fab fa-github"></i>Project2</a>
        </div>
    </div>

    <footer>
        <p>© 2024 username</p>
    </footer>

    <canvas id="myCanvas" style="display:none;"></canvas>

    <script>
        const imageUrl = 'https://picsum.photos/1920/1080.webp';

        // Fetch the image to get a consistent URL
        fetch(imageUrl)
            .then(response => {
                if (response.ok) {
                    const img = new Image();
                    img.crossOrigin = 'anonymous';
                    img.src = response.url; // Use the resolved URL
                    img.onload = function() {
                        document.body.style.backgroundImage = `url(${response.url})`;
                        const canvas = document.getElementById('myCanvas');
                        const rgbColor = getImageColor(canvas, img);

                        const links = document.querySelectorAll('.link');
                        links.forEach(link => {
                            link.style.backgroundColor = rgbColor;
                            link.style.color = 'white';

                            const hoverColor = lightenColor(rgbColor, 0.2);
                            link.addEventListener('mouseover', () => {
                                link.style.backgroundColor = hoverColor;
                            });
                            link.addEventListener('mouseout', () => {
                                link.style.backgroundColor = rgbColor;
                            });
                        });

                        const hr = document.querySelector('#buttonContainer hr');
                        hr.style.borderTop = `2px dashed ${rgbColor}`;
                        const socialIcons = document.querySelectorAll('.social-icon');
                        socialIcons.forEach(icon => {
                            icon.style.backgroundColor = rgbColor;

                            const hoverColor = lightenColor(rgbColor, 0.2);
                            icon.addEventListener('mouseover', () => {
                                icon.style.backgroundColor = hoverColor;
                            });
                            icon.addEventListener('mouseout', () => {
                                icon.style.backgroundColor = rgbColor;
                            });
                        });

                        const footer = document.querySelector('footer');
                        footer.style.color = rgbColor;
                    };
                } else {
                    console.error('Failed to fetch image:', response.status);
                }
            })
            .catch(error => console.error('Error fetching the image:', error));

        function getImageColor(canvas, img) {
            canvas.width = img.width;
            canvas.height = img.height;

            const context = canvas.getContext("2d");
            context.drawImage(img, 0, 0, canvas.width, canvas.height);

            const data = context.getImageData(0, 0, img.width, img.height).data;
            let r = 0, g = 0, b = 0;

            const pixelCount = img.width * img.height;
            for (let i = 0; i < data.length; i += 4) {
                r += data[i];     // R
                g += data[i + 1]; // G
                b += data[i + 2]; // B
            }
            r = Math.round(r / pixelCount);
            g = Math.round(g / pixelCount);
            b = Math.round(b / pixelCount);

            return `rgb(${r}, ${g}, ${b})`;
        }

        function lightenColor(rgb, percent) {
            const rgbValues = rgb.match(/\d+/g).map(Number);
            const r = Math.min(255, Math.round(rgbValues[0] + (255 - rgbValues[0]) * percent));
            const g = Math.min(255, Math.round(rgbValues[1] + (255 - rgbValues[1]) * percent));
            const b = Math.min(255, Math.round(rgbValues[2] + (255 - rgbValues[2]) * percent));
            return `rgb(${r}, ${g}, ${b})`;
        }

        document.getElementById('dynamicButtonLink').addEventListener('click', function(event) {
            event.preventDefault();

            const buttonContainer = document.getElementById('buttonContainer');

            if (buttonContainer.style.display === 'none') {
                buttonContainer.style.display = 'block';
            } else {
                buttonContainer.style.display = 'none';
            }
        });
    </script>

    </body>
    </html>