Use off-screen canvas to create Prezi-like page transition animation effects

Use off-screen canvas to create website page special effects and imitate Prezi transition effects

First screen effect
Home animation circular diffusion effect
page switching transition effect
Click on one of the titles to start the transition animation
Insert image description here
 

· First screen circular circulation diffusion effect

The difficulty of the first screen effect lies in the drawing of circular circular diffusion animation and Bezier curve. It is not difficult to animate a circle gradually expanding. The key lies in how to make the circle gradually become transparent to produce a cascading effect. The context.globalCompositeOperation property is used .

ctx.globalCompositeOperation = 'destination-in';
ctx.fillRect(0,0,WINDOW_WIDTH,WINDOW_WIDTH);

The purpose of the destination-in attribute value is to make the new picture (source image) drawn later transparent, and only show the overlapping part of the old picture and the new picture. If you draw a new picture behind it that has no practical meaning and accounts for 100% of the area, , you can create the effect that you can only see the old picture from the last moment.

ctx.fillRect(0,0,WINDOW_WIDTH,WINDOW_WIDTH); This meaningless rectangle serves as the so-called new picture.

Before drawing the new circle, change the property value to:

ctx.globalCompositeOperation = "source-over";;
move();//绘制圆形的方法

This allows new images to coexist with old images. Therefore, the reason why there is an afterimage effect during the circular expansion process and after reaching the maximum is because the old image of the previous moment can be seen at all times.

Another key to achieving this effect is to set the global transparency ctx.globalAlpha = 0.95 . The transparency cannot be 1, otherwise the picture will become a solid circle.

The initialization function render() code is as follows:

var render = function () {
    
    
    ctx.globalCompositeOperation = 'destination-in';
    ctx.fillRect(0,0,WINDOW_WIDTH,WINDOW_HEIGHT);
    ctx.globalCompositeOperation = "source-over";
    move();     //绘制圆形                            
    drawCurve(); //绘制轨道曲线
    render_log = window.requestAnimationFrame(render);
};

 

· Bezier curve trajectory animation

The difficulty in drawing a quadratic Bezier curve is how to draw the motion trajectory in segments. Here you need to understand the method provided by canvas - the drawing principle of ctx.quadraticCurveTo .
You can read @hujiulong blogger’s article: Use canvas to draw a curve animation—an in-depth understanding of Bezier curves . It can be said that the segmented drawing of Bezier curves is explained very carefully and thoroughly. In the future, as long as you add shadow effects such as shadowBlur to the curves, you can develop a variety of cool styles.

The following is the method for drawing Bezier curves piecewise in the program:

//start:起点向量,end:终点向量,
//curv:由用户决定的曲线曲度(0,1)
//percent:每一时刻曲线绘制的百分比
function drawCurvePath(start,end,curv,percent){
    
    

    let t = percent/100;
     //利用曲线曲度计算二次贝塞尔曲线上的控制点point
    let point = [
        ( start[ 0 ] + end[ 0 ] ) / 2 - ( start[ 1 ] - end[ 1 ] ) * curv,
        ( start[ 1 ] + end[ 1 ] ) / 2 - ( end[ 0 ] - start[ 0 ] ) * curv
    ];
    let p0 = start;
    let p1 = point;
    let p2 = end;
    let v01 = [p1[0]-p0[0],p1[1]-p0[1]]; //p0p1向量
    let v12 = [p2[0]-p1[0],p2[1]-p1[1]]; //p1p2向量
    //求p0p1上的点Q0
    let q0 = [p0[0]+v01[0]*t,p0[1]+v01[1]*t];
    //求p1p2上的点Q1
    let q1 = [p1[0]+v12[0]*t, p1[1]+v12[1]*t];
    //求向量Q0Q1
    let v = [q1[0]-q0[0],q1[1]-q0[1]];
    //求向量Q0Q1与贝塞尔曲线的交点B,即当前曲线段的终点
    let b = [q0[0] +v[0]*t, q0[1]+v[1]*t ];

    //路径发光特效,只让路径发光,不影响其他图案,加save()restore()方法
    ctx.save();
    ctx.beginPath();
    ctx.shadowColor = '#FFF';
    ctx.shadowBlur = 3;
    ctx.moveTo(start[0],start[1]);//起始点坐标
    ctx.quadraticCurveTo(q0[0],q0[1],b[0],b[1]);

   //路径上的发光小圆球特效
    ctx.lineWidth = 0.5;
    ctx.strokeStyle = '#FFF';
    ctx.stroke();

    ctx.beginPath();
    ctx.fillStyle = "rgba(255,255,255,0.8)";
    ctx.arc(b[0],b[1],4,0,Math.PI*2);
    ctx.fill();
    ctx.restore();
    ctx.closePath();
}

 

