pixi.js 的头像制作功能【函数】

发布时间 2023-09-10 17:49:41作者: 半遮
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/pixi.js@7.x/dist/pixi.min.js"></script>
    <title>pixi draw avatar</title>
</head>

<body>

    <div class="pixiCantainer" id="pixiCantainer"> </div>
    <!-- js -->
    <script>
        console.error('【本例子仅供参考,头像图片的生成应先load完之后再画,否则头像可能会变形】')

        /*
        参考资料:
        1: 画图形 : https://juejin.cn/post/7205802450573377596 ;
        
         */

        //  设置图片的裁剪位置 
        function shotAvatarWH(width, height, set_w, set_h) {
            let d = Math.abs((width - height))
            let d_position = d / 2;
            let x, y, w, h;
            if (width > height) {
                x = d_position, y = 0, w = height, h = height
            } else {
                x = 0, y = d_position, w = width, h = width
            }
            if (set_w) w = set_w
            if (set_h) h = set_h
            let obj = { x, y, w, h }
            return obj
        }


        // 制作头像的函数
        function setPicScale(pic) {
            pic.width = parseInt(pic.width);
            pic.height = Number(pic.height);
            pic.sprite_w = Number(pic.sprite_w);
            pic.sprite_h = Number(pic.sprite_h);
            let obj = { w: 0, h: 0, x: 0, y: 0 };
            let ratio_sprite = pic.sprite_w / pic.sprite_h
            let ratio_img = pic.width / pic.height
            let ratio = ratio_sprite - ratio_img

            if (pic.objectFit == 'contain') {

            } else {
                // cover
                if (pic.width == pic.height) {
                    console.warn('a类--------');
                    if (pic.sprite_w == pic.sprite_h) {
                        console.warn('a类--1------');
                        obj.w = pic.width;
                        obj.h = pic.height;
                    } else if (ratio > 0) {
                        obj.h = pic.height;
                        obj.w = pic.height * ratio_sprite;
                        console.warn('a类--2------', obj.w, obj.h)
                    } else if (ratio < 0) {
                        obj.w = pic.width;
                        obj.h = pic.width / ratio_sprite;
                        obj.y = (obj.h - pic.height) / 2;
                        console.warn('a类--3------', obj.w, obj.h)
                    }
                } else if (ratio_img > 1) {
                    console.warn('b类--------');
                    if (ratio == 0) {
                        obj.w = pic.width;
                        obj.h = pic.height;
                        console.warn('b类--1------');
                    } else if (ratio > 0) {
                        obj.h = pic.height;
                        obj.w = pic.height * ratio_sprite
                        obj.x = (obj.w - pic.width) / 2;
                        console.warn('b类--2------')
                    } else if (ratio < 0) {
                        obj.w = pic.width;
                        obj.h = pic.width / ratio_sprite;
                        obj.y = (obj.h - pic.height) / 2;
                        console.warn('b类--3------')
                    }
                } else if (ratio_img < 1) {
                    console.warn('c类--------');
                    if (ratio == 0) {
                        obj.w = pic.height;
                        obj.h = pic.height;
                        console.warn('c类--1------')
                    } else if (ratio > 0) {
                        console.warn('c类--2------')
                        if (ratio_sprite > 1) {
                            console.warn('c类--2-1-----')
                            obj.h = pic.height;
                            obj.w = pic.height * ratio_sprite
                            obj.x = (obj.w - pic.width) / 2;
                        } else {
                            console.warn('c类--2-2-----')
                            obj.h = pic.height;
                            obj.w = pic.height * ratio_sprite
                            obj.x = (obj.w - pic.width) / 2;
                        }
                    } else if (ratio < 0) {
                        obj.w = pic.width;
                        obj.h = pic.width / ratio_sprite;
                        obj.y = (obj.h - pic.height) / 2;
                        console.warn('c类--3------')
                    }
                }
            }

            obj.w = parseInt(obj.w)
            obj.h = parseInt(obj.h)
            obj.x = parseInt(obj.x)
            obj.y = parseInt(obj.y)
            console.warn('d类-------', obj)
            return obj
        }


        function drawAvatar(pic) {
            /*
            var pic={
                url:''; // 图片链接
                width:20,// 展示的宽度(如果是画圆形 drawType: 'circle' 的时候,对比 pic.width 和 pic.height , 取最小值作为圆直径  )
                height:30,// 展示的高度(如果是画圆形 drawType: 'circle' 的时候,对比 pic.width 和 pic.height , 取最小值作为圆直径  )
                radius: 50,// 圆半径 (如果是画圆形 drawType: 'circle' 的时候, pic.radius 做为半径,  pic.width 和 pic.height 都回无效  )
                center_x: 220,// 中心点x 位置
                center_y: 320,// 中心点y 位置
                drawType: 'circle', // 画图的形状类型,参数有 : 'circle' || 'rect' || 'roundedRect'
            }
        
             */
            let spriteObj = PIXI.Sprite.from(pic.url);
            spriteObj.anchor.set(0, 0);
            let sprite_w = spriteObj.width, sprite_h = spriteObj.height;
            let circle_r;
            if (pic.drawType == 'circle') {
                if (pic.radius) {
                    circle_r = pic.radius
                } else {
                    pic.width > pic.height ? circle_r = pic.height / 2 : circle_r = pic.width / 2;
                }
                pic.width = circle_r * 2
                pic.height = circle_r * 2
            }
            // resize avatar 
            let resize_avatar = { sprite_w: spriteObj.width, sprite_h: spriteObj.height, ...pic, }
            let scale_size = setPicScale(resize_avatar);

            spriteObj.width = scale_size.w;
            spriteObj.height = scale_size.h;
            spriteObj.x = pic.center_x - spriteObj.width / 2
            spriteObj.y = pic.center_y - spriteObj.height / 2

            // 画蒙版图形 s
            let masking = new PIXI.Graphics();
            let mask_x = pic.center_x - pic.width / 2,
                mask_y = pic.center_y - pic.height / 2;
            masking.beginFill(0x66CCFF, .5);//背景色

            if (pic.drawType == 'rect') {
                console.warn('p1--');
                masking.drawRect(mask_x, mask_y, pic.width, pic.height);
            } if (pic.drawType == 'roundedRect') {
                console.warn('p1--');
                masking.drawRoundedRect(mask_x, mask_y, pic.width, pic.height, pic.rounde_deg || 10);
            } else if (pic.drawType == 'circle') {
                console.warn('-----------cut----------');
                // drawCircle
                mask_x = pic.center_x
                mask_y = pic.center_y
                masking.drawCircle(mask_x, mask_y, circle_r); // 圆心的 X 坐标,圆心的 y 坐标,半径
            }
            masking.endFill();
            spriteObj.mask = masking;
            // 画蒙版图形 e
            return [spriteObj, masking]
        }
        // ---------------------- 开始

        let my_container = document.querySelector('#pixiCantainer')

        let htmlFontSize = parseFloat(document.querySelector('html').style.fontSize)
        console.log(htmlFontSize, 'htmlFontSize是');
        let ui_width = 750
        let start_y = 20
        // 启动app
        const app = new PIXI.Application({
            background: '#fcf',
            // resizeTo: window,
            width: ui_width,
            antialias: true,//抗锯齿功能开启,默认不开,开了会比较消耗性能
            // height: 700,
        });
        let children_list = []

        my_container.appendChild(app.view);

        let pic_data = {
            frame_bg: 'https://image.whoisamy.shop/action/commonPics/23_08_11_groupPurchase/page_bg.png',
            frame_top: 'https://image.whoisamy.shop/action/commonPics/23_08_11_groupPurchase/fra_top.png',
            frame_mid: 'https://image.whoisamy.shop/action/commonPics/23_08_11_groupPurchase/fra_mid.png',
            frame_bot: 'https://image.whoisamy.shop/action/commonPics/23_08_11_groupPurchase/fra_bot.png',
            avatar_1: "https://th.bing.com/th/id/R.b49dbddffaa692d75988e0c5882dacca?rik=r6IIYs2muimY7A&riu=http%3a%2f%2fwww.quazero.com%2fuploads%2fallimg%2f140529%2f1-140529145A4.jpg&ehk=Co9XURYRCjJXUTzFG0Mw6lD7olzDKceEgv3slEC8kvQ%3d&risl=&pid=ImgRaw&r=0",
            avatar_2: "https://img.zcool.cn/community/0104c15cd45b49a80121416816f1ec.jpg@1280w_1l_2o_100sh.jpg",
            avatar_3: "https://pic2.zhimg.com/255de7c1e56c1ab09329885d85d2c16a_r.jpg?source=1940ef5c",
        }

        let pic_arr = []
        for (const key in pic_data) {
            if (Object.hasOwnProperty.call(pic_data, key)) {
                const element = pic_data[key];
                pic_arr.push(element)
            }
        }


        let loader = app.loader,
            // resources = app.loader.resources,
            Sprite = PIXI.Sprite;



        // pic 1 s  背景图
        const bunny_1 = PIXI.Sprite.from(pic_data.frame_bg);
        bunny_1.anchor.set(0, 0);
        // bunny_2.x = app.screen.width / 2 - bunny_2.width / 2;
        bunny_1.x = app.screen.width / 2 - (702 - 20) / 2;
        bunny_1.y = start_y + 20 - 14;
        bunny_1.width = 702 - 16;
        bunny_1.height = 500 + 30;
        // app.stage.addChild(bunny_2);
        // pic 1 e

        // pic 2 s 头边框
        const bunny_2 = PIXI.Sprite.from(pic_data.frame_top);
        bunny_2.anchor.set(0, 0);
        // bunny_2.x = app.screen.width / 2 - bunny_2.width / 2;
        bunny_2.x = app.screen.width / 2 - 702 / 2;
        bunny_2.y = start_y;
        // pic 2 e

        // pic 3 s 中边框
        const bunny_3 = PIXI.Sprite.from(pic_data.frame_mid);
        bunny_3.anchor.set(0, 0);
        bunny_3.height = 400
        bunny_3.x = app.screen.width / 2 - 702 / 2;
        bunny_3.y = 71 + start_y;
        // pic 3 e

        // pic 4 s 底边框
        const bunny_4 = PIXI.Sprite.from(pic_data.frame_bot);
        bunny_4.anchor.set(0, 0);
        bunny_4.x = app.screen.width / 2 - 702 / 2;
        bunny_4.y = 400 + start_y + 71;
        // pic 4 e


        const style = new PIXI.TextStyle({
            fontFamily: 'Arial',
            fontSize: 36,
            fontStyle: 'italic',
            fontWeight: 'bold',
            fill: ['#ffffff', '#00ff99'], // gradient
            stroke: '#4a1850',
            strokeThickness: 5,
            dropShadow: true,
            dropShadowColor: '#000000',
            dropShadowBlur: 4,
            dropShadowAngle: Math.PI / 6,
            dropShadowDistance: 6,
            wordWrap: true,
            wordWrapWidth: 440,
            lineJoin: 'round',
        });

        const richText = new PIXI.Text('Rich text with a lot of options and across multiple lines', style);

        richText.x = 50;
        richText.y = 220;


        // 

        // app.stage.addChild(rectangle);



        let rectangle = new PIXI.Graphics();
        rectangle.lineStyle(4, 0xFF3300, 1);
        rectangle.beginFill(0x66CCFF);
        rectangle.drawRect(0, 0, 64, 64);
        rectangle.endFill();
        rectangle.x = 70;
        rectangle.y = 70;

        let circle = new PIXI.Graphics();
        circle.beginFill(0x9966FF);
        circle.drawCircle(0, 0, 32);
        circle.endFill();
        circle.x = 84;
        circle.y = 130;

        // 画头像 s
        // function drawAvatar(url) {
        //     let imgbase64;
        //     let cvs = document.createElement('canvas')
        //     cvs.setAttribute('class','avatarCanvas')
        //     cvs.style.cssText = "position:absolute;left:0;top:0;z-index:-1"
        //     // 

        // 填充图片到形状中 (蒙版) s ------------
        //创建精灵
        // let Pikachu = new PIXI.Sprite(PIXI.loader.resources[pic_data.avatar_1].texture);
        let Pikachu = PIXI.Sprite.from(pic_data.avatar_1);

        //创建一个正方形对象
        let rectangle_2 = new PIXI.Graphics();
        rectangle_2.beginFill(0x66CCFF);
        rectangle_2.drawRect(0, 0, 200, 200);
        rectangle_2.endFill();
        rectangle_2.x = 300;
        rectangle_2.y = 300;

        //给精灵设置蒙版
        Pikachu.mask = rectangle_2;

        // *-*
        // ---------
        let avatar_cp = { y: 160, x: 270, }
        let avatar_cp_1 = drawAvatar({
            url: pic_data.avatar_1,
            // url: pic_data.avatar_2,
            // url: pic_data.avatar_3,
            width: 200,
            height: 180,
            // objectFit: 'cover',
            // drawType: 'rect',
            drawType: 'roundedRect',
            // drawType: 'circle',
            center_x: avatar_cp.x,//中心点x
            center_y: avatar_cp.y,//中心点y
            radius: 100,//半径
            rounde_deg: 40,
            // lineStyle: "4, 0xFF3300, 1"
        })
        let avatar_cp_2 = drawAvatar({
            // url: pic_data.avatar_1,
            url: pic_data.avatar_2,
            // url: pic_data.avatar_3,
            width: 200,
            height: 200,
            // objectFit: 'cover',
            drawType: 'circle',
            // drawType: 'rect',
            center_x: avatar_cp.x + 300,//中心点x
            center_y: avatar_cp.y,//中心点y
            radius: 100,//半径
            // lineStyle: "4, 0xFF3300, 1"
        })

        let avatar_list = [...avatar_cp_1, ...avatar_cp_2]
        // console.log(myAvatar, '[myAvatar是]');

        // 头像1 e

        // 填充图片到形状中 (蒙版) e ------------

        // 画头像 e
        children_list = [bunny_1, bunny_4, bunny_3, bunny_2, richText, rectangle, circle, rectangle_2, ...avatar_list]
        console.log(children_list, 'children_list 是');

        app.stage.addChild(...children_list);



    </script>
</body>

</html>