首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Fabric.js折线自定义控件怎么实现?

Fabric.js折线自定义控件怎么实现?

提问于 2022-09-23 10:42:25
回答 0关注 0查看 92

Fabric.js 官方demo有个多边形自定义的控件 http://fabricjs.com/custom-controls-polygon

但是将其中的多边形替换成折线会出现问题线不跟着控制点 或者控制点不在线上 哪位大神帮忙实现下

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .controls {
            display: inline-block;
        }
    </style>
</head>
<body>
<div class="controls">
    <p>
        <button id="edit" onclick="Edit()">Toggle editing polygon</button>
    </p>
</div>
<canvas id="c" width="500" height="400" style="border:1px solid #ccc"></canvas>
<script src="./fabric.js"></script>
<script>
    var canvas = this.__canvas = new fabric.Canvas('c');
    // create a polygon object
    var points = [{
        x: 30, y: 30
    }, {
        x: 150, y: 140
    }, {
        x: 240, y: 150
    }, {
        x: 100, y: 30
    } ]
    // 将官方多边形替换成折线
    const polygon = new fabric.Polyline([
        {x: 30, y: 30},
        {x: 150, y: 140},
        {x: 240, y: 150},
        {x: 100, y: 30}
    ], {
        fill: 'transparent', // 如果画折线,需要填充透明
        stroke: '#6639a6', // 线段颜色:紫色
        strokeWidth: 5 // 线段粗细 5
    })
    canvas.viewportTransform = [1, 0, 0, 0.7, -50, 50];
    canvas.add(polygon);

    // define a function that can locate the controls.
    // this function will be used both for drawing and for interaction.
    function polygonPositionHandler(dim, finalMatrix, fabricObject) {
        var x = (fabricObject.points[this.pointIndex].x - fabricObject.pathOffset.x),
            y = (fabricObject.points[this.pointIndex].y - fabricObject.pathOffset.y);

        console.log('x',x);
        console.log('y',y);
        return fabric.util.transformPoint(
            { x: x, y: y },
            fabric.util.multiplyTransformMatrices(
                fabricObject.canvas.viewportTransform,
                fabricObject.calcTransformMatrix()
            )
        );
    }

    function getObjectSizeWithStroke(object) {
        var stroke = new fabric.Point(
            object.strokeUniform ? 1 / object.scaleX : 1,
            object.strokeUniform ? 1 / object.scaleY : 1
        ).multiply(object.strokeWidth);
        return new fabric.Point(object.width + stroke.x, object.height + stroke.y);
    }

    // define a function that will define what the control does
    // this function will be called on every mouse move after a control has been
    // clicked and is being dragged.
    // The function receive as argument the mouse event, the current trasnform object
    // and the current position in canvas coordinate
    // transform.target is a reference to the current object being transformed,
    function actionHandler(eventData, transform, x, y) {
        var polygon = transform.target;
        var    currentControl = polygon.controls[polygon.__corner];
        var   mouseLocalPosition = polygon.toLocalPoint(new fabric.Point(x, y), 'center', 'center');
        var   polygonBaseSize = getObjectSizeWithStroke(polygon);
        var   size = polygon._getTransformedDimensions(0, 0);
        var   finalPointPosition = {
                x: mouseLocalPosition.x * polygonBaseSize.x / size.x + polygon.pathOffset.x,
                y: mouseLocalPosition.y * polygonBaseSize.y / size.y + polygon.pathOffset.y
            };
        polygon.points[currentControl.pointIndex] = finalPointPosition;
        return true;
    }

    // define a function that can keep the polygon in the same position when we change its
    // width/height/top/left.
    function anchorWrapper(anchorIndex, fn) {
        return function(eventData, transform, x, y) {
            var fabricObject = transform.target,
                absolutePoint = fabric.util.transformPoint({
                    x: (fabricObject.points[anchorIndex].x - fabricObject.pathOffset.x),
                    y: (fabricObject.points[anchorIndex].y - fabricObject.pathOffset.y),
                }, fabricObject.calcTransformMatrix()),
                actionPerformed = fn(eventData, transform, x, y),
                newDim = fabricObject._setPositionDimensions({}),
                polygonBaseSize = getObjectSizeWithStroke(fabricObject),
                newX = (fabricObject.points[anchorIndex].x - fabricObject.pathOffset.x) / polygonBaseSize.x,
                newY = (fabricObject.points[anchorIndex].y - fabricObject.pathOffset.y) / polygonBaseSize.y;
            fabricObject.setPositionByOrigin(absolutePoint, newX + 0.5, newY + 0.5);
            return actionPerformed;
        }
    }

    function Edit() {
        // clone what are you copying since you
        // may want copy and paste on different moment.
        // and you do not want the changes happened
        // later to reflect on the copy.
        var poly = canvas.getObjects()[0];
        canvas.setActiveObject(poly);
        poly.edit = !poly.edit;
        if (poly.edit) {
            var lastControl = poly.points.length - 1;
            poly.cornerStyle = 'circle';
            poly.cornerColor = 'rgba(0,0,255,0.5)';
            /* 编辑状态重新画点 */
            poly.controls = poly.points.reduce(function(acc, point, index) {
                console.log('index',index);
                acc['p' + index] = new fabric.Control({
                    positionHandler: polygonPositionHandler,
                    actionHandler: anchorWrapper(index > 0 ? index - 1 : lastControl, actionHandler),
                    actionName: 'modifyPolygon',
                    pointIndex: index
                });
                return acc;
            }, { });
        } else {
            poly.cornerColor = 'blue';
            poly.cornerStyle = 'rect';
            poly.controls = fabric.Object.prototype.controls;
        }
        poly.hasBorders = !poly.edit;
        canvas.requestRenderAll();
    }

</script>


</body>
</html>

回答

和开发者交流更多问题细节吧,去 写回答
相关文章

相似问题

相关问答用户
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档