精华内容
下载资源
问答
  • canvas学习day3——判断点,鼠标点击是否在指定路径
    2021-04-29 04:19:16

    ctx.isPointInPath( 要判断的点x轴坐标,要判断的点y轴坐标 )

    1、获取ctx对象
    2、增加监听事件
    3、ctx.isPointInPath

    <body>
        <canvas id="cvs"></canvas>
        <script>
            var cvs = document.querySelector( '#cvs' );
            var ctx = cvs.getContext( '2d' );
    
            /*
            * 判断点在不在路径中:
            * ctx.isPointInPath( 要判断的点x轴坐标,要判断的点y轴坐标 )
            * */
    
            ctx.rect( 10, 10, 50, 50 );
            ctx.stroke();
    
            // 点击画布,判断点击的位置在不在路径中
            cvs.addEventListener( 'click', function( e ) {
                var x = e.pageX - cvs.offsetLeft;
                var y = e.pageY - cvs.offsetTop;
                alert( ctx.isPointInPath( x, y ) );
            } )
        </script>
    </body>
    
    更多相关内容
  • 最近在写画板程序,要判断一个点在一个闭合的path内或者是一个不规则的图形内,这个可不好解决网上查了一堆有算法云云的,直到看到一个大神的帖子 其实可以相当的简单几句话的是 核心代码://------关键部分 判断点...

    最近在写画板程序,要判断一个点在一个闭合的path内或者是一个不规则的图形内,这个可不好解决网上查了一堆有算法云云的,直到看到一个大神的帖子 其实可以相当的简单几句话的是 核心代码:

    //------关键部分 判断点是否在 一个闭合的path内--------//

    if(event.getAction()==MotionEvent.ACTION_DOWN){

    //构造一个区域对象,左闭右开的。

    RectF r=new RectF();

    //计算控制点的边界

    mPath.computeBounds(r, true);

    //设置区域路径和剪辑描述的区域

    re.setPath(mPath, new Region((int)r.left,(int)r.top,(int)r.right,(int)r.bottom));

    //判断触摸点是否在封闭的path内 在返回true 不在返回false

    Log.e("","--判断点是否则范围内----"+re.contains((int)event.getX(), (int)event.getY()));

    }

    主要是用了 mPath.computeBounds(r, true);来计算边界 产生Region来判断

    全部示例代码:

    package com.example.touchtest;

    import android.content.Context;

    import android.graphics.Canvas;

    import android.graphics.Paint;

    import android.graphics.Path;

    import android.graphics.RectF;

    import android.graphics.Region;

    import android.util.AttributeSet;

    import android.util.Log;

    import android.view.MotionEvent;

    import android.view.View;

    public class TestView extends View{

    //----绘制轨迹----

    private float mX;

    private float mY;

    private final Paint mGesturePaint = new Paint();

    private final Path mPath = new Path();

    //------检测点是否在path内

    private boolean isDraw=false;

    Region re=new Region();

    public TestView(Context context, AttributeSet attrs) {

    super(context, attrs);

    mGesturePaint.setColor(context.getResources().getColor(android.R.color.holo_green_dark));

    mGesturePaint.setStyle(Paint.Style.STROKE);

    mGesturePaint.setStrokeWidth(4.0f);

    }

    public TestView(Context context) {

    super(context);

    mGesturePaint.setColor(context.getResources().getColor(android.R.color.holo_green_dark));

    mGesturePaint.setStyle(Paint.Style.STROKE);

    mGesturePaint.setStrokeWidth(4.0f);

    }

    @Override

    protected void onDraw(Canvas canvas) {

    canvas.drawPath(mPath, mGesturePaint);

    }

    @Override

    public boolean onTouchEvent(MotionEvent event)

    {

    if(isDraw){

    //------关键部分 判断点是否在 一个闭合的path内--------//

    if(event.getAction()==MotionEvent.ACTION_DOWN){

    //构造一个区域对象,左闭右开的。

    RectF r=new RectF();

    //计算控制点的边界

    mPath.computeBounds(r, true);

    //设置区域路径和剪辑描述的区域

    re.setPath(mPath, new Region((int)r.left,(int)r.top,(int)r.right,(int)r.bottom));

    //在封闭的path内返回true 不在返回false

    Log.e("","--判断点是否则范围内----"+re.contains((int)event.getX(), (int)event.getY()));

    }

    return true;

    }

    switch (event.getAction())

    {

    case MotionEvent.ACTION_DOWN:

    touchDown(event);

    break;

    case MotionEvent.ACTION_MOVE:

    touchMove(event);

    break;

    case MotionEvent.ACTION_UP:

    mPath.close();

    isDraw=true;

    break;

    }

    //更新绘制

    invalidate();

    return true;

    }

    //---------------下边是划线部分----------------------------//

    //手指点下屏幕时调用

    private void touchDown(MotionEvent event)

    {

    //重置绘制路线,即隐藏之前绘制的轨迹

    mPath.reset();

    float x = event.getX();

    float y = event.getY();

    mX = x;

    mY = y;

    mPath.moveTo(x, y);

    }

    //手指在屏幕上滑动时调用

    private void touchMove(MotionEvent event)

    {

    final float x = event.getX();

    final float y = event.getY();

    final float previousX = mX;

    final float previousY = mY;

    final float dx = Math.abs(x - previousX);

    final float dy = Math.abs(y - previousY);

    //两点之间的距离大于等于3时,连接连接两点形成直线

    if (dx >= 3 || dy >= 3)

    {

    //两点连成直线

    mPath.lineTo(x, y);

    //第二次执行时,第一次结束调用的坐标值将作为第二次调用的初始坐标值

    mX = x;

    mY = y;

    }

    }

    }

    0818b9ca8b590ca3270a3433284dd417.png运行

    经测试可以很准确的判断 touch触摸点是否在上边绘制的不规则图形内,搞绘图的小伙伴们赶紧拿去开心的玩耍吧!哈哈

    展开全文
  • 为了追踪所画内容,诸如画图应用程序、计算机辅助设计系统(computer-aided design system 简称CAD系统)以及游戏等许多应用程序,都会维护份包含当前显示对象的列表。通常来说,这些应用程序都允许用户对当前显示在...

    为了追踪所画内容,诸如画图应用程序、计算机辅助设计系统(computer-aided design system 简称CAD系统)以及游戏等许多应用程序,都会维护一份包含当前显示对象的列表。通常来说,这些应用程序都允许用户对当前显示在屏幕上的物体进行操作。比方说,在CAD应用程序中,我们可以对设计中的元素进行选择、移动、缩放等操作

    ——《HTML5 Canvas核心技术》

    在Canvas中 实现拖拽 也同样如此,Canvas提供了一个名为 isPointInPath(x, y) 的API,判断 点(x, y) 是否在路径之中。如果在路径之中,则返回true。于是我们可以有如下思路:

    维护一个可以描述各个路径的 数组 ,通过 ispointInPath(x, y) 判断点击位置是否在某一个路径之中,如果在此路径之中,选中此路径,进行操作(移动、缩放等),再绘制图形

    此文我以 多边形拖拽为例进行说明 ,Demo如下(后面的印子是录屏软件的原因:japanese_ogre:):

    48b8ff6608820a89087775a342808bd0.gif

    Demo中的多边形如何绘制之前做过总结,不再赘述:ghost::Canvas多边形绘制

    思路说明

    下图给了大致的说明及伪代码,思路并不难,但有部分细节需要处理

    1ebcf2b5a24c6ddbca64045166ae813b.png

    代码结构说明

    此处列举代码结构及标注其思路,更详细的代码注释已在CodePen之中

    因为本文重点在拖拽(drag),所以对绘图部分描述会较少

    //绘制多边形路径函数

    function drawPolygonPath

    //多边形类定义

    class Polygon{

    ...

    }

    //根据点击事件返回在canvas中的位置

    function positoinInCanvas

    //获取两点间直线距离

    function getDistance

    //开始阶段,记录拖拽对象

    canvas.onmousedown

    //拖拽阶段,画路径,描边

    canvas.onmousemove

    //结束阶段,更新拖拽对象位置

    canvas.onmouseup

    关键部分说明

    接下来开始代码中的关键部分及细节处理

    如何维护拖拽对象数组

    在程序初始化时,我们定义一个polygonArray数组

    polygonArray = []

    在每次画一个新的多边形之后,都会new一个多边形对象推入数组中进行维护

    const polygon = new Polygon(mouseStart.get('x'), mouseStart.get('y'), sideNum, radius);

    polygonArray.push(polygon);//记录路径对象

    在后续点击操作时,需要根据对应信息确定点击位置是否在路径之中

    点击时,如何选取要拖拽的对象

    首先获取点击时在 canvas中 的对应位置,我的代码用 mouseStart 记录 x 及 y

    接着遍历 polygonArray 中的 polygon ,遍历中调用 polygon.createPath() ,通过 isPointInPath() 判断点击位置是否有路径,有的话 draggingPolygon = polygon 结束函数

    const pos = positionInCanvas(e, canvasLeft, canvasTop);//获取在canvas中的像素位置

    //记录鼠标起始点s

    mouseStart.set('x', pos.x);

    mouseStart.set('y', pos.y);

    ...

    for (let polygon of polygonArray) {

    polygon.createPath();

    if (ctx.isPointInPath(mouseStart.get('x'), mouseStart.get('y'))) {

    draggingPolygon = polygon;

    return;

    }

    }

    拖拽时的计算

    这部分要完全理解推荐大家根据Demo中两个 console.log(draggingPolygon) 及代码进行调试,因为我们是在 mousemove 阶段,这个阶段触发函数非常频繁

    我尽量用语言表达清楚

    首先计算 move 时与 mouseStart 的距离,记为diff,有x轴上的 offsetX ,也有y轴上的 offsetY

    const

    pos = positionInCanvas(e, canvasLeft, canvasTop),

    diff = new Map([

    ['offsetX', pos.x - mouseStart.get('x')],

    ['offsetY', pos.y - mouseStart.get('y')]

    ]);

    接着记录当前拖拽对象的 centerX 及 centerY ,记为temp

    let

    tempCenterX = draggingPolygon.centerX,

    tempCenterY = draggingPolygon.centerY;

    这里就是难理解的点,为什么要记录?继续往下看,后面会使用到。

    根据 diff 中的offset,设置draggingPolygon新的中心位置

    draggingPolygon.centerX += diff.get('offsetX');

    draggingPolygon.centerY += diff.get('offsetY');

    接着清空画布进行绘制新的路径和描边

    ctx.clearRect(0, 0, canvas.width, canvas.height);

    for (let polygon of polygonArray) {

    drawPolygonPath(polygon.sideNum,

    polygon.radius,

    polygon.centerX,

    polygon.centerY, ctx);

    ctx.stroke();

    }

    最后使用到上文中的 tempCenterX 与 tempCenterY :

    draggingPolygon.centerX = tempCenterX;

    draggingPolygon.centerY = tempCenterY;

    为什么需要这么做呢?

    因为我们的拖拽是 基于多边形的原位置 ,而 mousemove 阶段并 不能确定函数的最终位置 ,如果这时没有复原的话,会出现 "漂移" ,我把这两行代码注释掉,效果如下:

    390d6921df54eb4be1118789be7628f0.gif

    如果我没说清楚,墙裂推荐大家对代码进行修改和调试

    拖拽后的处理

    拖拽完成后是处于 mouseup 阶段,此时我们已经确定dragginPolygon的最终位置,进行更新即可,最后置为null,排除 在没有拖拽多边形情况下,鼠标在画布上移动触发对应代码

    const

    pos = positionInCanvas(e, canvasLeft, canvasTop),

    offsetMap = new Map([

    ['offsetX', pos.x - mouseStart.get('x')],

    ['offsetY', pos.y - mouseStart.get('y')]

    ]);

    draggingPolygon.centerX += offsetMap.get('offsetX');

    draggingPolygon.centerY += offsetMap.get('offsetY');

    draggingPolygon = null;

    结语

    其实这个功能实现并不难,关键是了解一个概念:通过维护当前显示对象的列表及isPointInPath进行判断来实现追踪

    最后欢迎大家交流学学习

    参考资料

    《HTML5 Canvas核心技术》

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    展开全文
  • 导语 ...Fabric.js 是一个强大而简单的 Javascript HTML5 画布库 Fabric 在画布元素之上提供交互式对象模型 Fabric 还具有 SVG-to-canvas(和 canvas-to-SVG)解析器 为了方便,下面我将通过 vue项目

    导语

    我们想在画布上画个基本的简单形状的时候,使用 Canvas 不会觉得有什么繁琐。但当画布上需要任何形式的互动,绘制复杂的图形和在特定情况需要改变图片的时候,使用原生 canvas API 将会变得很困难。
    而 Fabric 旨在解决这个问题。

    Fabric.js 是一个强大而简单的 Javascript HTML5 画布库
    Fabric 在画布元素之上提供交互式对象模型
    Fabric 还具有 SVG-to-canvas(和 canvas-to-SVG)解析器

    为了方便,下面我将通过 vue项目 为大家讲解如何使用 Fabric

    1. 安装

    yarn add fabric -S
    #or
    npm i fabric -S
    

    也可以在 官网 下载最新 js 文件,通过 script 标签引入

    2. 使用

    <!-- html -->
    <canvas id="canvas" width="500" height="500"></canvas>
    

    2.1 绘制一个简单的图形

    Fabric 提供了 7 种基础形状:

    • fabric.Circle (圆)
    • fabric.Ellipse (椭圆)
    • fabric.Line (线)
    • fabric.Polyline (多条线绘制成图形)
    • fabric.triangle (三角形)
    • fabric.Rect (矩形)
    • fabric.Polygon (多边形)
    • 矩形
    // js
    
    //引入fabric
    import { fabric } from "fabric";
    
    // 创建一个fabric实例
    let canvas = new fabric.Canvas("canvas"); //可以通过鼠标方法缩小,旋转
    // or
    // let canvas = new fabric.StaticCanvas("canvas");//没有鼠标交互的fabric对象
    
    // 创建一个矩形对象
    let rect = new fabric.Rect({
        left: 200, //距离左边的距离
        top: 200, //距离上边的距离
        fill: "green", //填充的颜色
        width: 200, //矩形宽度
        height: 200, //矩形高度
    });
    
    // 将矩形添加到canvas画布上
    canvas.add(rect);
    

    可以看到界面中填充了一个可以通过鼠标放大缩小且可以旋转的绿色矩形
    通过对象的形式配置元素样式,非常的方便!

    • 圆形和三角形
    // 创建一个圆形对象
    let circle = new fabric.Circle({
        left: 0, //距离左边的距离
        top: 0, //距离上边的距离
        fill: "red", //填充的颜色
        radius: 50, //圆的半径
    });
    // 创建一个三角形对象
    let triangle = new fabric.Triangle({
        left: 200, //距离左边的距离
        top: 0, //距离上边的距离
        fill: "blue", //填充的颜色
        width: 100, //宽度
        height: 100, //高度
    });
    // 将图形形添加到canvas画布上
    canvas.add(circle, triangle);
    

    我们可以通过以下属性设置,决定是否可以对相关元素进行交互

    canvas.selection = false; // 禁止所有选中
    rect.set("selectable", false); // 只是禁止这个矩形选中
    

    2.2 绘制图片

    主要有通过 url 和 img 标签绘制两种方式

    //通过url绘制图片
    fabric.Image.fromURL(
        //本地图片需要通过require来引入,require("./xxx.jpeg")
        "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.thaihot.com.cn%2Fuploadimg%2Fico%2F2021%2F0711%2F1625982535739193.jpg&refer=http%3A%2F%2Fimg.thaihot.com.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1630940858&t=e1d24ff0a7eaeea2ff89cedf656a9374",
        (img) => {
            img.scale(0.5);
            canvas.add(img);
        }
    );
    //也可以通过标签绘制
    let img = document.getElementById("img");
    let image = new fabric.Image(img, {
        left: 100,
        top: 100,
        opacity: 0.8,
    });
    canvas.add(image);
    

    2.3 通过自定义的路径绘制

    在此之前我们需要了解几个参数的含义

    • M : “move”移动到某点
    • L : “line”画线 x,y
    • C : “curve”曲线
    • A : “arc”弧
    • z : 闭合路径(类似 PS 中的创建选区)
    let customPath = new fabric.Path("M 0 0 L 300 100 L 170 100  z");
    customPath.set({
        left: 100,
        top: 100,
        fill: "green",
    });
    canvas.add(customPath);
    

    let customPath = new fabric.Path(
        "M 0 0 L 300 100 L 170 100 L 70 300 L 20 200 C136.19,2.98,128.98,0,121.32,0 z"
    );
    

    可以看到通过路径绘制,我们可以制作非常复杂的图形(但是一般用不到,我们一般用它来解析 SVG 后拿到 path 复原图形)

    2.4 动画

    第一个参数是动画的属性,第二个参数是动画的最终位置,第三个参数是一个可选的对象,指定动画的细节:持续时间,回调,动效等。

    第三个参数主要有

    • duration 默认为 500ms。可以用来改变动画的持续时间。
    • from 允许指定动画属性的起始值(如果我们不希望使用当前值)。
    • onComplete 动画结束之后的回调。
    • easing 动效函数。

    2.4.1 绝对动画

    let canvas = new fabric.Canvas("canvas");
    let rect = new fabric.Rect({
        left: 400, //距离左边的距离
        top: 200, //距离上边的距离
        fill: "green", //填充的颜色
        width: 200, //宽度
        height: 200, //高度
    });
    rect.animate("left", 100, {
        onChange: canvas.renderAll.bind(canvas),
        duration: 1000,
    });
    canvas.add(rect);
    

    2.4.2 相对动画(第二个参数通过+=,-=等来决定动画的最终效果)

    rect.animate("left", "+=100", {
        onChange: canvas.renderAll.bind(canvas),
        duration: 1000,
    });
    

    rect.set({ angle: 45 });
    rect.animate("angle", "-=90", {
    onChange: canvas.renderAll.bind(canvas),
    duration: 2000,
    });
    

    2.4.3 定义动画的动效函数

    默认情况下,动画使用“easeInSine”动效执行。如果这不是你需要的,fabric 为我们提供了很多内置动画效果, fabric.util.ease 下有一大堆动效的选项。
    常用的有easeOutBounce,easeInCubiceaseOutCubiceaseInElasticeaseOutElasticeaseInBounceeaseOutExpo

    rect.animate("left", 100, {
        onChange: canvas.renderAll.bind(canvas),
        duration: 1000,
        easing: fabric.util.ease.easeOutBounce,
    });
    

    2.5 图像滤镜

    目前 Fabric 为我们提供了以下内置滤镜

    • BaseFilter 基本过滤器
    • Blur 模糊
    • Brightness 亮度
    • ColorMatrix 颜色矩阵
    • Contrast 对比
    • Convolute 卷积
    • Gamma 伽玛
    • Grayscale 灰度
    • HueRotation 色调旋转
    • Invert 倒置
    • Noise 噪音
    • Pixelate 像素化
    • RemoveColor 移除颜色
    • Resize 调整大小
    • Saturation 饱和

    2.5.1 单个滤镜

    fabric.Image.fromURL(require("./aaa.jpeg"), (img) => {
        img.scale(0.5);
        canvas.add(img);
    });
    fabric.Image.fromURL(require("./aaa.jpeg"), (img) => {
        img.scale(0.5);
        // 添加滤镜
        img.filters.push(new fabric.Image.filters.Grayscale());
        // 图片加载完成之后,应用滤镜效果
        img.applyFilters();
        img.set({
            left: 300,
            top: 250,
        });
        canvas.add(img);
    });
    

    2.5.2 叠加滤镜

    “filters”属性是一个数组,我们可以用数组方法执行任何所需的操作:移除滤镜(pop,splice,shift),添加滤镜(push,unshift,splice),甚至可以组合多个滤镜。当我们调用 applyFilters 时,“filters”数组中存在的任何滤镜将逐个应用,所以让我们尝试创建一个既色偏又明亮(Brightness)的图像。

    fabric.Image.fromURL(require("./aaa.jpeg"), (img) => {
        img.scale(0.5);
        // 添加滤镜
        img.filters.push(
            new fabric.Image.filters.Grayscale(),
            new fabric.Image.filters.Sepia(), //色偏
            new fabric.Image.filters.Brightness({ brightness: 0.2 }) //亮度
        );
        // 图片加载完成之后,应用滤镜效果
        img.applyFilters();
        img.set({
            left: 300,
            top: 250,
        });
        canvas.add(img);
    });
    

    可以看到多个滤镜的效果叠加显示了,当然 Fabric 还支持自定义滤镜,在本篇文章点赞过 500 后我将更新 fabric 高级篇,感谢大家的支持~

    2.6 颜色

    无论你是使用十六进制,RGB 或 RGBA 颜色,Fabric 都能处理的很好

    2.6.1 定义颜色

    new fabric.Color("#f55");
    new fabric.Color("#aa3123");
    new fabric.Color("356333");
    new fabric.Color("rgb(100,50,100)");
    new fabric.Color("rgba(100, 200, 30, 0.5)");
    

    2.6.2 颜色转换

    new fabric.Color('#f55').toRgb(); // "rgb(255,85,85)"
    new fabric.Color('rgb(100,100,100)').toHex(); // "646464"
    new fabric.Color('fff').toHex(); // "FFFFFF"
    

    我们还可以用另一种颜色叠加,或将其转换为灰度版本。

    let redish = new fabric.Color("#f55");
    let greenish = new fabric.Color("#5f5");
    redish.overlayWith(greenish).toHex(); // "AAAA55"
    redish.toGrayscale().toHex(); // "A1A1A1"
    

    2.7 渐变

    Fabric 通过 setGradient 方法支持渐变,在所有对象上定义。调用 setGradient(‘fill’, { … })就像设置一个对象的“fill”值一样。

    let circle = new fabric.Circle({
      left: 100,
      top: 100,
      radius: 50
    });
    
    circle.setGradient("fill", {
        // 渐变开始的位置
        x1: 0,
        y1: 0,
        // 渐变结束的位置
        x2: circle.width,
        y2: 0,
        //渐变的颜色
        colorStops: {
            // 渐变的范围(0,0.1,0.3,0.5,0.75,1)0-1之间都可以
            0: "red",
            0.2: "orange",
            0.4: "yellow",
            0.6: "green",
            0.8: "blue",
            1: "purple"
        },
    });
    

    2.8 文本

    fabric.Text 对象对于文本,提供了比 canvas 更丰富的功能,包括:

    • 支持多行 Multiline support 不幸的是,原生文本方法忽略了新建一行。
    • 文本对齐 Text alignment 左,中,右。使用多行文本时很有用。
    • 文本背景 Text background 背景也支持文本对齐。
    • 文字装饰 Text decoration 下划线,上划线,贯穿线。
    • 行高 Line Height 在使用多行文本时有用。
    • 字符间距 Char spacing 使文本更紧凑或更间隔。
    • 子范围 Subranges 将颜色和属性应用到文本对象的子对象中。
    • 多字节 Multibyte 支持表情符号。
    • 交互式画布编辑 On canvas editing 可以直接在画布上键入文本。
    let text = new fabric.Text(
        "大家好~这里是前埔寨\n我是荣顶~\n一个要成为开发王的男人!",
        {
            left: 0,
            top: 200,
            fontFamily: "Comic Sans", //字体
            fontSize: 50, //字号
            fontWeight: 800, //字体粗细,可以使用关键字(“normal”,“bold”)或数字(100,200,400,600,800)
            shadow: "green 3px 3px 2px", //文字阴影,颜色,水平偏移,垂直偏移和模糊大小。
            underline: true, //下划线
            linethrough: true, //删除线
            overline: true, //上划线
            fontStyle: "italic", //字体风格,normal(正常)或italic(斜体)
            stroke: "#c3bfbf", //描边的颜色
            strokeWidth: 1, //描边的宽度
            textAlign: "center", //文本对齐方式
            lineHeight: 1.5, //行高
            textBackgroundColor: "#91A8D0", //文本背景颜色
        }
    );
    canvas.add(text);
    

    2.9 事件

    fabric 中通过 on 方法来初始化事件,off 方法用来删除事件。

    常用的事件有以下

    • “mouse:down” 鼠标被按下
    • “object:add” 对象被添加
    • “after:render” 渲染完成

    还有一大堆:
    鼠标事件:“mouse:down” ,“mouse:move”和“mouse:up…”
    选择相关的事件:“before:selection:cleared”, “selection:created”,
    详细的可以查看 官方文档

    canvas.on("mouse:down", function(options) {
        canvas.clear();
        let text = new fabric.Text("你点我啦~", {
            left: 200,
            top: 200,
        });
        canvas.add(text);
        console.log(options.e.clientX, options.e.clientY);
    });
    canvas.on("mouse:up", function(options) {
        this.text = "你没点我0.0";
        canvas.clear();
        let text = new fabric.Text("你没点我0.0", {
            left: 200,
            top: 200,
        });
        canvas.add(text);
        console.log(options.e.clientX, options.e.clientY);
    });
    

    Fabric 允许将侦听器直接附加到 canvas 画布中的对象上。

    let rect = new fabric.Rect({ width: 100, height: 50, fill: "green" });
    rect.on("selected", function() {
        console.log("哦吼~你选择了我");
    });
    
    let circle = new fabric.Circle({ radius: 75, fill: "blue" });
    circle.on("selected", function() {
        console.log("哈哈哈~你选择了我");
    });
    

    3.0 自由绘画

    Fabric canvas 的 isDrawingMode 属性设置为 true 即可实现自由绘制模式.
    这样画布上的点击和移动就会被立刻解释为铅笔或刷子。

    let canvas = new fabric.Canvas("canvas");
    canvas.isDrawingMode = true;
    canvas.freeDrawingBrush.color = "blue";
    canvas.freeDrawingBrush.width = 5;
    

    最后

    很开心写下这篇文章,它是我用来总结归纳 fabric 的知识点并且非常用心的一篇文章,希望这篇文章对你有所帮助,目前 fabric 在国内还不是很火,但是 github 上已经有 19.2k 的 star 了,也算是一个明星项目.我们日常开发经常会用到 canvas,但是它的 api 对于处理复杂的业务逻辑会令人感到非常的劳累,所以我分享这篇文章,希望对大家有所帮助,点赞超过 500 我会更新 fabric.js 高级篇,感谢你的支持!

    很高兴可以和大家一起变强!
    关注我的公众号,前埔寨。我是荣顶,和我一起在键帽和字符上横跳,代码与程序中穿梭。🤞

    原创不易,转载请注明出处!

    展开全文
  • canvas绘制矩形组件 <template> <div class="img-intercept-content" :style="hotStyle"> <div class="imgContainer" :style="hotStyle" ref="imgContainer"> <canvas ref
  • 基于参考文献,学习并在Canvas实现物体基本运动
  • 最近做了一个人员轨迹运动的需求, 来分享下代码. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>轨迹运动</title> <style> .canvas-...
  • 调用createLinearGradient()方法创建一个linearGradient对象 var gnt = cxt.createLinearGradient(x1, y1, x2, y2); x1、y1表示渐变色开始的坐标 x2、y2表示渐变色结束的坐标 添加渐变(开始) gnt....
  • 、是否在闭合路径内 1. 几何判断(适合规则图形) 矩形: function isInsideRect (x0, y0, width, height, x, y) { return x &gt;= x0 &amp;&amp; x &lt;= (x0 + width) &amp;&amp; ...
  • canvas实现点线动画效果

    千次阅读 2019-05-10 21:38:09
    Dots实例的初始化方法,在canvas中绘制一个点,并确定这个Dots实例移动的方向与速度(由sx与sy决定,即确定sx与sy的值) // 初始化点的方法 x/y为可选参数 为生成点的位置 不传则随机生成 init : function ...
  • canvas 2d 绘图

    2021-08-10 16:53:25
    canvas 2d 绘图 约定原则:手绘画图原则 画布 一张无线大的能作画的布,默认以左上角顶点位置为原始坐标 画笔 只能够变换任何颜色,任意粗细程度的画笔 填充 在绘制的范围内填充任何颜色,包含渐变和透明 图形 ...
  • Python求两之间的直线距离(2种实现方法)方法:#导入math包import math#定义的函数class Point:def __init__(self,x=0,y=0):self.x=xself.y=ydef getx(self):return self.xdef gety(self):return self.y#定义...
  • canvas系列教程05 ——交互、动画

    千次阅读 2022-04-24 17:50:15
    //将tools定义为window对象的属性,该属性的值是一个对象 window.tools = {}; //获取鼠标位置 window.tools.getMouse = function (element) { //定义一个mouse的对象 var mouse = { x: 0, y: 0 }; //为传入的元素...
  • H5 Canvas画布基础

    2021-03-10 10:36:23
    H5 画布基础H5 Canvas画布基础知识笔记基本用法矩形绘制路径绘制Save & Restorecanvas 签名画板canvas 曲线canvas 变换canvas-实例1(变换) :钟表图片 H5 Canvas画布基础知识笔记      ...
  • 前言之前在某网站上看到了一个canvas绘制的动画效果,虽然组成的元素很简单,只有和线,但是视觉效果却非常炫丽,当下就非常想自己把他实现一遍。因为工作原因这个想法搁置了一段时间,前不久忽然想起来,就抽空...
  • canvas 文字颜色_Canvas 超全教程

    千次阅读 2020-11-22 03:38:59
    一个可以使用脚本(通常为JavaScript)来绘制图形的 HTML 元素.例如,它可以用于绘制图表、制作图片构图或者制作简单的(以及不那么简单的)动画.<canvas> 最早由Apple引入WebKit,用于Mac OS X 的 Dashboard,...
  • MDN文档 canvas教程笔记

    2020-12-29 11:45:55
    MDN Canvas教程API Canvas​Rendering​Context2D即canvas.getContext('2d')返回的对象类型,几乎所有作图操作基于这个“上下文对象”而非canvas dom... y, width, height)绘制一个填充的矩形strokeRect(x, y, width...
  • Canvas

    2021-04-23 17:27:46
    我们使用canvas绘制了一个图形,一旦绘制成功了,canvas就像素化了它们。 canvas没有能力,从画布上再次得到这个图形,也就是说我们没有能力去修改已经在画布上的内容,这个就是canvas比较轻量的原因 ​ 如果我们想...
  • canvas :可以理解为一个div,作用是一块画板 如果想要使用canvas,需要创建一个“画家”。生成画家的方法: var huaban = document.querySelector('.canvas');//画板 var bicaso = huaban.getContext('2d');//画家 ...
  • canvas绘图

    2019-07-11 15:40:24
    在react项目中使用canvas绘图,在原有图片上绘制批阅痕迹, 支持撤回功能,保留前面的绘图痕迹,在绘制完毕后合成一张新的图片
  • 画路径模式: 前后点击任意两个节点,则会在这两个节点间生成一个连线,并产生一个随机的路径距离!">画线 计算最短路径模式: 前后点击任意两个节点,则会计算最短路径并用红线标出最短路径!">求最短距离 ...
  • 项目需求:本项目中为自己的毕设项目,其中有一个模块需要通过APP进行码垛设计,并将码垛的结果发送给机械手的控制器。该模块的需求具体如下:1. 可以从物料库中拖动项目的物料模块到码盘。2. 用户将对应的图形模块...
  • canvas——路径搜索

    2017-06-07 13:35:00
    接下来以A*算法为例,迷宫是一个连通图,因此可以寻找到地图上可通行的任意两间的路径。 A*算法 A*算法的目的是求出最低通过成本,利用它来寻找最优路径。 A*算法的核心在于它的估值函数:f(n)=g(n)+h(n)...
  • 前几天师妹突然火急火燎的的给我打电话...画布是一个矩形区域,您可以控制其每一像素。 canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。 {canvas元素用于在网页上绘制图形} 1.如何使用? 进门! ①创建
  • wpf canvas折线图和点图

    2021-03-30 15:17:37
    i += 1)//作480个刻度,因为当前x轴长 480px,每10px作一个小刻度,还预留了一些小空间 { Line x_scale = new Line(); x_scale.StrokeEndLineCap = PenLineCap.Triangle; x_scale.StrokeThickness = 1; x_scale....
  • canvas详解(2)-事件处理

    千次阅读 2018-08-13 10:35:08
    canvas因为是画布的原因,实际上我们可以将它当做一张图片,所以在html中,无论这个canvas包含多少元素,多少图形,他都只有一个tag显示。那么它当中的图形事件也只能添加到canvas元素自身上了。 既然所有的的事件...
  • Canvas学习参考文档

    千次阅读 热门讨论 2021-02-01 22:17:11
    创建Canvas元素Canvas坐标系通过JavaScript来绘制Canvas的基本使用图形绘制设置样式画笔实例练习渐变色绘制镂空的房子绘制坐标网格绘制坐标系绘制坐标绘制折线图参考文档Canvas图形绘制矩形绘制...
  • canvas详解(1)-原理

    千次阅读 2018-08-13 10:24:51
    canvas本身并不具备绘画能力,它本身只是一个画布,是一个容器。绘图能力是基于html5的getContext("2d")返回的CanvasRenderingContext2D对象来完成的。 const canvas = document.getElementById("...
  • canvas基础

    2021-02-02 00:08:04
    介绍canvas的基本知识,动画绘制 通过案例来练习canvas基础知识
  • canvas

    2021-01-16 17:52:37
    是 HTML5 新增的,一个可以使用脚本(通常为 JavaScript )在其中绘制图像的 HTML 元素。它可以用来制作照片集或者制作简单(也不是那么简单)的动画,甚至可以进行实时视频处理和渲染。 它最初由苹果内部使用自己 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,576
精华内容 1,430
关键字:

canvas判断一个点离路径的距离

友情链接: debounce_filter.rar