gpt4 book ai didi

javascript - svg 旋转,缩放和平移鼠标

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:31:34 26 4
gpt4 key购买 nike

尝试使用鼠标在 SVG 元素上应用旋转、移动和调整大小。 Here你可以测试一下。

目前我在南控、中控和旋转控制方面工作。

  1. 旋转效果非常好,我可以旋转、停止并再次旋转。但是我通过拖动中心点移动元素后,旋转第一次闪烁并且旋转起点不同。我相信这是因为翻译后中心位置发生了变化。我尝试重新计算中心位置,但没有成功。

  2. 缩放是移动元素而不是增加尺寸。

请帮我解决这个问题。我在这里遗漏了一些调整。

注意:首先,您已经用鼠标绘制了一些路径以对其进行控制。

var svg = document.querySelector('.container');
var svgns = 'http://www.w3.org/2000/svg';

var path = document.createElementNS(svgns, 'path');
svg.appendChild(path);

var points = [];
var Resizer_Instance = null;

var boundingBox = svg.getBoundingClientRect();

var toSVGPath = function(points) {
var SVGPath = '';
for (var i = 0; i < points.length; i++) {
var prefix = (i == 0) ? 'M' : 'L';
SVGPath += prefix + points[i].x + ' ' + points[i].y + ' ';
}
return SVGPath;
};

var create_mousedown = false;

var createStart = function(event) {
create_mousedown = true;
};

var creating = function(event) {
if (create_mousedown) {
var point = svg.createSVGPoint();
point.x = event.clientX - boundingBox.left;
point.y = event.clientY - boundingBox.top;
var t = point.matrixTransform(svg.getScreenCTM().inverse());
points.push(t);
path.setAttributeNS(null, 'd', toSVGPath(points));
}
};

var createEnd = function(event) {
create_mousedown = true;
svg.removeEventListener('mousedown', createStart);
svg.removeEventListener('mousemove', creating);
svg.removeEventListener('mouseup', createEnd);
setTimeout(function functionName() {
Resizer_Instance = new Resizer(path, svg);
}, 500);
};

svg.addEventListener('mousedown', createStart);
svg.addEventListener('mousemove', creating);
svg.addEventListener('mouseup', createEnd);


