简体   繁体   English

如何使用在3D空间中设置动画的2D对象创建图形画布?

[英]How can I create a graphic canvas with 2D objects animated in 3D space?

I came across this site and fell in love with the background animation, particularly the points connected to each other, animating in a 3D space. 我偶然发现了这个网站,并且爱上了背景动画,尤其是在3D空间中进行动画连接的各个点。 (The element in question is: <canvas id="bg" width="1920" height="995"></canvas> ) I am new to canvas animation, and from the research I've done so far, I do not know what path I should start down to achieve a similar background animation for my project. (有问题的元素是: <canvas id="bg" width="1920" height="995"></canvas> )我是画布动画的新手,根据到目前为止的研究,我知道不知道我应该从哪条路开始,以便为我的项目实现类似的背景动画。 So far, I have looked into Paper.js and plain Canvas and its JS API. 到目前为止,我已经研究了Paper.js和普通的Canvas及其JS API。

Here are the specifications I have: 这是我的规格:

  • Ability to make 'canvas' (not literally <canvas> , but the graphic canvas. I am not opposed to any particular graphic wrapper). 能够制作“画布”(不是字面上的<canvas> ,而是图形画布。我并不反对任何特定的图形包装器)。
  • Ability to make 'canvas' responsive 使“画布”具有响应能力
  • Round points (2D circles) navigating in 3D space (ability to spin objects on an axis is a plus, animating in a helix is an extra plus.) 在3D空间中导航的圆点(2D圆)(在轴上旋转对象的能力是加号,在螺旋中进行动画效果是额外的加号。)
  • Instantiable modules of these Round Point sets 这些圆点集的可实例化模块
  • Ability to animate these modules on specific events (click, hover, etc) 能够对特定事件(单击,悬停等)进行动画处理

Nice to haves: 很高兴拥有:

  • Vector graphics 矢量图形

Something similar to what I want to achieve can be viewed here . 可以在此处查看与我要实现的目标类似的东西。

I know all of what I am trying to do will require pieces to a whole (JS graphics library such as Paper.js, custom JS classes, etc), but I would just like to know what others have had success with. 我知道我要尝试做的所有事情都需要整体(JS图形库,例如Paper.js,自定义JS类等),但是我只想知道其他人成功了。

Thanks! 谢谢!

I honestly just did this on a whim. 老实说,我只是一时兴起。 I usually try not to bite on the questions that say "give me this code" but I wanted to see how long it would take to do it. 我通常尽量不回答说“给我这个代码”的问题,但是我想知道这样做需要多长时间。 It could definitely be cleaned up, name spaced, ect, it may not even be what you're looking for at all but the effect turned out cool regardless. 它肯定可以清理,命名等,它甚至根本不是您要找的东西,但是效果却很酷。

note mouse events are not included in this example. 注意此示例中不包括鼠标事件。 The question is a bit vague in terms of specifics so all I provided is a very simple way to get started using 3d and the canvas 2d element. 这个问题在细节上有点含糊,所以我提供的只是一种非常简单的方法来开始使用3d和canvas 2d元素。

Theres some pretty decent code here which is the example code and book exercises from Foundation HTML5 Animation with JavaScript which has some fantastic intro to 3d examples using Javascript and canvas. 这里有一些相当不错的代码它是带有JavaScript的Foundation HTML5 Animation的示例代码和书籍练习,其中包含一些使用Javascript和canvas的3d示例的精彩介绍。 I recommend checking it out! 我建议检查一下!

Live Demo 现场演示

Full Screen 全屏

fiddle 小提琴

var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d");

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
ctx.lineWidth = 4;

// Color stuff not real important just fluff
var cycle = 0,
    colors = {
        r: 0,
        g: 170,
        b: 0
    };

function colorCycle(inc) {
    cycle += inc;
    if (cycle > 100) {
        cycle = 0;
    }
    colors.r = ~~ (Math.sin(.3 * cycle + 0) * 127 + 128);
    colors.g = ~~ (Math.sin(.3 * cycle + 2) * 127 + 128);
    colors.b = ~~ (Math.sin(.3 * cycle + 4) * 127 + 128);
}

// Sections and points

function Point(x, y, z, size) {
    this.x = x;
    this.y = y;
    this.z = z;
    this.xpos = 0;
    this.ypos = 0;
    this.size = 5;

    rotateY(this,angle+=0.1);
}

function Section(x, y, z, width) {
    this.x = x;
    this.y = y;
    this.z = z;
    this.width = width;
    this.points = [];
    this.points.push(new Point(this.x - this.width / 2, this.y, this.z, 20));
    this.points.push(new Point(this.x + this.width / 2, this.y, this.z, 20));

    this.render = function (angleX, angleY) {
        ctx.beginPath();
        for (var p = 0; p < this.points.length; p++) {
            var point = this.points[p];

            rotateX(point, angleX);
            rotateY(point, angleY);
            doPerspective(point);

            ctx.arc(point.xpos, point.ypos, point.size, 0, Math.PI * 2, true);

            if (p == 0) {
                ctx.moveTo(this.points[0].xpos, this.points[0].ypos);
            } else {
                ctx.lineTo(point.xpos, point.ypos);
            }
        }

        ctx.closePath();
        ctx.stroke();
        ctx.fill();
    }
}

// 3d Functions for rotation and perspective
function rotateX(point, angleX) {
    var cosX = Math.cos(angleX),
        sinX = Math.sin(angleX),
        y1 = point.y * cosX - point.z * sinX,
        z1 = point.z * cosX + point.y * sinX;
    point.y = y1;
    point.z = z1;
}

function rotateY(point, angleY) {
    var cosY = Math.cos(angleY),
        sinY = Math.sin(angleY),
        x1 = point.x * cosY - point.z * sinY,
        z1 = point.z * cosY + point.x * sinY;
    point.x = x1;
    point.z = z1;
}

function doPerspective(point) {
    if (point.z > -fl) {
        var scale = fl / (fl + point.z);
        point.size = scale * 5;
        point.xpos = vpX + point.x * scale;
        point.ypos = vpY + point.y * scale;
    }
}

// Init code
var sections = [],
    numSections = 50,
    fl = 250,
    vpX,
    vpY,
    angle = 0;

vpX = canvas.width / 2;
vpY = canvas.height / 2;

// make some sections
for (var i = 0; i < numSections; i++) {
    sections.push(new Section(0, -250 + (i * 10), 0, 50));
}

function render() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    colorCycle(0.1);
    ctx.fillStyle = "rgb(" + colors.r + "," + colors.g + "," + colors.b + ")";
    ctx.strokeStyle = "rgb(" + colors.r + "," + colors.g + "," + colors.b + ")";
    for (var i = 0; i < sections.length; i++) {
        sections[i].render(0, 0.03);
    }
    requestAnimationFrame(render);
}
render();

When you are aiming for high quality 3d graphics in the browser without any plugins, it can get complicated quickly. 如果您的目标是在浏览器中使用高质量的3d图形而没有任何插件,则它很快就会变得复杂。 There are some higher level libraries to make this easier. 有一些更高级别的库使此操作更容易。 One of the best known is three.js . 最著名的之一是three.js

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM