Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/406.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 尝试在FabricJS中使用句柄创建语音气泡_Javascript_Html_Html5 Canvas_Fabricjs - Fatal编程技术网

Javascript 尝试在FabricJS中使用句柄创建语音气泡

Javascript 尝试在FabricJS中使用句柄创建语音气泡,javascript,html,html5-canvas,fabricjs,Javascript,Html,Html5 Canvas,Fabricjs,我正试图用FabricJS创建一个语音泡泡,以集成到WordPress插件中(希望)免费发布,帮助人们注释图像,我在这里发现了原始泡泡:但我有一些问题,有点不确定如何着手解决它们(我将继续尝试并在这里发布一个解决方案,以防万一) fabric.speechBubble=fabric.util.createClass(fabric.Object,fabric.Observable{ 键入:“speechBubble”, 初始化:函数(选项){ 选项| |(选项={}); this.callSupe

我正试图用FabricJS创建一个语音泡泡,以集成到WordPress插件中(希望)免费发布,帮助人们注释图像,我在这里发现了原始泡泡:但我有一些问题,有点不确定如何着手解决它们(我将继续尝试并在这里发布一个解决方案,以防万一)

fabric.speechBubble=fabric.util.createClass(fabric.Object,fabric.Observable{
键入:“speechBubble”,
初始化:函数(选项){
选项| |(选项={});
this.callSuper('initialize',options);
此.set('width',options.width | | 200);
此.set('height',options.height | | 100);
此.set('left',options.left | | 100);
此.set('top',options.top | | 100);
此.set('radius',options.radius | | 20);
this.set('pointerX',options.pointerX | | this.left+300);
this.set('pointerY',options.pointerY | | this.top+300);
},
toObject:function(){
返回fabric.util.object.extend(this.callSuper('toObject'){
pointerX:this.get('pointerX'),
pointerY:this.get('pointerY'),
});
},
_渲染:函数(ctx){
//这个.callSuper(“'u render',ctx”);
var r=this.left+this.width;
var b=this.top+this.height;
if(this.pointerYthis.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);
}
否则{
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;
如果(this.pointerYthis.top)dir=3;

如果(this.pointerX=this.top&&this.pointerY此.left&&this.pointerY=this.left&&this.pointerX=this.top&&this.pointerY我刚刚找到了一个非常酷的库,名为。我已经将您链接到他们展示可移动手柄的第三个演示。希望这会有所帮助。

d最终完成这项工作-你可以看到我在这里所做的基本上是将现有的文本框克隆,然后在其周围添加一个边框,最后将其附加到一个箭头/三角形上,该箭头/三角形用作位于文本框下方的指针,与边框颜色相同
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);
    }
});