When I saw the cubs’ login page in Denver, many people liked it very much, so I shamelenly said that I would use canvas to implement it again, which really set a flag for myself. Fortunately, the result was terrible.
Ladies and gentlemen, this is probably the worst demo you’ve ever seen, so I hope you don’t mind
Start by looking at other people’s renderings
To think
- Why the bear will follow the input box to move.
- Why do bear’s ears move forward
- What is the movement pattern of the bear
Do some logical thinking and elimination
2d- 3d
- Judge the focus coordinates of the text box, so as to support the data of the bear rotation and other actions
Implement 3d vector classes
var eyeLength = 250, centerX = 200/ 2, centerY = 200 / 2;
// Set the visual distance and the coordinates of the center point
function Vector3(x, y, z) {
this.x = x;
this.y = y;
this.z = z;
this._get2d = function() {
// Scale the left side of the space to generate coordinates in the plane view
var scale = eyeLength / (eyeLength + this.z);
var x = centerX + this.x * scale;
var y = centerY + this.y * scale;
return { x: x,
y: y }; }}Copy the code
Rotate objects 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;
}
Copy the code
Through the input vector and Angle value, the calculation is carried out to generate the coordinate after the coordinate is rotated in space. The calculation formula used here is the rotation matrix, and the matrix is not separated into a separate class.
The shape of the class
And if you saw in the last 2d vector presentation, when you’re dealing with vectors, you’re dealing with each vector point, so you can’t just do something like fillRect, and I’m using a Bates curve to draw it.
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);
});
}
Copy the code
We capture the vectors in paths to generate a face, and then form the object by the face, and rearrange the faces in the same shape so that the faces can be rendered according to Z (depth) when drawing, so as to produce the effect of occlusion.
We will then be able to create shapes 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"
})
Copy the code
After rendering and transformation, the next step is to interact, here I use vUE to write the page, by listening to the input box text length, (text length * font size) + left margin = focus coordinates.
var vm=new Vue({
el:'#bod'.data: {username:"".// Record input box
left:0.// The distance to the left is used to determine when the rotation ends
len:0.// Focus coordinates
pos:0.// Whether to start the selection
dir:'left'// Direction of rotation
},
computed: {// Calculate the length of the text
roate:function (argument) {
this.len=this.username.length; }},watch: {// Listen for len to increase or decrease
len:function(o,n){
this.pos=1;
if(n<o){
this.dir='right';
}else {
this.dir='left'}}}})Copy the code
Then we can turn everything over to the browser
function anima(){
if(vm.pos===1) {// If you can rotate
if(vm.left<r){// If the length is not enough, continue to rotate
ctx.clearRect(0.0.200.200);
switch (vm.dir) {// Determine the direction
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{// Reset the data when the length is reached
vm.left=0;
vm.pos=0;
}
}
requestAnimationFrame(anima)
}
anima();
Copy the code
insufficient
- The painting is a little ugly, not very clear to have that feeling
- Only a single object was rendered in depth, but the rendering of spatial depth was not realized
- The function of vector and shape is not perfect, so the effect is very limited
The source code
conclusion
In fact this is a rather bad things to do, do with PS or AE dynamic effect before, only think about how to beautification effect, the implement before really kick-ass graphics engine that group of people, from start to do simple implementation, it took nearly half a day, down among a lot of ideas, and then to arrange, although the final effect is not good, but, I’m still shameless and hope I can lure some big shots to join the canvas team and write interesting stuff together.
The related technical tutorials of Canvas and SVG will be updated from time to time. There will be practical ones, master principles ones, 2D 2.5D 3D ones, and linear algebra, physical graphics and other related basic knowledge will be involved.
Welcome guests to pay attention to the coin collection