canvas用2d渲染出3d的感覺


  好久沒有寫博客了,深究動畫其實也就是setTimeout setInterval requestAnimationFrame很多人可能不熟悉requestAnimationFrame但是事實上和setTimeout沒有區別,setTImeout是 通過定時然后達到循環執行,后者呢比較優雅,動畫幀。。。不說了,我也不知道,自己測試一下,程序員是應該有這種一探究竟的精神。

  在實際數據中很可能是沒有perspeactive 3d,也沒有transition-z的。但是三維的東西其實也就是在電腦屏幕上而已,屏幕沒有厚多少多少的說法吧,所以呢,事實上在屏幕上看到的其實也不過是畫在一張二維屏幕上的視覺效果圖而已。

  先說一個最基本的知識,俗話說的transition3d的3d是關於屏幕的水平方向和豎直方向,還有一個是人和屏幕的垂直距離形成的z軸,這個z軸當然只是偽裝的,事實上人和屏幕距離就是那么遠,但是為了偽裝,我們讓離我們近的看起來大點,遠的看起來小點。就是傳說中的近大遠小,也叫作透視。

 

  現實生活中我們一般沒有仔細體驗過一種感覺,就是離一個東西越來越遠,看它越來越小,慢慢的就會達到一個極限值,此時看東西會變成一個點。加入過一個半徑為1的小球,在向后遠離1000個單位時,剛好看不到了,我們就假設有一個透視值perspective = 1000 ; 敲代碼之前的廢話就這么多了,現在我們開始寫我們的三維canvas 。

准備工作:

1. 有一個畫布供我們玩耍

<body>
    <canvas width='1000' height='500' id='3d-canvas' ></canvas>
</body>
// 生產一個畫布
var canvas = document.getElementById('3d-canvas');
panel = canvas.getContext('2d');
// 一個畫布上畫小球的工具
function drawBall(x,y,r,color){
    var color = color ? color : '#333' ;
    panel.beginPath()
    panel.arc(x,y,r,0,Math.PI*2);
    panel.closePath()
    panel.fillStyle = color ;
    panel.fill()
}

 

2. 然后要有一個透視,讓我們產生3d視覺效果,一個生產小球的機器,我們一般情況會已知小球的x, y, z坐標和他的大小就是半徑r。根據這些條件我們去畫小球。

var perspective = 1000
// 一個小球的構造函數,可以生產小球
function Ball(x,y,z,r){
    this.x = x ;
    this.y = y ;
    this.z = z ;
    this.r = r ;
    this.render = function(){
        // 根據
    }
}

 

3.最后我們new一個小球,然后渲染出來

// 生產一個小球,然后渲染
var small_ball = new Ball(300,300,1000,20)
small_ball.render()

 

好了,現在我們就渲染好了,畫出來了。本篇博客到此結束啦

 

咳咳,好了不開玩笑了,現在我們把任務范圍縮小了一下,已知透視值,x,y,z,r畫一個小球。就是render方法

最簡單的透視計算方法。

perspective=0 => scale=0
perspective=1000 => scale=1

 

這是透視值和比例大小的關系,所以我們就可以得出一個

var scale = this.z/perspective ;
var r = this.r*scale ;

 

然后我們計算實際視覺上的x和y的坐標

 

    var x = (this.x-w/2)*scale + w/2
    var y = (this.y-h/2)*scale + h/2    

 

這個x, y 是什么意思嘛,就是當scale放大一倍的時候,x會相對原來相對相對中線的位置放大scale倍。

現在我們就可以這樣寫render函數

function Ball(x,y,z,r){
    this.x = x ;
    this.y = y ;
    this.z = z ;
    this.r = r ;
    
    this.render = function(){
        var scale = this.z/perspective 
        var r = this.r*scale 
        var x = (this.x-w/2)*scale + w/2
        var y = (this.y-h/2)*scale + h/2
        drawBall(x,y,r)
    }
}

 現在完成了所有的配置項。就可以構造一個視覺上的3d小球了。

 

最后貼一個效果圖

https://sowhitesocoll.github.io/text-proticle/drawtext.html

這個demo種運用了tween.js算法和canvas得getImageData方法,和上邊所謂得3d效果技巧。喜歡的同志們可以點個小星星


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM