キャンバスの描画は、contain または cover モードで適応され、中央に配置されます。
2022-01-31 17:01:34
キャンバス描画のdrawImageは、異なる画像サイズとスケールを必要とするので、html+cssのレイアウトと同様に、異なるニーズに合わせてcontain and coverする必要があります。
含む
画像の長辺が完全に表示されるように、アスペクト比を維持したまま拡大縮小します。つまり、画像の全体が表示できるようにします。
コンテインモードで画像を固定ボックスの矩形内に配置する場合、画像の多少の拡大縮小が必要です。
その原理は
画像の長辺が完全に表示できるように幅と高さが不揃いな場合、画像の高辺が固定ボックスに対応する辺と等しくなるように元画像を拡大縮小し、他の辺を等比級数で求めます
画像の幅と高さが等しい場合、固定ボックスの幅と高さで拡大縮小画像の幅と高さが決まり、固定ボックスの幅が高さより大きい場合、拡大縮小画像は固定ボックスの高さより高くなり、もう片方は比例します。
/**
* @param {Number} sx fixes the x coordinate of the box, sy fixes the y left scale of the box
* @param {Number} box_w the width of the fixed box, box_h the height of the fixed box
* @param {Number} source_w the width of the original image, source_h the height of the original image
* @return {Object} {drawImage's parameters, x coordinate, y coordinate, width and height of the scaled image}, corresponding to drawImage(imageResource, dx, dy, dWidth, dHeight)
*/
function containImg(sx, sy , box_w, box_h, source_w, source_h){
var dx = sx,
dy = sy,
dWidth = box_w,
dHeight = box_h;
if(source_w > source_h || (source_w == source_h && box_w < box_h)){
dHeight = source_h*dWidth/source_w;
dy = sy + (box_h-dHeight)/2;
}else if(source_w < source_h || (source_w == source_h && box_w > box_h)){
dWidth = source_w*dHeight/source_h;
dx = sx + (box_w-dWidth)/2;
}
return{
dx,
dy,
dWidth,
dHeight
}
}
var c=document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = '#e1f0ff';
// fix the position and size of the box - the image needs to be placed inside this box
ctx.fillRect(30, 30, 150, 200);
var img = new Image();
img.onload = function () {
console.log(img.width,img.height);
var imgRect = containImg(30,30,150,200,img.width,img.height);
console.log('imgRect',imgRect);
ctx.drawImage(img, imgRect.dx, imgRect.dy, imgRect.dWidth, imgRect.dHeight);
}
img.src = ". /timg2.jpg";
//Note: In img preload mode, onload should be placed above the value assigned to src to avoid the situation where the onload event cannot be triggered if there is already a cache and the event in onload is not executed
カバー
画像をアスペクト比で拡大縮小しておくと、画像の短辺だけが完全に表示されることになります。つまり、通常、画像は水平方向または垂直方向にのみ完全であり、それ以外の方向では傍受が発生します。
原理を説明します。
画像の一部を固定ボックスの縮尺で取り込む
/**
* @param {Number} box_w width of the fixed box, box_h height of the fixed box
* @param {Number} source_w the width of the original image, source_h the height of the original image
* @return {Object} {the intercepted image information}, corresponding to drawImage(imageResource, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) parameter
*/
function coverImg(box_w, box_h, source_w, source_h){
var sx = 0,
sy = 0,
sWidth = source_w,
sHeight = source_h;
if(source_w > source_h || (source_w == source_h && box_w < box_h)){
sWidth = box_w*sHeight/box_h;
sx = (source_w-sWidth)/2;
}else if(source_w < source_h || (source_w == source_h && box_w > box_h)){
sHeight = box_h*sWidth/box_w;
sy = (source_h-sHeight)/2;
}
return{
sx,
sy,
sWidth,
sHeight
}
}
var c=document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = '#e1f0ff';
// fix the position and size of the box - the image needs to be placed inside this box
ctx.fillRect(30, 30, 150, 200);
var img = new Image();
img.onload = function () {
console.log(img.width,img.height);
var imgRect = coverImg(150,200,img.width,img.height);
console.log('imgRect',imgRect);
ctx.drawImage(img, imgRect.sx, imgRect.sy, imgRect.sWidth, imgRect.sHeight, 30, 30, 150, 200);
}
img.src = ". /timg2.jpg";
//Note: In img preload mode, onload should be placed above the value assigned to src to avoid the situation where the onload event cannot be triggered if there is already a cache, and thus the event in onload does not execute
この記事がお役に立てれば幸いです。そして、スクリプト・ハウスを応援していただければ幸いです。
関連
-
html5でポップアップ画像のクリック機能を実装する
-
Html5による大画面データビジュアライゼーション開発の実装
-
window.postMessage を用いた html5 のクロスドメインデータインタラクション
-
Canvasでグラフィックス/イメージバインディングのイベントリスナーを実装する方法
-
html5 モバイルアダプティブレイアウトの実装
-
モバイル版Html5におけるBaidu地図のクリックイベント
-
HTML5 postMessage使用マニュアル
-
Html5 Canvasアニメーションの基本的な衝突検出の実装
-
キャンバスの幅と高さの設定に関する問題点
-
html5 canvasによる画像圧縮のサンプルコード
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
html5呼び出しカメラサンプルコード
-
キャンバスの内容を消去する(点消去+線消去)
-
htmlページでsessionの値を取得する方法
-
Html5は、コンテナは、画面の高さや残りの高さの適応的なレイアウトの実装を埋めることができます
-
Html5ページオープンアプリに関するいくつかの考察
-
Html5カスタムフォントソリューション
-
postMessageを使用してiframeの高さを適応させる例
-
キャンバスアプレットでテキストのアンカーポイントを中央に設定する
-
画像リソースが同一ドメイン下にないために、キャンバスがクロスドメインで汚染される場合の解決策
-
webViewでhtml画像を読み込む際の問題を解決する。