Fabric.js 文本字段 - Android 问题

Posted

技术标签:

【中文标题】Fabric.js 文本字段 - Android 问题【英文标题】:Fabric.js Text field - issue with Android 【发布时间】:2014-12-10 08:56:15 【问题描述】:

我正在使用fabric.js,但文本字段存在一些问题。它们显然在 android 设备上不可编辑。我可以选择文本区域,但我不能编辑它。

这是我的代码:

var canvas = new fabric.Canvas('c');
canvas.setHeight(500);
canvas.setWidth(500);
var canvasCenter = canvas.getCenter();

var title_input = new fabric.IText( dimensions.titleArgs['content'], 
    id: 'title',
    lineHeight: 1,
    fontStyle: 'normal',
    fontSize: 50,
    hasControls: false,
    lockMovementX: true,
    lockMovementY: true,
    centerTransform: true,
    top: canvasCenter["top"],
    left: canvasCenter["left"],
    originX: 'left',
    originY: 'bottom',
    fontFamily: "Helvetica Neue", Verdana, Arial, sans-serif'
);
canvas.add(title_input);

canvas.renderAll();

我正在使用fabric v1.4.12,我已经进行了测试

三星 SM-T100(三星 Galaxy Tab 3),Android v. 4.2.2。和 Chrome v. 38.0.212.102 三星 SM-G900F(三星 Galaxy S5),Android v. 4.4.2。和 Chrome v. 38.0.212.102

