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

相关推荐
LjQ20401 分钟前
网络爬虫一课一得
开发语言·数据库·python·网络爬虫
你是狒狒吗8 分钟前
TM中,return new TransactionManagerImpl(raf, fc);为什么返回是new了一个新的实例
java·开发语言·数据库
spionbo18 分钟前
Vue 表情包输入组件实现代码及完整开发流程解析
前端·javascript·面试
全宝19 分钟前
✏️Canvas实现环形文字
前端·javascript·canvas
勤奋的知更鸟19 分钟前
Java编程之组合模式
java·开发语言·设计模式·组合模式
虾球xz25 分钟前
CppCon 2015 学习:3D Face Tracking and Reconstruction using Modern C++
开发语言·c++·学习·3d
JoannaJuanCV28 分钟前
BEV和OCC学习-3:mmdet3d 坐标系
3d·occ·bev
林鸿群28 分钟前
C#子线程更新主线程UI及委托回调使用示例
开发语言·c#
前端梭哈攻城狮32 分钟前
uniapp图片上传添加水印/压缩/剪裁
前端·javascript·vue.js
天涯学馆32 分钟前
前后端分离的 API 设计:技术深度剖析
前端·javascript·面试