オフスクリーン キャンバスを使用して Prezi のようなページ遷移アニメーション効果を作成する

オフスクリーン キャンバスを使用して Web サイト ページの特殊効果を作成し、Prezi トランジション効果を模倣します。

最初の画面エフェクト
ホームアニメーションの円形拡散効果
ページ切り替えトランジションエフェクト
いずれかのタイトルをクリックすると、トランジション アニメーションが開始されます。
ここに画像の説明を挿入します
 

・第一画面循環循環拡散効果

最初の画面エフェクトの難しさは、円形の円拡散アニメーションとベジェ曲線の描画にあります。円が徐々に広がっていくアニメーションを作成するのは難しいことではありませんが、円を徐々に透明にしてカスケード効果を生み出すことが鍵となります。 context.globalCompositeOperationプロパティを使用します

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

destination-in属性値の目的は、後から描画する新しい絵(ソース画像)を透明にして、古い絵と新しい絵の重なっている部分だけを表示することです。という意味で、その面積が 100% を占め、直前の古い写真しか見られないような効果を生み出すことができます。

ctx.fillRect(0,0,WINDOW_WIDTH,WINDOW_WIDTH); この無意味な四角形は、いわゆる新しいピクチャとして機能します。

新しい円を描画する前に、プロパティ値を次のように変更します。

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

これにより、新しいイメージと古いイメージを共存させることができます。したがって、円拡大過程や最大到達後に残像効果が生じるのは、常に直前の古い画像が見えるためである。

この効果を実現するもう 1 つの鍵は、グローバル透明度ctx.globalAlpha = 0.95を設定することです。透明度を 1 にすることはできません。そうしないと、画像が実線の円になります。

初期化関数 render() コードは次のとおりです。

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);
};

 

・ベジェ曲線軌跡アニメーション

2次ベジェ曲線を描画する際に難しいのは、動作の軌跡をセグメントに分割して描画する方法ですが、ここではcanvasが提供するメソッド、つまりctx.quadraticCurveToの描画原理を理解する必要があります。
@hujiulong ブロガーの記事「キャンバスを使用して曲線アニメーションを描画する - ベジェ曲線の詳細な理解」を参照してください。ベジェ曲線の分割描画が非常に丁寧かつ丁寧に解説されていると言えます。将来的には、ShadowBlur などの影効果をカーブに追加する限り、さまざまなクールなスタイルを開発できます。

プログラム内で区分的にベジェ曲線を描画する方法は次のとおりです。

//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();
}

 

・イミテーションプレゼンテーションアーティファクトPreziトランジションアニメーション効果

プレゼンテーション ツール Prezi の最も優れた機能の 1 つは、その独特のトランジション スタイルです。すべてのコンテンツが同じページに書かれているように見えます。特定のコンテンツを選択すると、移動 - フォーカス - ルートに沿って移動します。増幅効果。

Prezi で最も一般的なモーション エフェクトである移動、回転、ズームは、キャンバスが提供する基本機能でもあります。

巨大なキャンバスにすべてのコンテンツを描画し、ルートに応じて移動および拡大縮小すると同様の効果が得られますが、キャンバスでは特定のコンテンツを拡大すると、鮮明さが低下するという問題があります。ドロップします盛り込む内容が多ければ多いほど、ぼやけやすくなります。

したがって、現時点では、複数のオフスクリーン キャンバスが相互に連携するように設計することで、この問題をうまく解決できます。

オフスクリーンキャンバス

オフスクリーン キャンバスでは、DOM 操作を行わずに画像を描画できます。非常に複雑なアニメーション効果や頻繁に変更する必要のないシーンを実行する場合、ページ レンダリングのパフォーマンスが向上し、ページの再描画や再描画がトリガーされなくなります。ユーザーエクスペリエンスを向上させるため。

この例では、メインのオフスクリーン キャンバスを使用して、ページ切り替え後のコンテンツを運び、動きの効果をデザインします。
mainOffcanvas、4 つのオフスクリーン キャンバスで構成されます。
ズームイン後もページの各部分が元の 100% の明瞭さを維持できるようにするために、幅 100% の 4 つの追加のオフスクリーン キャンバスを使用して、4 ページの特定のコンテンツをそれぞれ描画します。次に、これら 4 つのオフスクリーン キャンバスをメイン キャンバスの異なる位置に描画します。

コードに示すように: 1 つのメイン オフスクリーン キャンバス + 4 つのセカンダリ オフスクリーン キャンバス

//离屏画布初始状态
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);

次に、メインのオフスクリーン キャンバスは、対応するコンテンツを画面の中央に移動し、拡大します。拡大の結果、対応するコンテンツは、実際のセカンダリ オフスクリーン キャンバスが表示されたときに表示される効果とまったく同じである必要があります。 100%で描画されます。

ここに画像の説明を挿入します
該当部分を拡大すると、内容がぼやけていることがわかります。なぜなら、今私たちが見ているのはまだメインのオフスクリーンキャンバスのコンテンツだからです。

現時点では内容はまだ曖昧です
次に、セカンダリのオフスクリーン キャンバスを密かに透明なコンテンツに置き換え、メインのオフスクリーン キャンバスの代わりにページ上に描画する必要があります。置換操作を跡形もなく見せるためには、このときの対応するコンテンツの正確な位置座標を計算する必要があります。これは、図の赤枠の左上の頂点の座標値です。(メインのオフスクリーン キャンバスに最初に描画された座標に従って、プログラムの初期化の開始時に計算できます。)

キャンバスの置き換えが成功したら、メイン キャンバス上の座標が (0, 0) になるまで実際の 2 番目のオフスクリーン キャンバスを移動します。最終的に実際に表示されるのは、特定のコンテンツを明確に描画するオフスクリーン キャンバスです。

この時点ですでに明らかです
後で、特定のページにタグ リンクを追加し、メイン ディレクトリに戻り、同じズームと移動方法を使用して次のページにシームレスに切り替えることもできます。

オフスクリーン キャンバスの各部分は、デザインしたい豊かな効果を自由に表現できます。それらの接合が適切かつ規則的である限り、オフスクリーン キャンバスのさまざまなレベルの相互作用は、単純な座標計算によって実現でき、最終的にはよりクールな外観を演出します。

完全なコードのリンク:
https://github.com/yiran8080/git_demo/tree/master/canvas_transition

おすすめ

転載: blog.csdn.net/csdnyiiran/article/details/105081229