canvas用2d渲染出3d的感觉
好久沒(méi)有寫博客了,深究動(dòng)畫其實(shí)也就是setTimeout setInterval requestAnimationFrame很多人可能不熟悉requestAnimationFrame但是事實(shí)上和setTimeout沒(méi)有區(qū)別,setTImeout是 通過(guò)定時(shí)然后達(dá)到循環(huán)執(zhí)行,后者呢比較優(yōu)雅,動(dòng)畫幀。。。不說(shuō)了,我也不知道,自己測(cè)試一下,程序員是應(yīng)該有這種一探究竟的精神。
在實(shí)際數(shù)據(jù)中很可能是沒(méi)有perspeactive 3d,也沒(méi)有transition-z的。但是三維的東西其實(shí)也就是在電腦屏幕上而已,屏幕沒(méi)有厚多少多少的說(shuō)法吧,所以呢,事實(shí)上在屏幕上看到的其實(shí)也不過(guò)是畫在一張二維屏幕上的視覺(jué)效果圖而已。
先說(shuō)一個(gè)最基本的知識(shí),俗話說(shuō)的transition3d的3d是關(guān)于屏幕的水平方向和豎直方向,還有一個(gè)是人和屏幕的垂直距離形成的z軸,這個(gè)z軸當(dāng)然只是偽裝的,事實(shí)上人和屏幕距離就是那么遠(yuǎn),但是為了偽裝,我們讓離我們近的看起來(lái)大點(diǎn),遠(yuǎn)的看起來(lái)小點(diǎn)。就是傳說(shuō)中的近大遠(yuǎn)小,也叫作透視。
?
現(xiàn)實(shí)生活中我們一般沒(méi)有仔細(xì)體驗(yàn)過(guò)一種感覺(jué),就是離一個(gè)東西越來(lái)越遠(yuǎn),看它越來(lái)越小,慢慢的就會(huì)達(dá)到一個(gè)極限值,此時(shí)看東西會(huì)變成一個(gè)點(diǎn)。加入過(guò)一個(gè)半徑為1的小球,在向后遠(yuǎn)離1000個(gè)單位時(shí),剛好看不到了,我們就假設(shè)有一個(gè)透視值perspective = 1000 ; 敲代碼之前的廢話就這么多了,現(xiàn)在我們開始寫我們的三維canvas 。
準(zhǔn)備工作:
1. 有一個(gè)畫布供我們玩耍
<body><canvas width='1000' height='500' id='3d-canvas' ></canvas> </body> // 生產(chǎn)一個(gè)畫布 var canvas = document.getElementById('3d-canvas'); panel = canvas.getContext('2d'); // 一個(gè)畫布上畫小球的工具 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. 然后要有一個(gè)透視,讓我們產(chǎn)生3d視覺(jué)效果,一個(gè)生產(chǎn)小球的機(jī)器,我們一般情況會(huì)已知小球的x, y, z坐標(biāo)和他的大小就是半徑r。根據(jù)這些條件我們?nèi)ギ嬓∏颉?/p> var perspective = 1000 // 一個(gè)小球的構(gòu)造函數(shù),可以生產(chǎn)小球 function Ball(x,y,z,r){this.x = x ;this.y = y ;this.z = z ;this.r = r ;this.render = function(){// 根據(jù) } }
?
3.最后我們new一個(gè)小球,然后渲染出來(lái)
// 生產(chǎn)一個(gè)小球,然后渲染 var small_ball = new Ball(300,300,1000,20) small_ball.render()?
好了,現(xiàn)在我們就渲染好了,畫出來(lái)了。本篇博客到此結(jié)束啦
?
咳咳,好了不開玩笑了,現(xiàn)在我們把任務(wù)范圍縮小了一下,已知透視值,x,y,z,r畫一個(gè)小球。就是render方法
最簡(jiǎn)單的透視計(jì)算方法。
perspective=0 => scale=0 perspective=1000 => scale=1?
這是透視值和比例大小的關(guān)系,所以我們就可以得出一個(gè)
var scale = this.z/perspective ; var r = this.r*scale ;?
然后我們計(jì)算實(shí)際視覺(jué)上的x和y的坐標(biāo)
?
var x = (this.x-w/2)*scale + w/2var y = (this.y-h/2)*scale + h/2?
這個(gè)x, y 是什么意思嘛,就是當(dāng)scale放大一倍的時(shí)候,x會(huì)相對(duì)原來(lái)相對(duì)相對(duì)中線的位置放大scale倍。
現(xiàn)在我們就可以這樣寫render函數(shù)
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/2var y = (this.y-h/2)*scale + h/2drawBall(x,y,r)} }?現(xiàn)在完成了所有的配置項(xiàng)。就可以構(gòu)造一個(gè)視覺(jué)上的3d小球了。
?
最后貼一個(gè)效果圖
https://sowhitesocoll.github.io/text-proticle/drawtext.html
這個(gè)demo種運(yùn)用了tween.js算法和canvas得getImageData方法,和上邊所謂得3d效果技巧。喜歡的同志們可以點(diǎn)個(gè)小星星
轉(zhuǎn)載于:https://www.cnblogs.com/sowhite/p/6706805.html
總結(jié)
以上是生活随笔為你收集整理的canvas用2d渲染出3d的感觉的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Kubernetes 1.6新特性
- 下一篇: 反手发力动作--乒在民间