【JavaScript】使用canvas随机生成类似gitLab(github)对称几何头像

【JavaScript】使用canvas随机生成类似gitLab(github)对称几何头像_第1张图片

一.算法分析

头像分成4个小正方形,这四个小正方形图案只是通过旋转构成。
每个小正方形中有四个图案,构建这四个图案。
那么就可以通过两个for循环,外循环为旋转,内循环来绘制图案。

二.模型构建分析:

1.以头像中心为原点,水平为x轴,垂直为y轴建系。
【JavaScript】使用canvas随机生成类似gitLab(github)对称几何头像_第2张图片
1.xy轴将头像分成4个部分,可以很明显看出,头像可以由任意一个1/4图形旋转构成。
观察1/4图形(也就是一个象限)的形状。

2.以第一象限为例,同样划分成4个小正方形
【JavaScript】使用canvas随机生成类似gitLab(github)对称几何头像_第3张图片
在这些小正方形去构建图形,这里我们以构建三角形为例。
我的解决方案是:将正方形划分成25个点,每次选取三个点去构成三角形。
【JavaScript】使用canvas随机生成类似gitLab(github)对称几何头像_第4张图片
这样通过两个嵌套的for循环,就能够完成头像的绘制。

三.使用canvas进行绘制

//position为坐标的封装类
class position {
    constructor(x = null, y = null) {
        this._x = x;
        this._y = y;
    }
    init() {
        this.x = Math.floor(Math.random() * 5);
        this.y = Math.floor(Math.random() * 5);
    }
    toString() {
        return '(' + this.x + ', ' + this.y + ')';
    }
    get x() {
        return this._x;
    }
    get y() {
        return this._y;
    }
    set x(x) {
        this._x = x;
    }
    set y(y) {
        this._y = y;
    }
}
//quarter为单位三角形的坐标类
class quarter {
    constructor(a, b, c) {
        this._a = a;
        this._b = b;
        this._c = c;
    }
    get a() {
        return this._a;
    }
    get b() {
        return this._b;
    }
    get c() {
        return this._c;
    }
    set a(a) {
        return this._a = a;
    }
    set b(b) {
        return this._b = b;
    }
    set c(c) {
        return this._c = c;
    }
}

//生成图形的坐标
function generatorMap() {
    let a = new position().init();
    let b = new position().init();
    let c = new position().init();
    return new quarter(a, b, c);
}

//绘画
function drawAvatar(canvasId, containerId) {
    /*根据id获取canvas
    * 如果为空,则创建新的canvas
    * */
    var canvas = document.getElementById(canvasId);
    if (canvas) {
        canvas.remove();
    } else {
        var newcanvas = "";
        document.getElementsByName("body").append(newcanvas);
        canvas = document.getElementById(canvasId);
    }

    //初始化canvas设置
    canvas.width = 800;
    canvas.height = 800;
    var ctx = canvas.getContext('2d');
    //头像背景颜色设置
    ctx.fillStyle = "#FFFFFF";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    //设置头像颜色
    var colors = [
        "#1abc9c", "#2ecc71", "#3498db", "#9b59b6", "#34495e", "#16a085", "#27ae60", "#2980b9", "#8e44ad", "#2c3e50",
        "#f1c40f", "#e67e22", "#e74c3c", "#00bcd4", "#95a5a6", "#f39c12", "#d35400", "#c0392b", "#bdc3c7", "#7f8c8d"
    ];
    ctx.fillStyle = colors[Math.floor((Math.random() * colors.length))];
    ctx.translate(400, 400);
    for (let i = 1; i <= 4; i++) {
        let quarter = generatorMap();
        let a, b, c;
        a = caculateP(quarter.a, i);
        b = caculateP(quarter.b, i);
        c = caculateP(quarter.c, i);
        for (var j = 0; j < 4; j++) { // draw individual dots
            ctx.rotate(Math.PI*2/4);
            ctx.beginPath();
            ctx.moveTo(a.x, a.y);
            ctx.lineTo(b.x, b.y);
            ctx.lineTo(c.x, c.y);
            ctx.fill();
        }
    }
    document.getElementById(containerId).src = canvas.toDataURL("image/png");
}

function caculateP(position, i) {
    var step = 50;
    position.x = (i % 2 == 1 ? 0 : 1) * 4 * step + position.x * step;
    position.y = (i <= 2 ? 0 : 1) * 4 * step + position.y * step;
    console.log(position.x, position.y);
    return position;
}

总结:
1.不足就是图形过于单调,但可以通过调整算法。比如在5*5的数组中构建好一定数量的图形,封装成一个类,然后随机选择。
2.canvas是否存在镜像的方法?我没有在mdn上找到答案,如果有镜像映射,那么只要生成1/4,然后映射两次就行。
3.兴趣始于gitlab以及github的头像,蛮好看的,同样可以调整算法进行绘制。

参考:
canvas旋转样例

你可能感兴趣的:(JavaScript)