我已经查看了其他一些有关此事的帖子,但仍然无法弄清楚为什么公式不起作用。
计算旋转矩形的边界框:
w' = sin(a)*h + cos(a)*w;
h' = sin(a)*w + cos(a)*h;
问题是我在w'
和h'
完全不准确的情况下会出现奇怪的行为。
// calculate rotation angle of shape
function getRotationDegrees(obj) {
var matrix = obj.css("-webkit-transform") ||
obj.css("-moz-transform") ||
obj.css("-ms-transform") ||
obj.css("-o-transform") ||
obj.css("transform");
if (matrix !== 'none') {
var values = matrix.split('(')[1].split(')')[0].split(',');
var a = values[0];
var b = values[1];
var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
} else {
var angle = 0;
}
if (angle < 0) angle += 360;
return angle;
}
var shape = $('.shape'),
shapeLeft = shape.position().left,
shapeTop = shape.position().top,
shapeWidth = shape.width(),
shapeHeight = shape.height(),
angle = getRotationDegrees(shape),
// formula below
height = Math.abs(shapeWidth * Math.sin(angle)) + Math.abs(shapeHeight * Math.cos(angle)),
width = Math.abs(shapeHeight * Math.sin(angle)) + Math.abs(shapeWidth * Math.cos(angle));
$('#g1').css('width', width);
$('#g2').css('height', height);
&#13;
.elements,
.element {
position: absolute
}
#s2 {
background: #333333;
top: 60px;
left: -25px;
width: 300px;
height: 100px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="layout" style="position:relative; margin-top:50px; margin-left:70px;">
<div class="elements">
<div id="g1" class="element" style="background:red;left:-35px;top:-10px;height:2px;"></div>
<div id="g2" class="element" style="background:red;left:-35px;top:-10px;width:2px;"></div>
<div id="s2" class="element shape" style="transform: rotate(8deg);"></div>
</div>
</div>
&#13;
我做错了什么?
答案 0 :(得分:1)
两个错误来源:
(次要)角度的圆角。 (不知道你的意思是什么&#34;已经是一个数字&#34;)
(主要)您直接在getRotationDegrees
中使用Math.cos / sin
的结果。这些函数需要弧度,即Math.atan2
直接返回的结果。
下面的代码段添加了边界框的另外两条边,以及正确的位置偏移。我添加了一个滑块来更改旋转角度,以说明此代码是健壮的。
function getMatrix(obj) {
var matrix = obj.css("-webkit-transform") ||
obj.css("-moz-transform") ||
obj.css("-ms-transform") ||
obj.css("-o-transform") ||
obj.css("transform");
return (matrix == 'none') ? null : matrix.split('(')[1].split(')')[0].split(',');
}
// calculate rotation angle of shape
function getRotationRadians(matrix) {
var angle = matrix ? Math.atan2(matrix[1], matrix[0]) : 0;
if (angle < 0) angle += 2.0 * Math.PI;
return angle;
}
// calculate translation
function getTranslation(matrix) {
return matrix ? [matrix[4], matrix[5]] : [0, 0];
}
// calculate bounding box
function getBoundingBox(shape) {
var shapeLeft = shape.position().left,
shapeTop = shape.position().top,
shapeWidth = shape.width(),
shapeHeight = shape.height();
var matrix = getMatrix(shape);
var angle = getRotationRadians(matrix);
var height = Math.abs(shapeWidth * Math.sin(angle)) + Math.abs(shapeHeight * Math.cos(angle));
var width = Math.abs(shapeHeight * Math.sin(angle)) + Math.abs(shapeWidth * Math.cos(angle));
var trans = getTranslation(matrix);
var left = trans[0] - (width * 0.5);
var top = trans[1] - (height * 0.5);
return {'x': left, 'y': top, 'w': width, 'h': height};
}
formatBox($('.shape'));
function formatBox(shape) {
var box = getBoundingBox(shape);
var offx = 124, offy = 109;
var g1 = $('#g1'), g2 = $('#g2'), g3 = $('#g3'), g4 = $('#g4');
g1.css('width', box.w);
g2.css('height', box.h);
g3.css('width', box.w);
g4.css('height', box.h);
g1.css('left', offx + box.x);
g2.css('left', offx + box.x);
g3.css('left', offx + box.x);
g4.css('left', offx + box.x + box.w);
g1.css('top', offy + box.y);
g2.css('top', offy + box.y);
g3.css('top', offy + box.y + box.h);
g4.css('top', offy + box.y);
}
var angleInp = document.getElementById("angleInp");
angleInp.addEventListener("change", function() {
var shape = $('.shape');
shape.css('transform', 'rotate(' + angleInp.value + 'deg)');
formatBox(shape);
}, false);
&#13;
.elements,
.element {
position: absolute
}
#s2 {
background: #333333;
top: 60px;
left: -25px;
width: 300px;
height: 100px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="slider">
<input class="bar" type="range" id="angleInp" min="0" max="360" value="15" onchange="angleInp.value=value"/>
</div>
<div class="layout" style="position:relative; margin-top:50px; margin-left:70px;">
<div class="elements">
<div id="g1" class="element" style="background:red;left:0px;top:0px;height:2px;"></div>
<div id="g2" class="element" style="background:red;left:0px;top:0px;width:2px;"></div>
<div id="g3" class="element" style="background:red;left:0px;top:0px;height:2px;"></div>
<div id="g4" class="element" style="background:red;left:0px;top:0px;width:2px;"></div>
<div id="s2" class="element shape" style="transform: rotate(15deg);"></div>
</div>
</div>
&#13;