ここで説明する「キーストーン」テクニックを使用して、html5 キャンバスを使用した「ハード カバー」の本のページにパースペクティブを追加しました。
基本的に起こることは、イメージ/キャンバス要素がソース テクスチャとして定義されることです。各レンダー ループ中に、これは定義された幅のセグメントに分割され (1 ピクセルが最高品質)、各セグメントの高さは、テクスチャの X 軸上の位置に応じてスケーリングされます。
これにより、以下に示すように、特定のソース イメージ/テクスチャで適切な遠近法の錯覚が作成されます。
これは、「ハード カバー」のページめくりでは問題なく機能し、含まれるテキストと一緒にテクスチャが素晴らしい印象を与えます。ただし、同じ種類のキーストーンを「ソフト」なページめくりに適用する必要があります。問題は、以下に示すように、ページ自体が曲線で定義されているため、単純な透視変換が機能しないことです。
現在、ページ テクスチャは、画像/テクスチャをクリップするように設定されたページ エッジ二次曲線パスを使用して、ページめくりの任意の時点で曲線の最大高さにスケーリングされます。さまざまな標準キャンバス関数を使用して影とページ ラインを動的に描画するので、ページ ライン (2 次曲線で描画) がページめくりに自然な遠近感を提供するため、これは許容できるように見えます。
ただし、テキスト自体 (別のキャッシュされたキャンバス/画像要素から取得されたもの) は見栄えがよくなく、常に完全にフラットなままです。
私がやりたいことは、上記と同じスライシング/セグメンテーション/スケーリング キーストーン テクニックを何らかの形で適用することctx.quadraticCurveTo();
です。
私の例の画像では、実際にはそれほど悪くはありませんが、テキストがページの上部/下部に近づくと、ワープ効果はもちろん大きくなります. それだけでなく、ページの折り目に最も近いテキストを押しつぶすために、水平方向の倍率も計算する必要があります。
残念ながら、サンプルコードを提供する立場にはありません。しかし、基本的には、上記のリンクで説明されているキーストーン処理と非常によく似た方法で行っています。要約すると、二次曲線の座標/値を使用して、以下に示すスライス/レンダリング関数の各セグメントのスケール係数を計算できるようにする必要があります。
function keystoneAndDisplayImage(ctx, img, x, y, pixelWidth, scalingFactor) {
var h = img.height,
w = img.width,
// The number of slices to draw.
numSlices = Math.abs(pixelWidth),
// The width of each source slice.
sliceWidth = w / numSlices,
// Whether to draw the slices in reverse order or not.
polarity = (pixelWidth > 0) ? 1 : -1,
// How much should we scale the width of the slice
// before drawing?
widthScale = Math.abs(pixelWidth) / w,
// How much should we scale the height of the slice
// before drawing?
heightScale = (1 - scalingFactor) / numSlices;
for(var n = 0; n < numSlices; n++) {
// Source: where to take the slice from.
var sx = sliceWidth * n,
sy = 0,
sWidth = sliceWidth,
sHeight = h;
// Destination: where to draw the slice to
// (the transformation happens here).
var dx = x + (sliceWidth * n * widthScale * polarity),
dy = y + ((h * heightScale * n) / 2),
dWidth = sliceWidth * widthScale,
dHeight = h * (1 - (heightScale * n));
ctx.drawImage(img, sx, sy, sWidth, sHeight,
dx, dy, dWidth, dHeight);
}
}
...しかし、どこから始めればよいか本当にわかりません。どんな助けでも大歓迎です。
編集:
私が達成したいことについてもう少し考えてみたところ、この方法で 3D テクスチャ マッピングを完全に表現することは、要求するには多すぎるかもしれないことに気付きました。したがって、html5キャンバスで定義された二次曲線に基づいて、各セグメントの高さスケールとy位置を簡単に変更できる回答に満足しています。
より良い例の画像を次に示します。
ご覧のとおり、ページめくりに自然に追従するために、曲線係数とその y 位置によって 1 ピクセル幅のセグメントを計算する必要がある場合、大きなテキストは、キーストーン化されていない単一の画像テクスチャで完全にまっすぐになります。この場合、半現実的な遠近効果を達成するための他の「ハック」または方法に失敗すると、非常に役立ちます。