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

摘要:
在实际数据中很可能是没有perspeactive3d,也没有transition-z的。准备工作:1.有一个画布供我们玩耍//生产一个画布varcanvas=document.getElementById;panel=canvas.getContext;//一个画布上画小球的工具functiondrawBall{varcolor=color?varperspective=1000//一个小球的构造函数,可以生产小球functionBall{this.x=x;this.y=y;this.z=z;this.r=r;this.render=function(){//根据}}3.最后我们new一个小球,然后渲染出来//生产一个小球,然后渲染varsmall_ball=newBallsmall_ball.render()好了,现在我们就渲染好了,画出来了。就是render方法最简单的透视计算方法。现在我们就可以这样写render函数functionBall{this.x=x;this.y=y;this.z=z;this.r=r;this.render=function(){varscale=this.z/perspectivevarr=this.r*scalevarx=*scale+w/2vary=*scale+h/2drawBall}}现在完成了所有的配置项。

好久没有写博客了,深究动画其实也就是setTimeout setInterval requestAnimationFrame很多人可能不熟悉requestAnimationFrame但是事实上和setTimeout没有区别,setTImeout是 通过定时然后达到循环执行,后者呢比较优雅,动画帧。。。不说了,我也不知道,自己测试一下,程序员是应该有这种一探究竟的精神。

在实际数据中很可能是没有perspeactive 3d,也没有transition-z的。但是三维的东西其实也就是在电脑屏幕上而已,屏幕没有厚多少多少的说法吧,所以呢,事实上在屏幕上看到的其实也不过是画在一张二维屏幕上的视觉效果图而已。

先说一个最基本的知识,俗话说的transition3d的3d是关于屏幕的水平方向和竖直方向,还有一个是人和屏幕的垂直距离形成的z轴,这个z轴当然只是伪装的,事实上人和屏幕距离就是那么远,但是为了伪装,我们让离我们近的看起来大点,远的看起来小点。就是传说中的近大远小,也叫作透视。

现实生活中我们一般没有仔细体验过一种感觉,就是离一个东西越来越远,看它越来越小,慢慢的就会达到一个极限值,此时看东西会变成一个点。加入过一个半径为1的小球,在向后远离1000个单位时,刚好看不到了,我们就假设有一个透视值perspective = 1000 ; 敲代码之前的废话就这么多了,现在我们开始写我们的三维canvas 。

准备工作:

1. 有一个画布供我们玩耍

<body>
    <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=0perspective=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/2drawBall(x,y,r)
    }
}

现在完成了所有的配置项。就可以构造一个视觉上的3d小球了。

最后贴一个效果图

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

这个demo种运用了tween.js算法和canvas得getImageData方法,和上边所谓得3d效果技巧。喜欢的同志们可以点个小星星

免责声明:文章转载自《canvas用2d渲染出3d的感觉》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Kalman Filter算法详解如何在Ubuntu 20.04 LTS上安装Dotnet Core?下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

html5与EmguCV前后端实现——人脸识别篇(一)

  上个月因为出差的关系,断更了很久,为了补偿大家长久的等待,送上一个新的系列,之前几个系列也会抽空继续更新。   大概半年多前吧,因为工作需要,我开始研究图像识别技术。OpenCV在这方面已经有了很多技术积累,在html5领域也很早就有了这方面的Demo。但是一番学习下来,我发现基本上这方面的文章大都比较零散片面,而且很多关键的代码可能已经老化不能正常使...

input框输入金额处理的解决办法

最近已经上线的项目突然出现了input输入金额删除时出现问题,网上各种搜索都没有搜到想要的,今天就以react框架为例子进行代码奉献,我会把需求及解决方法写出来,希望对朋友们有用。 如有更好地实现方式欢迎指点! 一、需求 1、只允许输入数字 2、只允许输入一个小数点,且小数点只能有一个,后面最多可输两位小数 3、金额转成大写 4、控制金额输入的位数 二、实...

SVN图形管理工具-Submint

1.安装svn及相关依赖包 yum install subversion httpd mod_dav_svn apr-util-sqlite   2.下载submin wget https://supermind.nl/submin/current/submin-2.2.2-1.tar.gz tar zxvf submin-2.2.2-1.tar.g...

权值初始化

设计好神经网络结构以及loss function 后,训练神经网络的步骤如下: 初始化权值参数 选择一个合适的梯度下降算法(例如:Adam,RMSprop等) 重复下面的迭代过程: 输入的正向传播 计算loss function 的值 反向传播,计算loss function 相对于权值参数的梯度值 根据选择的梯度下降算法,使用梯度值更新每个权值参数...

startUML破解方式

StarUML官方下载地址:http://staruml.io/download StarUML是一个非常好用的画UML图的工具,但是它是收费软件​,以下是破解方法: ​1.使用Editplus或者Notepad++等特殊的文本编辑器打开%StarUML_HOME%/www/license/node/LicenseManagerDomain.js文件 2....

golang解析json配置文件

安装 go get github.com/akkuman/parseConfig 使用说明 环境假设 . ├── config.go ├── config.json config.json内容 { "name" : "akkuman", "urls" : ["xx.com","ww.com"], "info" : {...