绘画板 13——变形 (下)

本贴最后更新于 3104 天前,其中的信息可能已经物是人非

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; })();
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    409 引用 • 3588 回帖
  • SVG
    24 引用 • 73 回帖
  • Painter
    14 引用 • 31 回帖
  • 变形
    2 引用 • 7 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...