var Resizer = (function() {

function Resizer(element) {
var that = this;
that.element = element;
createSelector.call(that);

document.addEventListener('mousemove', dragging);
document.addEventListener('mouseup', dragend);

}

var RAD2DEG = 180 / Math.PI;

function angleBetweenPoints(p1, p2) {
var angle = null;
if (p1.x == p2.x && p1.y == p2.y)
angle = Math.PI / 2;
else
angle = Math.atan2(p2.y - p1.y, p2.x - p1.x);
return (angle * RAD2DEG) + -90;
}

function controlPositions(el) {
var pt = svg.createSVGPoint();
var bbox = el.getBoundingClientRect();
var matrix = el.getScreenCTM().inverse();
var halfWidth = bbox.width / 2;
var halfHeight = bbox.height / 2;
var placements = {};

pt.x = bbox.left;
pt.y = bbox.top;

placements['nw'] = pt.matrixTransform(matrix);
pt.x += halfWidth;
placements['n'] = pt.matrixTransform(matrix);
pt.x += halfWidth;
placements['ne'] = pt.matrixTransform(matrix);
pt.y += halfHeight;
placements['e'] = pt.matrixTransform(matrix);
pt.y += halfHeight;
placements['se'] = pt.matrixTransform(svg.getScreenCTM().inverse());
pt.x -= halfWidth;
placements['s'] = pt.matrixTransform(matrix);
pt.x -= halfWidth;
placements['sw'] = pt.matrixTransform(matrix);
pt.y -= halfHeight;
placements['w'] = pt.matrixTransform(matrix);
pt.x += halfWidth;
placements['center'] = pt.matrixTransform(matrix);
pt.y -= (halfHeight + 30);
placements['rot'] = pt.matrixTransform(matrix);

return placements;
}

var dragging_element = null;

var dragstart = function(event) {
var box = this;
var context = box.context;
var rootContext = context.rootContext;
rootContext.current_handle_inaction = context.direction;
dragging_element = box;
};

var dragging = function(event) {
if (!dragging_element) return;
var box = dragging_element;
var context = box.context;
var rootContext = context.rootContext;
var currentHandle = rootContext.current_handle_inaction;
var control_points = rootContext.control_points;

if (currentHandle === context.direction) {
var point = svg.createSVGPoint();
point.x = event.clientX;
point.y = event.clientY;
var element = rootContext.element;
var transformed = point.matrixTransform(svg.getScreenCTM().inverse());

var centerPosition = context.center;

rootContext.angle = rootContext.angle || 0;
rootContext.hMove = rootContext.hMove || 0;
rootContext.vMove = rootContext.vMove || 0;
rootContext.scaleX = rootContext.scaleX || 1;
rootContext.scaleY = rootContext.scaleY || 1;

switch (currentHandle) {
case "rot":
rootContext.angle = angleBetweenPoints(transformed, centerPosition);
break;
case "center":
rootContext.hMove = transformed.x - centerPosition.x;
rootContext.vMove = transformed.y - centerPosition.y;
break;
case "s":
var startPos = control_points[currentHandle];
var vMove = transformed.y - startPos.y;
rootContext.scaleY += (vMove > 0 ? -1 : 1) * 0.001;
break;
}

var move_transform = "translate(" + rootContext.hMove + " " + rootContext.vMove + ")";
var rotate_transform = "rotate(" + rootContext.angle + ", " + centerPosition.x + ", " + centerPosition.y + ")";
var scale_transform = "scale(" + rootContext.scaleX + ", " + rootContext.scaleY + ")";

var transform = [move_transform, rotate_transform, scale_transform].join(' ');

rootContext.element.setAttribute('transform', transform);
rootContext.controlGroup.setAttribute('transform', transform);
}
};

var dragend = function() {
if (!dragging_element) return;
var box = dragging_element;
var context = box.context;
var rootContext = context.rootContext;
delete rootContext.current_handle_inaction;
// createSelector.call(rootContext);
dragging_element = null;
};

var adjustPositions = function() {
var that = this;
var control_points = that.control_points;
var controlGroup = that.controlGroup;
var point = svg.createSVGPoint();
for (var direction in control_points) {
var dP = control_points[direction];
point.x = dP.x;
point.y = dP.y;
debugger;
control_points[direction] = point.matrixTransform(controlGroup.getScreenCTM().inverse());
}
return control_points;
};

var Deg2Rad = 0.017453292519943295;

var createSelector = function() {
var that = this;
var points = that.control_points;
if (points) {
points = adjustPositions.call(that);
} else {
points = controlPositions(that.element, svg);
}
that.control_points = points;
var existingBoxes = {};
var controlGroup = that.controlGroup;

if (!controlGroup) {
controlGroup = document.createElementNS(svgns, 'g');
that.controlGroup = controlGroup;
svg.appendChild(controlGroup);
}

that.control_boxes = that.control_boxes || {};

var line_name = "connecting-line",
line_element = that.control_boxes['connecting-line'];

var line_route = ["nw", "n", "rot", 'n', "ne", "e", "se", "s", "sw", "w", "nw"];

if (!line_element) {
line_element = document.createElementNS(svgns, 'path');
line_element.style.cssText = "fill: none; stroke: #f41542; opacity: 0.5";

that.control_boxes[line_name] = line_element;
controlGroup.appendChild(line_element);

var pathString = "";

line_route.forEach(function(direction) {
var point = points[direction];
var command = pathString.length === 0 ? "M" : " L ";
pathString += (command + point.x + " " + point.y);
});

line_element.setAttribute('d', pathString);
}

Object.keys(points).forEach(function(direction) {
var point = points[direction];
var box = that.control_boxes[direction];
if (!box) {
box = document.createElementNS(svgns, 'circle');
box.style.cssText = "fill: #5AABAB";

that.control_boxes[direction] = box;
box.setAttributeNS(null, 'r', 3);
box.setAttribute('handle', direction);

box.addEventListener('mousedown', dragstart.bind(box));

controlGroup.appendChild(box);
}

box.setAttributeNS(null, 'cx', point.x);
box.setAttributeNS(null, 'cy', point.y);

box.context = {
point: point,
direction: direction,
rootContext: that,
center: points.center
};

});


};

var prototype = {
constructor: Resizer
};
Resizer.prototype = prototype;
return Resizer;
})();
path {
fill: none;
stroke: #42B6DF;
}
body,
html {
height: 100%;
width: 100%;
margin: 0;
}
<svg class="container" version="1.1" baseProfile="full" style="position:absolute;left:0;top:0;height:100%;width:100%;-ms-transform:scale(1,1);transform:scale(1,1);-webkit-transform:scale(1,1);-moz-transform:scale(1,1);-o-transform:scale(1,1);transform:scale(1,1);-ms-transform-origin:0, 0;-webkit-transform-origin:0, 0;-moz-transform-origin:0, 0;-o-transform-origin:0, 0;transform-origin:0, 0"
viewBox="-220.38356461849224 6442.3347962008365 454.7376658611161 114.54981723871151"></svg>

最佳答案

您无法仅使用这三个变换函数轻松处理所有三个变换操作(平移、缩放和旋转)。您实际上应该使用四个函数。

您应该记住元素的原始中心点。我们称其为 ocx 和 ocy。然后执行以下操作:

  1. 将原来的中心点平移到原点
  2. 执行规模
  3. 执行轮换
  4. 将中心转换回新的(当前)中心位置。

所以 transform 字符串看起来像这样:

transform="translate(ncx,ncy) rotate(rot) scale(sx,sy) translate(-ocx,-ocy)"

这样您就可以将所有操作隔离开来,并且您无需在一个更改时更改其他操作。

关于javascript - svg 旋转,缩放和平移鼠标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40526478/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com