, , .
var dist = Math.sqrt(Math.pow(canvas.width/2,2)+Math.pow(canvas.height/2,2));
;
var imgDist = Math.min(image.width,image.height)/2
, , , , .
var minScale = dist / imgDist;
, ,
( X)
var dx = Math.cos(ang) * minScale;
var dy = Math.sin(ang) * minScale;
, X, - Y, 90 X, .
ctx.setTransform(dx, dy, -dy, dx, canvas.width / 2, canvas.height / 2);
.
ctx.drawImage(image,-image.width / 2, - image.height / 2);
,
ctx.setTransform(1,0,0,1,0,0);
.
function drawToFitRotated(ctx, angle, image){
var dist = Math.sqrt(Math.pow(ctx.canvas.width /2, 2 ) + Math.pow(ctx.canvas.height / 2, 2));
var imgDist = Math.min(image.width, image.height) / 2;
var minScale = dist / imgDist;
var dx = Math.cos(angle) * minScale;
var dy = Math.sin(angle) * minScale;
ctx.setTransform(dx, dy, -dy, dx, ctx.canvas.width / 2, ctx.canvas.height / 2);
ctx.drawImage(image, -image.width / 2, - image.height / 2);
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
UPDATE
, , , , , , , . , , , , , 4 , . , , .
, . - R. C-E C-F. Ih Iw .
C-B, (ch) (cw).
A, acos (ch)/ C-B
, A, A1 A2. C-B A1, A2, C-E-B C-F-B C-E C-F.
C-E = C-B * cos (A1) C-F = C-B * cos (A2)
, C-E Ih C-E Iw. , , .
, , .
. 0 -90 , . , . > 180 180, > 90 °, 180 90 . . , 0 - 360 ( 0 Math.PI * 2).
.
. - , - . , , , .
, .
- .
demo = function(){
var canvas = (function(){
var canvas = document.getElementById("canv");
if(canvas !== null){
document.body.removeChild(canvas);
}
canvas = document.createElement("canvas");
canvas.id = "canv";
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.position = "absolute";
canvas.style.top = "0px";
canvas.style.left = "0px";
canvas.style.zIndex = 1000;
canvas.ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
return canvas;
})();
var ctx = canvas.ctx;
var image = new Image();
image.src = "http://i.imgur.com/gwlPu.jpg";
var w = canvas.width;
var h = canvas.height;
var cw = w / 2;
var ch = h / 2;
function drawBestFit(ctx, angle, image){
var iw = image.width / 2;
var ih = image.height / 2;
var dist = Math.sqrt(Math.pow(cw,2) + Math.pow(ch,2));
var diagAngle = Math.asin(ch/dist);
a1 = ((angle % (Math.PI *2))+ Math.PI*4) % (Math.PI * 2);
if(a1 > Math.PI){
a1 -= Math.PI;
}
if(a1 > Math.PI/2 && a1 <= Math.PI){
a1 = (Math.PI/2) - (a1-(Math.PI/2));
}
var ang1 = Math.PI/2 - diagAngle - Math.abs(a1);
var ang2 = Math.abs(diagAngle - Math.abs(a1));
var dist1 = Math.cos(ang1) * dist;
var dist2 = Math.cos(ang2) * dist;
var scale = Math.max(dist2/(iw),dist1/(ih));
var dx = Math.cos(angle) * scale;
var dy = Math.sin(angle) * scale;
ctx.setTransform(dx, dy, -dy, dx, cw, ch);
ctx.drawImage(image, -iw, - ih);
ctx.strokeStyle = "red";
ctx.lineWidth = 2 * (1/scale);
ctx.strokeRect(-iw / 2, -ih / 2, iw, ih)
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.strokeStyle = "blue";
ctx.lineWidth = 2;
ctx.strokeRect(cw - cw / 2, ch - ch / 2, cw, ch)
}
function drawToFitRotated(ctx, angle, image){
var dist = Math.sqrt(Math.pow(cw,2) + Math.pow(ch,2));
var imgDist = Math.min(image.width, image.height) / 2;
var minScale = dist / imgDist;
var dx = Math.cos(angle) * minScale;
var dy = Math.sin(angle) * minScale;
ctx.setTransform(dx, dy, -dy, dx, cw, ch);
ctx.drawImage(image, -image.width / 2, - image.height / 2);
ctx.setTransform(1, 0, 0, 1, 0, 0);
}
var angle = 0;
function update(){
if(image.complete){
angle += 0.01;
drawBestFit(ctx,angle,image);
}
if(!STOP){
requestAnimationFrame(update);
}else{
STOP = false;
var canv = document.getElementById("canv");
if(canv !== null){
document.body.removeChild(canv);
}
}
}
update();
}
var STOP = false;
function resizeEvent(){
var waitForStopped = function(){
if(!STOP){
demo();
return;
}
setTimeout(waitForStopped,200);
}
STOP = true;
setTimeout(waitForStopped,100);
}
window.addEventListener("resize",resizeEvent);
demo();
Hide result