HTML5画布旋转球

HTML5 Canvas Twirl Sphere
HTML5 Canvas Twirl Sphere

HTML5 Canvas Twirl Sphere Today, I would like to tell about creation of animated Twirl Sphere (I modified our previous 3D sphere, and, I used same way of accessing pixels of canvas). Our sphere goes around the canvas continuously. This example is cross browser solution (because of html5).

HTML5 Canvas Twirl Sphere今天,我想介绍一下动画Twirl Sphere的创建(我修改了之前的3D球体,并且使用了相同的方式访问画布像素)。 我们的领域不断围绕着画布。 此示例是跨浏览器解决方案(由于html5)。

In the result, you should to get something like this:

结果,您应该获得如下内容:

HTML5 Canvas Twirl Sphere

HTML5画布旋转球

Here are our demo and downloadable package:

这是我们的演示和可下载的软件包:

现场演示
打包下载

Ok, please download our source files and let’s start coding !

好的,请下载我们的源文件,然后开始编码!

步骤1. HTML (Step 1. HTML)

This is markup of our result page. Here it is:

这是我们结果页的标记。 这里是:

index.html (index.html)

<div class="container">
    <canvas id="slideshow" width="1024" height="630"></canvas>
    <canvas id="obj" width="256" height="256"></canvas>
</div>

<div class="container">
    <canvas id="slideshow" width="1024" height="630"></canvas>
    <canvas id="obj" width="256" height="256"></canvas>
</div>

I prepared two canvas objects: first one for resource image, and second one – for our Twirl sphere.

我准备了两个画布对象:第一个用于资源图像,第二个用于我们的Twirl球形。

步骤2. CSS (Step 2. CSS)

css / main.css (css/main.css)

.container {
    height: 630px;
    margin: 50px auto;
    position: relative;
    width: 1024px;
    z-index: 1;
}
#obj {
    position: absolute;
    z-index: 2;
}

.container {
    height: 630px;
    margin: 50px auto;
    position: relative;
    width: 1024px;
    z-index: 1;
}
#obj {
    position: absolute;
    z-index: 2;
}

We should keep our Sphere object above our main canvas.

我们应该将Sphere对象保持在主画布上方。

步骤3. JS (Step 3. JS)

And now, our main js script file. Here it is:

现在,我们的主要js脚本文件。 这里是:

js / script.js (js/script.js)

var canvas, ctx;
var canvasObj, ctxObj;
var iDstW = 256;
var iDstH = 256;
var iXSpeed = 4;
var iYSpeed = 3;
var iLastX = iDstW / 2;
var iLastY = iDstH / 2;
var oImage;
var aMap = [];
var aMapT = [];
var aBitmap;
var mathTwirl = function(px,py) {
    var x = px - iDstW / 2;
    var y = py - iDstH / 2;
    var r = Math.sqrt(x * x + y * y);
    var maxR = iDstW / 2;
    if (r > maxR) return {'x':px, 'y':py, 't': 1};
    var a = Math.atan2(y, x);
    a -= 1 - r / maxR;
    var dx = Math.cos(a) * r;
    var dy = Math.sin(a) * r;
    return {'x': dx+iDstW/2, 'y': dy+iDstH/2, 't': 1.5}
}
window.onload = function(){
    // load background
    oImage = new Image();
    oImage.src = 'images/bg.jpg';
    oImage.onload = function () {
        // creating canvas and context objects
        canvas = document.getElementById('slideshow');
        ctx = canvas.getContext('2d');
        canvasObj = document.getElementById('obj');
        ctxObj = canvasObj.getContext('2d');
        // clear context
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
        // and draw source image
        ctx.drawImage(oImage, 0, 0);
        aBitmap = ctx.getImageData(0, 0, iDstW, iDstH);
        for (var y = 0; y < iDstH; y++) {
            for (var x = 0; x < iDstW; x++) {
                var t = mathTwirl(x, y);
                aMap[(x + y * iDstH) * 2 + 0] = Math.max(Math.min(t.x, iDstW - 1), 0);
                aMap[(x + y * iDstH) * 2 + 1] = Math.max(Math.min(t.y, iDstH - 1), 0);
                aMapT[(x + y * iDstH)] = t.t;
            }
        }
        // begin updating scene
        updateScene();
    };
    function updateScene() {
        // update last coordinates
        iLastX = iLastX + iXSpeed;
        iLastY = iLastY + iYSpeed;
        // reverse speed
        if (iLastX + 1 > ctx.canvas.width - iDstW/2) {
            iXSpeed = -4;
        }
        if (iLastX - 1 < iDstW/2) {
            iXSpeed = 4;
        }
        if (iLastY + 1 > ctx.canvas.height - iDstH/2) {
            iYSpeed = -3;
        }
        if (iLastY - 1 < iDstH/2) {
            iYSpeed = 3;
        }
        // shifting of the second object
        canvasObj.style.left = iLastX - Math.floor(iDstW / 2) + 'px';
        canvasObj.style.top = iLastY - (Math.floor(iDstH / 2)) + 'px';
        // draw result Twirl sphere
        var aData = ctx.getImageData(iLastX - Math.ceil(iDstW / 2), iLastY - Math.ceil(iDstH / 2), iDstW, iDstH + 1);
        for (var j = 0; j < iDstH; j++) {
            for (var i = 0; i < iDstW; i++) {
                var u = aMap[(i + j * iDstH) * 2];
                var v = aMap[(i + j * iDstH) * 2 + 1];
                var t = aMapT[(i + j * iDstH)];
                var x = Math.floor(u);
                var y = Math.floor(v);
                var kx = u - x;
                var ky = v - y;
                for (var c = 0; c < 3; c++) {
                    aBitmap.data[(i + j * iDstH) * 4 + c] =
                      (aData.data[(x + y * iDstH) * 4 + c] * (1 - kx) + aData.data[((x + 1) + y * iDstH) * 4 + c] * kx) * (1-ky) * t +
                      (aData.data[(x + (y + 1) * iDstH) * 4 + c] * (1 - kx) + aData.data[((x + 1) + (y + 1) * iDstH) * 4 + c] * kx) * (ky) * t;
                }
            }
        }
        ctxObj.putImageData(aBitmap,0,0);
        // update timer
        setTimeout(updateScene, 16);
    }
};