·Imitation presentation artifact Prezi transition animation effect

One of the most outstanding features of Prezi, a presentation tool, should be its unique transition style: it seems that all the content is written on the same page. Selecting specific content will move - focus - and then move along a route . Amplification effect.

The most common motion effects in Prezi - translation, rotation, and zoom are also the basic functions provided by canvas.

If all the content is drawn on a huge canvas, and then moved and scaled according to the route, a similar effect can be achieved. However, the problem encountered by canvas is that after the specific content is enlarged, the clarity will also decrease . drop . The more content you put in, the easier it becomes to blur.

So at this time, designing multiple off-screen canvases to cooperate with each other can solve this problem well.

Off-screen canvas

Off-screen canvas can draw the picture without going through DOM operation. When doing some very complex animation effects or scenes that do not need to be changed frequently, it can improve the performance of page rendering and will not trigger page redrawing or redrawing. row to improve user experience.

In this example, a main off-screen canvas is used to carry the content after page switching and design the movement effect.
mainOffcanvas, composed of four off-screen canvases
In order to ensure that each part of the page can maintain its original 100% clarity after zooming in, four additional off-screen canvases with a width of 100% are used to draw the specific content of the four pages respectively. Then draw these four off-screen canvases in different positions of the main canvas.

As shown in the code: one main off-screen canvas + four secondary off-screen canvases

//离屏画布初始状态
var mainOffCanvas = document.getElementById('mainOffCanvas');
var ctx_main = mainOffCanvas.getContext('2d');

var offCanvas1 = document.getElementById('offCanvas1');
var ctx1 = offCanvas1.getContext('2d');

var offCanvas2 = document.getElementById('offCanvas2');
var ctx2 = offCanvas2.getContext('2d');

var offCanvas3 = document.getElementById('offCanvas3');
var ctx3 = offCanvas3.getContext('2d');

var offCanvas4 = document.getElementById('offCanvas4');
var ctx4 = offCanvas4.getContext('2d');
ctx_main.drawImage(offCanvas1,0,0,WINDOW_WIDTH,WINDOW_HEIGHT,20,20,WINDOW_WIDTH/2,WINDOW_HEIGHT/2);
ctx_main.drawImage(offCanvas2,0,0,WINDOW_WIDTH,WINDOW_HEIGHT,600,20,WINDOW_WIDTH/2,WINDOW_HEIGHT/2);
ctx_main.drawImage(offCanvas3,0,0,WINDOW_WIDTH,WINDOW_HEIGHT,20,300,WINDOW_WIDTH/2,WINDOW_HEIGHT/2);
ctx_main.drawImage(offCanvas4,0,0,WINDOW_WIDTH,WINDOW_HEIGHT,600,300,WINDOW_WIDTH/2,WINDOW_HEIGHT/2);

Next, the main off-screen canvas begins to move the corresponding content to the center of the screen and enlarges it. The result of the enlargement requires that the corresponding content should be exactly the effect that appears when the real secondary off-screen canvas is drawn at 100%.

Insert image description here
After the corresponding part is enlarged, you will find that the content has become blurred. Because what we see now is still the content of the main off-screen canvas.

The content is still blurry at this time
Next, what we need to do is to secretly replace the secondary off-screen canvas with clear content and draw it on the page instead of the main off-screen canvas. In order to make the replacement operation look traceless, it is necessary to calculate the accurate position coordinates of the corresponding content at this time, which is the coordinate value of the upper left vertex of the red box in the picture. (According to the coordinates initially drawn on the main off-screen canvas, it can be calculated at the beginning of the program initialization.)

After successfully replacing the canvas, move the real secondary off-screen canvas until the coordinates on the main canvas are (0, 0). In the end, what we really see is the off-screen canvas that clearly draws the specific content.

It is already clear at this point
Later, you can also add tag links to specific pages, return to the main directory, and use the same zoom + move method to seamlessly switch to the next page.

Each piece of off-screen canvas can present the rich effects you want to design at will. As long as their splicing is neat and regular, then the interaction of different levels of off-screen canvas can be achieved through simple coordinate calculations, and ultimately a cooler appearance will be presented. Stunning visual effects.

Full code link:
https://github.com/yiran8080/git_demo/tree/master/canvas_transition

Guess you like

Origin blog.csdn.net/csdnyiiran/article/details/105081229