Canvas实现3D效果

3D 球

效果图

代码

复制代码
var canvas = document.getElementById("cas"),
    ctx = canvas.getContext("2d"),
    vpx = canvas.width / 2,
    vpy = canvas.height / 2,
    Radius = 150,
    balls = [],
    angleX = Math.PI / 1000,
    angleY = Math.PI / 1000,

    factor = 0.0001 //旋转因子


var Animation = function () {
    this.init();
};
Animation.prototype = {
    init: function () {
        balls = [];
        var num = 500;
        for (var i = 0; i <= num; i++) {
            var k = -1 + (2 * (i + 1) - 1) / num;
            var a = Math.acos(k);
            var b = a * Math.sqrt(num * Math.PI);
            var x = Radius * Math.sin(a) * Math.cos(b);
            var y = Radius * Math.sin(a) * Math.sin(b);
            var z = Radius * Math.cos(a);
            var b = new ball(x, y, z, 1.5);
            balls.push(b);
            b.paint();
        }
    }
}

function animate() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    rotateX();
    rotateY();
    balls.sort(function (a, b) {
        return b.z - a.z;
    })
    for (var i = 0; i < balls.length; i++) {
        balls[i].paint();
    }
}

function rotateX() {
    var cos = Math.cos(angleX);
    var sin = Math.sin(angleX);
    for (var i = 0; i < balls.length; i++) {
        var y1 = balls[i].y * cos - balls[i].z * sin;
        var z1 = balls[i].z * cos + balls[i].y * sin;
        balls[i].y = y1;
        balls[i].z = z1;
    }
}

function rotateY() {
    var cos = Math.cos(angleY);
    var sin = Math.sin(angleY);
    for (var i = 0; i < balls.length; i++) {
        var x1 = balls[i].x * cos - balls[i].z * sin;
        var z1 = balls[i].z * cos + balls[i].x * sin;
        balls[i].x = x1;
        balls[i].z = z1;
    }
}

var ball = function (x, y, z, r) {
    this.x = x;
    this.y = y;
    this.z = z;
    this.r = r;
    this.width = 2 * r;
}

ball.prototype = {
    paint: function () {
        var fl = 450 //焦距
        ctx.save();
        ctx.beginPath();
        var scale = fl / (fl - this.z);
        var alpha = (this.z + Radius) / (2 * Radius);
        ctx.arc(vpx + this.x, vpy + this.y, this.r * scale, 0, 2 * Math.PI, true);
        ctx.fillStyle = "rgba(0,0,0," + (alpha + 0.5) + ")"
        ctx.fill();
        ctx.restore();
    }
}

var animation = new Animation();
canvas.addEventListener('mousedown', onMousedown)

function onMousedown() {
    window.addEventListener('mousemove', onMousemove)
    window.addEventListener('mouseup', onMouseup)
}

function onMousemove(e) {
    var x = e.clientX - canvas.offsetLeft - vpx - document.body.scrollLeft - document.documentElement
        .scrollLeft;
    var y = e.clientY - canvas.offsetTop - vpy - document.body.scrollTop - document.documentElement
        .scrollTop;
    angleY = -x * factor;
    angleX = -y * factor;
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    rotateX();
    rotateY();
    balls.sort(function (a, b) {
        return b.z - a.z;
    })
    for (var i = 0; i < balls.length; i++) {
        balls[i].paint();
    }
}

function onMouseup() {
    window.removeEventListener('mousemove', onMousemove)
    window.removeEventListener('mouseup', onMouseup)
}

参考链接

https://tool.4xseo.com/a/2285.html

相关推荐
云和数据.ChenGuang2 分钟前
Python 菜鸟入门:字典(dict)类型详解与 CRUD 实战案例
开发语言·人工智能·python
攻城狮Soar18 分钟前
详解volatile
开发语言·c++·1024程序员节
小羊没烦恼!18 分钟前
.NET无侵入自动化探针原理和主流实现
运维·开发语言·javascript·python·自动化·.net·1024程序员节
ch.ju28 分钟前
Java——idea知识:Collection父接口
java·开发语言·intellij-idea
昵称画9 小时前
交接班记录电子化:三班之间的信息不漏
开发语言·数据库·人工智能·低代码·php
“AI国潮设计-小江”9 小时前
【AIGC实战】Python+SDXL批量生成“潮汕英歌舞不倒翁”IP | 角色一致性与多场景融合方案,附完整代码
开发语言·人工智能·python·prompt·aigc
传奇开心果编程9 小时前
【Rust入门练中学】第6课:结构体与方法
开发语言·rust·结构体·编程语言理论·结构体方法·编程通用语言
Linux_cy9 小时前
服务器管理工具哪个好用?我用了七八个
运维·服务器·javascript·python·ssh·面板·gmssh
code tsunami9 小时前
【无标题】
开发语言·python
变与不变8069 小时前
jQuery细节以及使用应用场景
前端·javascript·jquery