When I saw the login page of the bear in the Nuggets, many people liked it, so I shamelessly said that I would use canvas to implement it again. I really set a flag for myself, but the result was bad.
Dear viewers, this may be the most bleak demo you have ever seen. I hope you don't dislike it.
First look at other people's renderings
to think- Why does the little bear move with the input of the input box.
- Why do bear ears move to the front
- What is the movement pattern of the bear
Make some logical thinking and exclusion
2d- 3d
- Determine the focus coordinates of the text box, so as to provide data support for the bear's rotation and other actions
A vector class that implements 3d
var eyeLength = 250, centerX = 200/ 2, centerY = 200 / 2;
//设定视距,中心点的坐标
function Vector3(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
this._get2d = function() {
//将空间左边进行缩放后生成平面视图中的坐标
var scale = eyeLength / (eyeLength + this.z);
var x = centerX + this.x * scale;
var y = centerY + this.y * scale;
return { x: x,
y: y };
}
}
Rotate an object in space
function rotateX(vec3,angleX) {
var cos = Math.cos(angleX);
var sin = Math.sin(angleX);
var y1 = vec3.y * cos - vec3.z * sin;
var z1 = vec3.z * cos + vec3.y * sin;
vec3.y = y1;
vec3.z = z1;
}
function rotateY(vec3,angleY) {
var cos = Math.cos(angleY);
var sin = Math.sin(angleY);
var x1 = vec3.x * cos - vec3.z * sin;
var z1 = vec3.z * cos + vec3.x * sin;
vec3.x = x1;
vec3.z = z1;
}
By inputting the vector and angle value, the calculation is performed to generate the coordinates after the coordinates are rotated in space. The calculation formula used here is the rotation matrix, and the matrix is not separated into a separate class.
shape class
If you have read the previous 2d vector explanation, you will know that when we use vectors to process, we need to process each vector point, so we can't directly use such fillRect
methods. Here I use Bezier curves to draw graphics.
function shape(option) {
this.points=[];
this.site=new Vector3(0,0,0);
this.create(option);
this.face=[];
this.ctx={};
}
shape.prototype.render = function(ctx) {
this.ctx=ctx;
for(let f =0;f<this.paths.length;f++){
this.face[f]=new Face(this.ctx,this.color,...this.paths[f]);
}
this.face.sort(function(a,b){
return a-b;
})
this.face.forEach( function(face, index) {
face.draw(ctx);
});
}
We generate a surface by capturing the vector in the paths, and then use the surface to form an object, and rearrange the surface in the same shape, so that the surface is z(深度)
rendered according to the drawing, resulting in the effect of occlusion.
This way we will be able to create the shape as follows
var face=new shape({
paths:[[new Vector3(-50,0,4),new Vector3(-50,-70,4),new Vector3(50,-70,4),new Vector3(50,0,4)]],
color:"#3366C"
})
var eyes=new shape({
paths:[[new Vector3(-54,0,6),new Vector3(-54,-8,6),new Vector3(-46,-4,6),new Vector3(-46,0,6)],
[new Vector3(-54,0,6),new Vector3(-54,8,6),new Vector3(-46,4,6),new Vector3(-46,0,6)]],
color:"white"
})
The quickest way to do this kind of drawing is to draw coordinates on paper first, and then implement it in code.
After implementing the drawing and transformation, the next step is to interact. Here I use vue to write the page, which is calculated by monitoring the text length of the input box, (text length * font size) + left margin = focus coordinate.
var vm=new Vue({
el:'#bod',
data:{
username:"",//记录输入框
left:0,//距离左边的长度,用于判断旋转何时结束
len:0,//焦点坐标
pos:0,//是否开始选择
dir:'left'//旋转的方向
},
computed:{
//计算文本长度
roate:function (argument) {
this.len=this.username.length;
}
},
watch:{
//监听len的值,判断是增还是减
len:function(o,n){
this.pos=1;
if(n<o){
this.dir='right';
}else {
this.dir='left'
}
}
}
})
Then we can hand everything over to the browser
function anima(){
if(vm.pos===1){//如果可以旋转
if(vm.left<r){//如果长度不够,继续旋转
ctx.clearRect(0,0,200,200);
switch (vm.dir) {//判断方向
case 'right':
face.rotate(0,r);
eyes.rotate(0,r);
face.render(ctx);
eyes.render(ctx);
vm.left+=r/5;
break;
case 'left':
face.rotate(0,-r);
eyes.rotate(0,-r);
face.render(ctx);
eyes.render(ctx);
vm.left+=r/5;
break;
}
}else{//长度达到后则重置数据
vm.left=0;
vm.pos=0;
}
}
requestAnimationFrame(anima)
}
anima();
insufficient
- The painting is a bit ugly, it is not very clear to have that feeling
- Only depth rendering is performed for a single object, and spatial depth rendering is not implemented
- The functions of vectors and shapes are not perfect, making the effect very limited
Summarize
In fact, this thing is not easy to do. When I used PS or AE for animation, I only thought about how to beautify the effect. After I realized it, I felt that the group of people in the graphics engine was really awesome. From the beginning, I planned to make it simple. , It took nearly half a day, and I pushed down a lot of ideas in the middle, and then I sorted it out. Although the final effect is not very good, I still shamelessly hope that I can tempt some big guys to join the canvas team and write interesting stories together. thing.
The related technical tutorials of canvas and svg are updated from time to time, including actual combat type and main principle type. 2d, 2.5d and 3d will be included, and the basic knowledge of linear algebra, physical graphics, etc. will be involved.
Welcome guests to collect and pay attention to coin tossing