var canvas, ctx;
var canvasObj, ctxObj;
var iDstW = 256;
var iDstH = 256;
var iXSpeed = 4;
var iYSpeed = 3;
var iLastX = iDstW / 2;
var iLastY = iDstH / 2;
var oImage;
var aMap = [];
var aMapT = [];
var aBitmap;
var mathTwirl = function(px,py) {
    var x = px - iDstW / 2;
    var y = py - iDstH / 2;
    var r = Math.sqrt(x * x + y * y);
    var maxR = iDstW / 2;
    if (r > maxR) return {'x':px, 'y':py, 't': 1};
    var a = Math.atan2(y, x);
    a -= 1 - r / maxR;
    var dx = Math.cos(a) * r;
    var dy = Math.sin(a) * r;
    return {'x': dx+iDstW/2, 'y': dy+iDstH/2, 't': 1.5}
}
window.onload = function(){
    // load background
    oImage = new Image();
    oImage.src = 'images/bg.jpg';
    oImage.onload = function () {
        // creating canvas and context objects
        canvas = document.getElementById('slideshow');
        ctx = canvas.getContext('2d');
        canvasObj = document.getElementById('obj');
        ctxObj = canvasObj.getContext('2d');
        // clear context
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
        // and draw source image
        ctx.drawImage(oImage, 0, 0);
        aBitmap = ctx.getImageData(0, 0, iDstW, iDstH);
        for (var y = 0; y < iDstH; y++) {
            for (var x = 0; x < iDstW; x++) {
                var t = mathTwirl(x, y);
                aMap[(x + y * iDstH) * 2 + 0] = Math.max(Math.min(t.x, iDstW - 1), 0);
                aMap[(x + y * iDstH) * 2 + 1] = Math.max(Math.min(t.y, iDstH - 1), 0);
                aMapT[(x + y * iDstH)] = t.t;
            }
        }
        // begin updating scene
        updateScene();
    };
    function updateScene() {
        // update last coordinates
        iLastX = iLastX + iXSpeed;
        iLastY = iLastY + iYSpeed;
        // reverse speed
        if (iLastX + 1 > ctx.canvas.width - iDstW/2) {
            iXSpeed = -4;
        }
        if (iLastX - 1 < iDstW/2) {
            iXSpeed = 4;
        }
        if (iLastY + 1 > ctx.canvas.height - iDstH/2) {
            iYSpeed = -3;
        }
        if (iLastY - 1 < iDstH/2) {
            iYSpeed = 3;
        }
        // shifting of the second object
        canvasObj.style.left = iLastX - Math.floor(iDstW / 2) + 'px';
        canvasObj.style.top = iLastY - (Math.floor(iDstH / 2)) + 'px';
        // draw result Twirl sphere
        var aData = ctx.getImageData(iLastX - Math.ceil(iDstW / 2), iLastY - Math.ceil(iDstH / 2), iDstW, iDstH + 1);
        for (var j = 0; j < iDstH; j++) {
            for (var i = 0; i < iDstW; i++) {
                var u = aMap[(i + j * iDstH) * 2];
                var v = aMap[(i + j * iDstH) * 2 + 1];
                var t = aMapT[(i + j * iDstH)];
                var x = Math.floor(u);
                var y = Math.floor(v);
                var kx = u - x;
                var ky = v - y;
                for (var c = 0; c < 3; c++) {
                    aBitmap.data[(i + j * iDstH) * 4 + c] =
                      (aData.data[(x + y * iDstH) * 4 + c] * (1 - kx) + aData.data[((x + 1) + y * iDstH) * 4 + c] * kx) * (1-ky) * t +
                      (aData.data[(x + (y + 1) * iDstH) * 4 + c] * (1 - kx) + aData.data[((x + 1) + (y + 1) * iDstH) * 4 + c] * kx) * (ky) * t;
                }
            }
        }
        ctxObj.putImageData(aBitmap,0,0);
        // update timer
        setTimeout(updateScene, 16);
    }
};

During initialization, the script is preparing two canvas objects and two contexts. After, it loads background image, and draw it at our first context. After it prepares hash table of sphere transformations: aMap (with using of new mathTwirl function). And, in the end – it starts timer which updates the main scene. This function (updateScene) updates coordinates of our Sphere object, and draws updated sphere at our second context.

在初始化期间,脚本正在准备两个画布对象和两个上下文。 之后,它将加载背景图像,并在我们的第一个上下文中绘制它。 准备好球体转换的哈希表之后:aMap(使用新的mathTwirl函数)。 最后,它启动计时器来更新主要场景。 此函数(updateScene)更新Sphere对象的坐标,并在第二个上下文中绘制更新的sphere。

现场演示
打包下载

结论 (Conclusion)

I hope that today’s Twirl HTML5 Sphere lesson has been interesting for you. We have done another one nice html5 example. I will be glad to see your thanks and comments. Good luck!

我希望今天的Twirl HTML5 Sphere课程对您来说很有趣。 我们还做了另一个很好的html5示例。 看到您的感谢和评论,我将非常高兴。 祝好运!

翻译自: https://www.script-tutorials.com/html5-canvas-twirl-sphere/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值