首页 > 解决方案 > 我想应用过滤器:模糊到任何形状

问题描述

点击图片点击路径。在击中三个或更多传球后单击第一个点以关闭传球。当路径关闭时,我想选择路径内部并实现模糊范围的功能。目前,关闭路径时没有任何反应。

标签: javascript

解决方案


我认为您对Paper.js渲染引擎有误。
它在元素的上下文中绘制其项目<canvas>,因此您可以从开发人员工具中访问的只是此画布及其图像数据。
您将无法定位您的路径并使用选择器对其进行操作,这似乎是您正在尝试做的事情。

无论如何,Paper.js不​​幸的是,目前不支持过滤器。
因此,一种选择可能是利用画布上下文过滤器属性(实验性)或自己实现模糊算法。
然后,在保持Paper.js绘图实用性的同时,您可以管理多个画布并进行智能合成以产生您正在寻找的效果。

这是一个演示可能实现的小提琴。
请注意,为了演示,我简化了您的用例,但您应该能够很容易地适应您的情况。
在这个例子中,我使用了 3 个不同的画布:
- 底部的一个用于绘制原始图像
- 中间的一个用于绘制模糊部分
- 顶部的一个用于绘制我们将用于合成的形状,并将隐藏在结束

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Debug Paper.js</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/paper.js/0.12.2/paper-core.min.js"></script>
    <style>
        html,
        body {
            margin   : 0;
            overflow : hidden;
            height   : 100%;
        }

        /* We position canvases on top of each other. */
        canvas {
            position : absolute;
            top      : 0;
            left     : 0;
            width    : 100vw;
            height   : 100vh;
        }
    </style>
</head>
<body>
<canvas id="bottom-canvas"></canvas>
<canvas id="middle-canvas"></canvas>
<canvas id="top-canvas"></canvas>
<script>
    // Get canvases references.
    const bottomCanvas = document.getElementById('bottom-canvas');
    const middleCanvas = document.getElementById('middle-canvas');
    const topCanvas = document.getElementById('top-canvas');

    // Initialise 2 PaperScopes.
    const bottomScope = new paper.PaperScope();
    bottomScope.setup(bottomCanvas);
    const topScope = new paper.PaperScope();
    topScope.setup(topCanvas);

    // For middle canvas, we need to adjust the size manually as Paper.js doesn't handle it.
    middleCanvas.width = middleCanvas.offsetWidth;
    middleCanvas.height = middleCanvas.offsetHeight;

    // Draw the image on the bottom canvas.
    new paper.Raster({
        source: 'https://i.imgur.com/6N0Zwag.jpg',
        crossOrigin: 'anonymous',
        position: bottomScope.view.center,
        parent: bottomScope.project.activeLayer,
        // When image is loaded...
        onLoad: function() {
            // ...make it fit the whole canvas.
            this.fitBounds(bottomScope.view.bounds, true);

            // Draw a circle on the top canvas that represents the user drawn shape
            // that we want to use for blurring.
            new paper.Path.Circle({
                center: topScope.view.center,
                radius: 200,
                fillColor: 'orange',
                parent: topScope.project.activeLayer
            });

            // We manually call the canvas view update to make sure that everything
            // is drawn before we play with image data.
            bottomScope.view.update();
            topScope.view.update();

            // Get middle canvas context to be able to draw on it.
            const middleCanvasContext = middleCanvas.getContext('2d');
            // Draw the bottom canvas image on the middle canvas with the blur filter applied.
            middleCanvasContext.filter = 'blur(15px)';
            middleCanvasContext.drawImage(bottomCanvas, 0, 0);

            // In order to see the clear part of the bottom canvas image,
            // we need to remove from middle canvas what is not on top canvas.
            // For that, we use "destination-in" composite operation.
            middleCanvasContext.filter = 'none';
            middleCanvasContext.globalCompositeOperation = 'destination-in';
            middleCanvasContext.drawImage(topCanvas, 0, 0);

            // Now, we need to hide the top canvas, to see the middle one below it.
            topCanvas.style.display = 'none';
        }
    });
</script>
</body>
</html>

推荐阅读