我在fabricjs.com (http://fabricjs.com/test/misc/itext.html) 上测试了示例,我也遇到了同样的问题。

应用程序在 iPad 和台式电脑上运行正常。

是否有其他人面临同样的问题或知道如何解决?

【问题讨论】:

你能提供一些你是如何添加文本字段的代码吗? @Innodel 我已经用一些示例代码更新了我的问题。 查看您的代码,一切正常,看起来如果您在页面中有任何其他 js,而不是与该 js 到结构的冲突。做一件事,制作一个 JSFiddle,在您的设备上进行测试,如果您遇到任何问题,请通过小提琴链接告诉我 这里是我的 JSFiddle jsfiddle.net/knospe/t4azmeyg的链接 【参考方案1】:

我已经浏览了你的代码,并且在你的小提琴更新后我已经在我的 geonee 手机上测试了你的代码。只需将 lockMovementX 和 lockMovementY 设置为 false。这将适用于 android 和任何地方。希望这会有所帮助

http://jsfiddle.net/t4azmeyg/15/

$j = jQuery.noConflict();

// Set canvas
var canvas = new fabric.Canvas('c');
canvas.selectionColor = 'rgba(255,0,0,1)';
canvas.selectionBorderColor = 'rgba(255,0,0,0.7)';
canvas.selectionLineWidth = 5;
canvas.backgroundColor = '#fff';
canvas.setHeight(500);
canvas.setWidth(500);

var canvasCenter = canvas.getCenter();

// Add background and position it in the center of canvas
var background_rec = new fabric.Rect(
    fill: 'lightblue',
    angle: 0,
    hasControls: false,
    originX: 'center',
    originY: 'center',
    lockMovementX: true,
    lockMovementY: true,
    selectable: false,
    left: canvasCenter["left"],
    top: canvasCenter["top"],
    width: 400,
    height: 225
);
canvas.add(background_rec);

// Position where the background starts
var zero_position_left = canvasCenter["left"] - background_rec.width/2;
var zero_position_top =  canvasCenter["top"] - background_rec.height/2;

var title_input = new fabric.IText('Custom Text', 
					fontFamily: 'arial black',
					fontStyle: 'normal',
					fontSize: $j('#configurator-fontsize').val(),
                    fill: 'red',
					hasControls: false,
					lockMovementX: false,
					lockMovementY: false,
					centerTransform: false,
					left: zero_position_left + 40,
					top: zero_position_top - 0.95*$j("#configurator-fontsize").val(),
					width: 300,
					height: 90
);
canvas.add(title_input);
canvas.sendToBack(title_input);


// Add input field for content1
var content1_input = new fabric.IText('Custom Content', 
					fontFamily: 'arial black',
					fontStyle: 'normal',
					fontSize: $j('#configurator-fontsize').val(),
                    fill: 'red',
					stroke: '#999',
					hasControls: false,
					lockMovementX: true,
					lockMovementY: true,
					left: zero_position_left + 70,
					top: zero_position_top + 60,
					width: 300,
					height: 80
);
canvas.add(content1_input);

canvas.renderAll();


// Canvas actions
// Change text-align
$j("#configurator-align").change(function() 
    // Get active element
    var activeObject = canvas.getActiveObject();
    
    if(activeObject && activeObject.get('type') === 'i-text') 
        activeObject.set(textAlign: $j("#configurator-align").val());
        canvas.renderAll();
     else console.log('No Text Object selected.');
);

// Change font-size
$j("#configurator-fontsize").change(function() 
    // Get active element
    var activeObject = canvas.getActiveObject();
    
    if(activeObject && activeObject.get('type') === 'i-text') 
        if(activeObject == title_input) 
            activeObject.set(fontSize: $j("#configurator-fontsize").val(), top: (zero_position_top - 0.90*$j("#configurator-fontsize").val() ));
         else 
            activeObject.set(fontSize: $j("#configurator-fontsize").val());
        
        canvas.renderAll();
     else console.log('No Text Object selected.');
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<div class="controls">
     <h3>Controls:</h3>

    <p>
        <label>Align:</label>
        <br />
        <select id="configurator-align">
            <option value="left">left</option>
            <option value="center">center</option>
            <option value="right">right</option>
        </select>
    </p>
    <p>
        <label>Font-size:</label>
        <br />
        <select id="configurator-fontsize">
            <!-- Values are given as pixels -->
            <!-- Approximate Conversion from Points to Pixels used -->
            <option value="16">12pt</option>
            <option value="19">14pt</option>
            <option value="22">16pt</option>
            <option value="24">18pt</option>
            <option value="26">20pt</option>
            <option value="29">22pt</option>
            <option value="32">24pt</option>
            <option value="35">26pt</option>
            <option value="37">28pt</option>
            <option value="40">30pt</option>
            <option value="45">34pt</option>
            <option value="48">36pt</option>
        </select>            
</div>

<canvas id="c"></canvas>

【讨论】:

Innodel 感谢您的回复。不幸的是,我不能接受这个答案。即使这解决了 Android 上的问题,这种解决方案是否不可接受,因为它改变了输入字段的性质。输入字段必须保持固定位置。将 lockMovementX 和 lockMovementY 设置为 false 可以让用户重新定位它们。 我已经在我的三星 Galaxy S5 上测试了您的解决方案,并且文本字段不可编辑。所以将 lockMovementX 和 lockMovementY 设置为 false,并不能解决这个问题。【参考方案2】:

由于Android 中大多数键的event.keyCode 值为0,因此fabric 不会将任何内容添加到IText 的内容中。

这个问题没有直接的解决方案;相反,无论何时选择 iText,您都可以关注外部输入字段并根据该输入字段更改 IText 字段的值。这是我的示例jsjiddle。可以将输入字段设置为隐藏,以使 Fabric IText 行为看起来更自然。

同样,这是 Android 的问题,因此任何基于 event.keyCodeevent.charCodeevent.which 读取键值的 javascript 库都可能会失败。

【讨论】:

【参考方案3】:

我最近遇到了同样的问题,问题是由于移动设备中的事件键码。

解决方法不是从每个按键中获取字符,而是绑定一个事件处理程序以输入隐藏文本对象并同步 itext 对象文本。 在fabricjs 中而不是fabric.util.addListener(this.hiddenTextarea, 'keypress', this.onKeyPress.bind(this)); 使用fabric.util.addListener(this.hiddenTextarea, "input", this.thisOnInputText.bind(this))

在事件处理程序 thisOnInputText 中做这样的事情:

this.text = this.hiddenTextarea.value 

就像 _updateTextarea 函数一样。

这是针对fabricjs版本:“1.5.0”

【讨论】:

以上是关于Fabric.js 文本字段 - Android 问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 fabric.js 在画布上绘制文本

Fabric.js 的文本框不换行

文本对齐在 fabric.js 中没有按预期工作

Fabric.js 带有变量的动态文本

Fabric.js 实现文本自动换行

Fabric.js - 带有免费矩形边界框的文本,如 Google 幻灯片