2016-11-13 87 views
0

我想根据fabric.canvas.object中的属性动态地生成div。聚合物中的动态html代码

以下是摘自我的代码。

class Polymer2FabricEdit extends Polymer.Element { 
    static get is() { return 'polymer-2-fabric-edit' } 
    static get config() { 
    return { 
     properties: { 
     canvas: { 
      type: Object, 
      value: null 
     }, 
     ctx: { 
      type: Object, 
      value: null 
     }, 
     canvasWidth: { 
      type: Number, 
      value: 300 
     }, 
     canvasHeight: { 
      type: Number, 
      value: 300 
     }, 
     topProperty: { 
      type: Number, 
      value: 0, 
      notify: true 
     }, 
     observers: [ 
     ] 
    } 
    } 
    constructor() { 
    super(); 
    console.log('created'); 
    } 
    connectedCallback() { 
    super.connectedCallback(); 
    console.log('attached'); 
    } 
    ready() { 
    super.ready(); 
    this.canvas = new fabric.Canvas(this.$.c, {isDrawingMode: false}); 
    console.log(this.canvas); 
    this.ctx = this.canvas.getContext('2d'); 
    this.addEventListener('click', (e)=>this.handleClick(e)); 
    this.addEventListener('change', (e)=>this.handleChange(e)); 
    this.$.dropTargetDiv.addEventListener("dragover", (e)=>this.preventEventDefault(e)); 
    this.$.dropTargetDiv.addEventListener("drop", (e)=>this.loadObject(e)); 
    this.$.imageLoader.addEventListener("change", (e)=>this.readURL(e)); 
    this.$.backgroundImageLoader.addEventListener("change", (e)=>this.readBackgroundURL(e)); 
    this.$.textureImageLoader.addEventListener("change", (e)=>this.readTextureURL(e)); 
    console.log('ready'); 
    } 

    generateEditView(obj) { 

    console.log("generateEditView"); 
    console.log(obj); 
    var html = "<br/><br/><b>Edit Properties</b><br/><br/>"; 
    for(var key in obj) { 
     if(key === "stateProperties") { 
     console.log(key, obj[key]); 
     var o = obj[key]; 
      for(var k in o) { 
      console.log(o[k], obj[o[k]]); 
      switch(o[k]) { 
      case 'top': 
       console.log("setting top from:", this.topProperty); 
       this.topProperty = obj[o[k]]; 
       html += '<input type="number" value="{{topProperty}}" min="0" max="150" id="topProperty">'; 
       html += '<input type="range" value="{{topProperty}}" min="0" max="150" id="topPropertyRange">'; 
       html += '<br/>'; 
       console.log("set to: " + this.topProperty); 
       break; 
      case ‘…’: 
      break; 
default; 
    } 
    console.log("adding: " + html); 
    this.$.editView.innerHTML = html; 
    } 


    handleClick(e) { 
    console.log("hamdleClick: " + e.type); 
    console.log("click: " + e.currentTarget.tagName); 
    console.log(e); 
    var id = e.path[0].id; 
    console.log("id: " + id); 
    switch(id) { 
     case '': 
      console.log("No ID - This is mostlike a selet of an object"); 
      var target = e.target; 
      var obj = this.canvas.getActiveObject(); 
      console.log("target:" + target); 
      console.log("selected Object:" + obj); 
      console.log("selected Menu: " + this.selectedMenu); 
      if(this.selectedMenu === "control") { 
      this.generateEditView(this.canvas.getActiveObject()); 
      } 
      break; 
     break; 
     case 'topProperty': 
      console.log("Change TopProperty", this.$.topProperty); 
      this.topProperty = this.$.topProperty; 
      break; 
     default: 
    } 
    } 

这不工作,我得到以下运行时错误 聚合物-2- edit.html:1979年指定的值“{{topProperty}}”不是一个有效的数字。该值必须与以下正则表达式匹配: - ?(\ d + | \ d +。\ d + |。\ d +)([eE] [ - +]?\ d +)? 看起来生成的代码没有拿起绑定。

如果我将代码更改为以下div,则显示正确。 html + =''; 的html + =“”

但后来读这篇文章,$。topProperty或本。$当我不确定。topPropertyRange 我也曾尝试在后两个加平变化= changeProperty(本),我得到changeProperty是未定义消息在调试器中。

我怀疑它的功能是在聚合物之外,但我需要它在聚合物内来设置对象的属性。

是否有添加动态输入字段和处理更改的示例?

回答

0

我仍然没有成功获得动态HTML生成的代码工作。 我试着用dom重写代码:如果它不按照我想要的方式工作。

这就是说我已经通过编写静态代码并使用css隐藏不需要的选择并显示我需要的部分来实现我的目标。

我加入这个CSS类

.hide { 
    display: none; 
    visibility: hidden; 
} 

然后我会为每个元素的DIV和附加的“编辑”属性名的DIV ID

<div id="topEdit"> 
    <label for="top">Top:</label> 
    <input type="number" value="{{top::input}}" min="0" max="150" id="top"> 
    <input type="range" value="{{top::input}}" min="0" max="150" id="topRange"> 
    <br/> 
</div> 
<div id="leftEdit"> 
    <label for="left">Left:</label> 
    <input type="number" value="{{left::input}}" min="0" max="150" id="left" onchange="{{Change}}"> 
    <input type="range" value="{{left::input}}" min="0" max="150" id="leftRange"> 
    <br/> 
</div> 
<div id="widthEdit"> 
    <label for="width">Width:</label> 
    <input type="number" value="{{width::input}}" min="0" max="150" id="width"> 
    <input type="range" value="{{width::input}}" min="0" max="150" id="widtnRange"> 
    <br/> 
</div> 

我用这个功能来隐藏所有编号为“

”的元素
clearView() { 
    // hide the Edit Elements 
    var elements = this.$; 
    for(var key in elements) { 
     var element = elements[key]; 
     var elementId = element.id; 
     if(!!elementId.match(/.*Edit$/)) { 
      element.classList.add('hide'); 
     } 
    } 
} 

原始代码然后遍历活动目标ct并从赞赏元素中移除了css hide类。由于所选的一些html元素没有直接与objects元素相对应,所以这种方法被修改了,我决定我不想为每个属性提供字段。 修改后的代码基于所选对象类型我利用了一组字段

当用户单击某个对象时,我执行类似于以下示例的代码。

此示例适用于文本或iText对象。

var fields = [ 
    "fontWeight", // normal, bold 
    "fontStyle", // normal, italic, oblique, '' 
    "textDecoration", // underline, linethrough, overline 
    "fontFamily", 
    "textAlign", 
    "stroke", 
    "backgroundColor", 
    "textBackgroundColor", 
    "strokeWidth", 
    "fontSize", 
    "lineHeight", 
    "charSpacing", 
    "shadow", // shadowColor, shadowBlur, shadowOffsetX, shadowOffsetY 
    "shadowColor", 
    "shadowBlur", 
    "shadowOffsetX", 
    "shadowOffsetY", 
    "text", 
    "addText" 
]; 

以下代码将删除css hide类并显示相应的元素。

for(var key in fields) { 
    var id = fields[key] + "Edit"; 
    var element = this.$[id]; 
    if(element) { 
     element.classList.remove('hide'); 
    } 
} 

这种方法适用于我,并为选定的元素提供完整的双向绑定。