简体   繁体   中英

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. (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. So far, I have looked into Paper.js and plain Canvas and its 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).
  • 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.)
  • 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.

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.

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. 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. There are some higher level libraries to make this easier. One of the best known is three.js .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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