我们在缩放和旋转相对于另一个div的点时遇到了一些麻烦。基本上我们有2层,一层带有图像(svg),另一层带有放置在图像上的图标。
我们已经能够根据图像的旋转(和位置)旋转图标,比例为1。 我们已经能够根据图像的比例(和位置)缩放图标,旋转为零。
但是很快就会缩放和旋转,事情会变得混乱......
这是翻译一个点(绝对)以匹配图像矩阵的代码:
self.getViewportCoordinatesFromPoint = function(pointX, pointY) {
var centerVal = {
x: gestureValues.centerVal.x(),//scaled centerX
y: gestureValues.centerVal.y(),//scaled centerY
normalX: gestureValues.centerVal.normalX(),//original center
normalY: gestureValues.centerVal.normalY()//original center
};
var output = {
x:pointX,
y:pointY
};
//Image rotation angle
var angle = gestureValues.mapRotation * Math.PI / 180.0;
//Scale no rotate
var scaledPoint = {};
var normX = (centerVal.normalX - output.x); //center of map to X axis
var ratioX = normX / centerVal.normalX; //percentage of the distance compared to center point.
var scaleX = centerVal.x * ratioX; //Scaled value of x from the center of scaled map
scaledPoint.x = centerVal.normalX - scaleX; // subtract the original map width from scaled value
var normY = (centerVal.normalY - output.y);
var ratioY = normY / centerVal.normalY;
var scaleY = centerVal.y * ratioY;
scaledPoint.y = centerVal.normalY - scaleY;
output = scaledPoint;
var rotatedPoint = {};
rotatedPoint.x = Math.cos(angle) * (output.x - centerVal.x) - Math.sin(angle) * (output.y - centerVal.y) + (centerVal.x);
rotatedPoint.y = Math.sin(angle) * (output.x - centerVal.x) + Math.cos(angle) * (output.y - centerVal.y) + (centerVal.y);
output = rotatedPoint;
//Add gesture values
output.x = ((output.x + gestureValues.mapXY[0]));
output.y = ((output.y + gestureValues.mapXY[1]));
return output;
};
非常感谢任何帮助!
提前致谢!
答案 0 :(得分:2)
好的,看看这个小提琴中的第32到65行。诀窍是计算距离中心*的距离,然后将其应用于旋转计算!
https://jsfiddle.net/DanielSim/sus9kgfh/
outputElement = document.getElementById('output');
rotationElement = document.getElementById('rotation');
rotationElement.oninput = function () {
rotation = parseInt(rotationElement.value, 10);
};
scaleElement = document.getElementById('scale');
scaleElement.oninput = function () {
scale = parseInt(scaleElement.value, 10) / 100;
};
feature = {
x: 20,
y: 20,
width: 10,
height: 10,
el: document.getElementById('feature')
};
map = {
x: 50,
y: 30,
width: 300,
height: 300,
el: document.getElementById('map')
};
rotation = 0;
scale = 1;
// Logic for correcting the coordinates of a point accounting for scale and rotation
adjustedTransform = function (_x, _y) {
var x = _x + map.x;
var y = _y + map.y;
var viewportMapCentre = {
x: map.width/2 + map.x,
y: map.height/2 + map.y
}
var differenceFromCentre = {
x: x - viewportMapCentre.x,
y: y - viewportMapCentre.y
};
var differenceFromCentreAtScale = {
x: differenceFromCentre.x * scale,
y: differenceFromCentre.y * scale
};
var rotatedPoint = {};
var angle = rotation * Math.PI / 180.0;
rotatedPoint.x = Math.cos(angle) * (differenceFromCentreAtScale.x) - Math.sin(angle) * (differenceFromCentreAtScale.y) + (viewportMapCentre.x);
rotatedPoint.y = Math.sin(angle) * (differenceFromCentreAtScale.x) + Math.cos(angle) * (differenceFromCentreAtScale.y) + (viewportMapCentre.y);
x = rotatedPoint.x;
y = rotatedPoint.y;
var coords = {
x:x,
y:y
};
return coords;
}
// Runs on each frame:
frame = 0;
step = function () {
//Apply standard transform to map
map.el.style.webkitTransform = generateTransform(map.x, map.y, scale, rotation);
//Apply adjusted transform to feature
featurePosition = adjustedTransform(feature.x, feature.y);
feature.el.style.webkitTransform = generateTransform(featurePosition.x, featurePosition.y, 1, 0);
generateTextOutput();
frame++;
};
displayLoop = function () {
step();
window.requestAnimationFrame(displayLoop);
};
generateTransform = function (x, y, scale, ry) {
return 'translate3d(' + x + 'px, ' + y + 'px, 0) scale3d(' + scale + ', ' + scale + ', ' + 1 + ') rotate3d(0, 0, 1,' + ry + 'deg)';
};
generateTextOutput = function () {
output = "";
output += "\nFrame: " + frame;
output += "\nRotation: " + rotation;
output += "\nScale: " + scale;
output += ("\nFeature Coords: " + featurePosition.x + ", " + featurePosition.y);
outputElement.innerText = output;
};
displayLoop();