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

相关推荐
xyq20247 分钟前
TypeScript中的String类型详解
开发语言
英俊潇洒美少年7 分钟前
Vue2/Vue3 vue-i18n完整改造流程(异步懒加载+后端接口请求)
前端·javascript·vue.js
小糖学代码6 小时前
LLM系列:1.python入门:15.JSON 数据处理与操作
开发语言·python·json·aigc
空中海6 小时前
第七章:vue工程化与构建工具
前端·javascript·vue.js
handler016 小时前
从源码到二进制:深度拆解 Linux 下 C 程序的编译与链接全流程
linux·c语言·开发语言·c++·笔记·学习
zhensherlock6 小时前
Protocol Launcher 系列:Trello 看板管理的协议自动化
前端·javascript·typescript·node.js·自动化·github·js
小白学大数据7 小时前
现代Python爬虫开发范式:基于Asyncio的高可用架构实战
开发语言·爬虫·python·架构
渔舟小调7 小时前
P19 | 前端加密通信层 pikachuNetwork.js 完整实现
开发语言·前端·javascript
不爱吃炸鸡柳7 小时前
数据结构精讲:树 → 二叉树 → 堆 从入门到实战
开发语言·数据结构
网络安全许木7 小时前
自学渗透测试第21天(基础命令复盘与DVWA熟悉)
开发语言·网络安全·渗透测试·php