试图在FabricJS中创建带有句柄的气泡 [英] Trying to create speech bubble with handle in FabricJS

查看:32
本文介绍了试图在FabricJS中创建带有句柄的气泡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用FabricJS创建气泡,以集成到WordPress插件中(希望)免费发布,以帮助人们注释图像,我在此处找到了原始气泡:

I'm trying to create a speech bubble with FabricJS to integrate into a WordPress plugin to (hopefully) release for free that helps people annotate images, I found the original bubble here on SO here: speech buble html5 canvas js but I'm having a few issues and am a little unsure as to how to go about solving them (I'll keep trying and post a solution here just in case).

fabric.speechBubble = fabric.util.createClass(fabric.Object, fabric.Observable, {

    type: 'speechBubble',

    initialize: function(options) {
        options || (options = {});
        this.callSuper('initialize', options);
        this.set('width', options.width || 200);
        this.set('height', options.height || 100);
        this.set('left', options.left || 100);
        this.set('top', options.top || 100);
        this.set('radius', options.radius || 20);
        this.set('pointerX', options.pointerX || this.left + 300);
        this.set('pointerY', options.pointerY || this.top + 300);
    },

    toObject: function() {
        return fabric.util.object.extend(this.callSuper('toObject'), {
            pointerX : this.get('pointerX'),
            pointerY : this.get('pointerY'),
        });
    },

    _render: function (ctx) {

        //this.callSuper('_render', ctx);

        var r = this.left + this.width;
        var b = this.top + this.height;

        if ( this.pointerY < this.top || this.pointerY > this.top + this.height ) {
            var con1 = Math.min(Math.max(this.left + this.radius, this.pointerX - 10),r-this.radius-20);
            var con2 = Math.min(Math.max(this.left + this.radius + 20,this.pointerX + 10),r-this.radius);
        }
        else {
            var con1 = Math.min(Math.max(this.top + this.radius, this.pointerY - 10),b-this.radius-20);
            var con2 = Math.min(Math.max(this.top + this.radius + 20, this.pointerY + 10),b-this.radius);
        }

        var dir;

        if ( this.pointerY < this.top ) dir = 2;
        if ( this.pointerY > this.top) dir = 3;
        if ( this.pointerX < this.left && this.pointerY >= this.top && this.pointerY <=b ) dir = 0;
        if ( this.pointerX > this.left && this.pointerY >= this.top && this.pointerY <=b ) dir = 1;
        if ( this.pointerX >= this.left && this.pointerX <= r && this.pointerY >= this.top && this.pointerY <= b) dir = -1;

        ctx.beginPath();
        ctx.save();

        console.log(dir);

        ctx.strokeStyle = "red";
        ctx.lineWidth = "3";
        ctx.fillStyle = "white";

        ctx.moveTo(this.left + this.radius, this.top);

        if(dir == 2){
            ctx.lineTo(con1,this.top);
            ctx.lineTo(this.pointerX,this.pointerY);
            ctx.lineTo(con2,this.top);
            ctx.lineTo(r-this.radius,this.top);
        }
        else ctx.lineTo(r-this.radius,this.top);
        ctx.quadraticCurveTo(r,this.top,r,this.top+this.radius);

        if(dir == 1){
            ctx.lineTo(r,con1);
            ctx.lineTo(this.pointerX,this.pointerY);
            ctx.lineTo(r,con2);
            ctx.lineTo(r,b-this.radius);
        }
        else ctx.lineTo(r,b-this.radius);
        ctx.quadraticCurveTo(r, b, r - this.radius, b);

        if(dir==3){
            ctx.lineTo(con2,b);
            ctx.lineTo(this.pointerX,this.pointerY);
            ctx.lineTo(con1,b);
            ctx.lineTo(this.left+this.radius,b);
        }
        else ctx.lineTo(this.left+this.radius,b);
        ctx.quadraticCurveTo(this.left, b, this.left, b-this.radius);

        if(dir==0){
            ctx.lineTo(this.left,con2);
            ctx.lineTo(this.pointerX,this.pointerY);
            ctx.lineTo(this.left,con1);
            ctx.lineTo(this.left,this.top+this.radius);
        }
        else ctx.lineTo(this.left,this.top+this.radius);
        ctx.quadraticCurveTo(this.left, this.top, this.left+this.radius, this.top);

        ctx.stroke();
        ctx.restore();
        this._renderFill(ctx);
        this._renderStroke(ctx);
    }
});

这是我现在所拥有的JSFiddle: http://jsfiddle.net/xu2nzjv2/7/

Here is a JSFiddle of what I have now: http://jsfiddle.net/xu2nzjv2/7/

我的第一件事是,当我将气泡添加到画布时,选择区域在左上角很远-即使指针指向左或右,也会发生这种情况.我还想知道是否有办法以某种方式锁定指针的位置,除非像上面的Stackoverflow画布形状那样专门拖动指针.

My first thing is when I add the bubble to the canvas the selection area is way off in the top left - that happens even when the pointer is pointing down left or right. I would also like to know if there is a way to lock the position of the pointer somehow unless it specifically is dragged like in the Stackoverflow canvas shape above.

第二件事是我想知道是否有一种方法可以像现在一样使点可拖动,但还可以移动整个气泡.一旦使边界/选择框工作,这部分可能不会太难,因为我认为我可以制造一个工具,因此,如果单击它,则画布仅侦听指针的重新放置.

The second thing is I was wondering if there was a way to make the point draggable like it is now but also be able to move the entire bubble. This part might not be too hard once I have the bounding/selection box thing working since I figure I can just make a tool so that if it is clicked then the canvas is only listening for the repositioning of the pointer.

任何帮助都是超级超级感谢!

Any help is super super appreciated!

推荐答案

有一个很酷的库,叫做 ComicBubbles 我刚刚发现的.我已将您链接到他们的第三个演示,该演示展示了可移动手柄.希望这会有所帮助.

There's a pretty cool library called ComicBubbles that I just found. I've linked you to their third demo which showcases the movable handle. Hopefully this helps.

这篇关于试图在FabricJS中创建带有句柄的气泡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