github 地址: https://github.com/wangyuheng/painter
DEMO 地址: http://painter.crick.wang/
变形
变形这部分代码比较多,所以分为上下两部分。在(上)中已经实现了左侧中间点的变形操作。但是一共有 8 个操作点,为了避免混乱,抽离 handle.border.listener.js 提供 8 个点的变形方法。
y 轴移动
之前左侧中间点的操作可以视为 x 轴移动,现在只需要实现 y 轴移动的算法,即可实现 8 个点的移动。因为角落的四个点其实就是同时向 2 个方向移动。
以 topCenter 为例,设定 Top,以上为正方向,1 为向上运动,-1 为向下运动。
var tTop = 1;
计算鼠标 y 轴移动距离
var dy = currPoint.y - lastPoint.y;
屏幕左上角为(0,0)点,所以图形的新高度为
var height = ele.height() - tTop * dy;
判断 height,如果小于 0,说明达到图形的 y 轴 0 点,要根据 y 轴进行翻转。
var height = ele.height() - tTop * dy;
if (height > 0) {
var newY = ele.y() + tTop * dy;
ele.y(newY).height(height);
} else {
//invert
tTop = -tTop;
ele.height(-height).matrix(new SVG.Matrix(ele).flip('y', ele.bbox().cy));
}
成员变量
根据 x、y 两个方向的移动,推测出需要如下成员变量
var lastPoint;
var xLeft;
var yTop;
var ele;
ele 可以在初始化时完成,为当前操作的元素,lastPoint、xLeft、yTop 需要在开始拖拽时初始化。
通用方法
为了节省代码,抽象了 4 个通用方法 left(dx)、right(dx)、top(dy)、bottom(dy)
8 个操作点根据需要,获取当前的鼠标移动距离,并调用其中的 1 或 2 个通用方法,即可实现变形效果。
绑定并触发
在构造函数中,除了初始化 ele,还需要给 ele 绑定对应的事件。
在 HandleBorder 中,监听 8 个操作点的 dragstart 和 dragmove 事件,调用对应方法。
var HandleBorderListener = function(targetElement) {
ele = targetElement;
ele.on('leftCenterDragStart', leftCenterDragStart);
ele.on('leftCenterDragMove', leftCenterDragMove);
ele.on('rightCenterDragStart', rightCenterDragStart);
ele.on('rightCenterDragMove', rightCenterDragMove);
ele.on('topCenterDragStart', topCenterDragStart);
ele.on('topCenterDragMove', topCenterDragMove);
ele.on('bottomCenterDragStart', bottomCenterDragStart);
ele.on('bottomCenterDragMove', bottomCenterDragMove);
ele.on('leftTopDragStart', leftTopDragStart);
ele.on('leftTopDragMove', leftTopDragMove);
ele.on('leftBottomDragStart', leftBottomDragStart);
ele.on('leftBottomDragMove', leftBottomDragMove);
ele.on('rightTopDragStart', rightTopDragStart);
ele.on('rightTopDragMove', rightTopDragMove);
ele.on('rightBottomDragStart', rightBottomDragStart);
ele.on('rightBottomDragMove', rightBottomDragMove);
}
在 HandleBorder 中,在 create 方法中
_this.rectLeftCenter.on("dragstart", function() {
_this.currentElement.fire("leftCenterDragStart", {
currPoint: event.detail.p
});
});
_this.rectLeftCenter.on("dragmove", function() {
_this.currentElement.fire("leftCenterDragMove", {
currPoint: event.detail.p
});
});
_this.rectLeftCenter.on("afterdragmove", function() {
_this.rebound(_this.currentElement.bbox());
});
完整代码
完整代码如下
(function() {
var lastPoint;
var xLeft;
var yTop;
var ele;
function left(dx) {
var width = ele.width() - xLeft * dx;
if (width > 0) {
var newX = ele.x() + xLeft * dx;
ele.x(newX).width(width);
} else {
//invert
xLeft = -xLeft;
ele.x(ele.bbox().x2).width(-width).matrix(new SVG.Matrix(ele).flip('x', ele.bbox().cx));
}
}
function right(dx) {
var width = ele.width() - xLeft * dx;
if (width > 0) {
ele.width(width);
} else {
//invert
xLeft = -xLeft;
ele.width(-width).matrix(new SVG.Matrix(ele).flip('x', ele.bbox().cx));
}
}
function top(dy) {
var height = ele.height() - tTop * dy;
if (height > 0) {
var newY = ele.y() + tTop * dy;
ele.y(newY).height(height);
} else {
//invert
tTop = -tTop;
ele.height(-height).matrix(new SVG.Matrix(ele).flip('y', ele.bbox().cy));
}
}
function bottom(dy) {
var height = ele.height() - tTop * dy;
if (height > 0) {
ele.height(height);
} else {
//invert
tTop = -tTop;
ele.height(-height).matrix(new SVG.Matrix(ele).flip('y', ele.bbox().cy));
}
}
function leftCenterDragStart(data) {
lastPoint = data.detail.currPoint;
xLeft = 1;
}
function leftCenterDragMove(data) {
var currPoint = data.detail.currPoint;
var dx = currPoint.x - lastPoint.x;
left(dx);
lastPoint = currPoint;
}
function rightCenterDragStart(data) {
lastPoint = data.detail.currPoint;
xLeft = -1;
}
function rightCenterDragMove(data) {
var currPoint = data.detail.currPoint;
var dx = currPoint.x - lastPoint.x;
right(dx);
lastPoint = currPoint;
}
function topCenterDragStart(data) {
lastPoint = data.detail.currPoint;
tTop = 1;
}
function topCenterDragMove(data) {
var currPoint = data.detail.currPoint;
var dy = currPoint.y - lastPoint.y;
top(dy);
lastPoint = currPoint;
}
function bottomCenterDragStart(data) {
lastPoint = data.detail.currPoint;
tTop = -1;
}
function bottomCenterDragMove(data) {
var currPoint = data.detail.currPoint;
var dy = currPoint.y - lastPoint.y;
bottom(dy);
lastPoint = currPoint;
}
function leftTopDragStart(data) {
lastPoint = data.detail.currPoint;
xLeft = 1;
tTop = 1;
}
function leftTopDragMove(data) {
var currPoint = data.detail.currPoint;
var dx = currPoint.x - lastPoint.x;
var dy = currPoint.y - lastPoint.y;
left(dx);
top(dy);
lastPoint = currPoint;
}
function leftBottomDragStart(data) {
lastPoint = data.detail.currPoint;
xLeft = 1;
tTop = -1;
}
function leftBottomDragMove(data) {
var currPoint = data.detail.currPoint;
var dx = currPoint.x - lastPoint.x;
var dy = currPoint.y - lastPoint.y;
left(dx);
bottom(dy);
lastPoint = currPoint;
}
function rightTopDragStart(data) {
lastPoint = data.detail.currPoint;
xLeft = -1;
tTop = 1;
}
function rightTopDragMove(data) {
var currPoint = data.detail.currPoint;
var dx = currPoint.x - lastPoint.x;
var dy = currPoint.y - lastPoint.y;
right(dx);
top(dy);
lastPoint = currPoint;
}
function rightBottomDragStart(data) {
lastPoint = data.detail.currPoint;
xLeft = -1;
tTop = -1;
}
function rightBottomDragMove(data) {
var currPoint = data.detail.currPoint;
var dx = currPoint.x - lastPoint.x;
var dy = currPoint.y - lastPoint.y;
right(dx);
bottom(dy);
lastPoint = currPoint;
}
var HandleBorderListener = function(targetElement) {
ele = targetElement;
ele.on('leftCenterDragStart', leftCenterDragStart);
ele.on('leftCenterDragMove', leftCenterDragMove);
ele.on('rightCenterDragStart', rightCenterDragStart);
ele.on('rightCenterDragMove', rightCenterDragMove);
ele.on('topCenterDragStart', topCenterDragStart);
ele.on('topCenterDragMove', topCenterDragMove);
ele.on('bottomCenterDragStart', bottomCenterDragStart);
ele.on('bottomCenterDragMove', bottomCenterDragMove);
ele.on('leftTopDragStart', leftTopDragStart);
ele.on('leftTopDragMove', leftTopDragMove);
ele.on('leftBottomDragStart', leftBottomDragStart);
ele.on('leftBottomDragMove', leftBottomDragMove);
ele.on('rightTopDragStart', rightTopDragStart);
ele.on('rightTopDragMove', rightTopDragMove);
ele.on('rightBottomDragStart', rightBottomDragStart);
ele.on('rightBottomDragMove', rightBottomDragMove);
}
this.HandleBorderListener = HandleBorderListener;
})();
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于