2016-06-15 5 views
0

JSを長年使っていますが、オブジェクトを正しく使用しています。JSオブジェクトのイベント

私はキャンバスを使用してイメージジェネレータを作成しています。これを次にpngとしてダウンロードできます。ユーザーは、入力ボックスを使用して画像にテキストを追加できます。私はこれをJSオブジェクトにして、ページ上に複数のインスタンスを作成できるようにしました。イベントリスナーがテキストを更新することを除いて、すべて正常に動作します。

入力ボックスは、関数に渡されたパラメータによって作成され、ユーザーの入力時にキャンバスを更新できるように、keyupイベントが追加されます。そのことを除いて、これはすべて機能していますが、私はkeyupイベントにどのようなJSオブジェクトを更新するべきかを伝える方法がわかりません。ここで

は私のコードです:

function Canvas_to_img(name, container, image, height, width, content_areas){ 
    // Assign params to object 
    object = this; 
    this.name = name; 
    this.container = container; 
    this.image = image; 
    this.height = height; 
    this.width = width; 
    this.content_areas = content_areas; 

    // Prepare image 
    var imageObj = new Image(); 
    imageObj.src = image; 

    // Add canvas div 
    container.prepend('<div class="canvas canvas--' + name + '"></div>') 

    // Add temp canvas div 
    container.append('<div class="canvas-temp canvas-temp--' + name + '"></div>') 

    // Add canvas wrapper 
    var wrapper = new Concrete.Wrapper({ 
     container: container.find('.canvas')[0], 
     width: width, 
     height: height 
    }); 

    // Add BG and Text layers 
    var bgLayer = new Concrete.Layer(); 
    var textLayer = new Concrete.Layer(); 
    wrapper.add(bgLayer).add(textLayer); 

    // Add image to BG layer 
    imageObj.onload = function() { 
     bgLayer.sceneCanvas.context.drawImage(imageObj,0,0, width, height); 
    }; 

    // Set up input areas and event listeners 
    for (key in content_areas){ 

     for (subkey in content_areas[key].fields){ 
      name_field = content_areas[key].fields[subkey].name; 
      name_layer = content_areas[key].fields[subkey].name; 

      // Add input fields for text layer 
      container.prepend('<div class="field-set__item">\ 
       <span class="field-set__label">' + name_field +'</span>\ 
       <input data-object="'+object+'" data-area="' + key + '" data-name="' + name + '" data-field="' + subkey + '" class="field-set__input ' + name_field + '" id="text1" type="text">\ 
      </div>'); 

      $("."+name_field).keyup(function() { 
       area = $(this).data('area'); 
       field = $(this).data('field'); 
       object = $(this).data('object'); 
       console.log(object); 
       value = $(this).val(); 
       content_areas[key].fields[subkey].name; 
       //content_areas[area].fields[field].value = value; 
       OBJECTNAME.updateContent(area, field, value) 
       OBJECTNAME.updateCanvas(wrapper); 
      }); 
     } 
    } 

    container.append('<a href="#" id="download--' + name +'" class="button download download--' + name + '">Download</a>'); 

    $('body').on('click', '.download--' + name, function(e) { 
     var dataURL = $('.canvas-temp--fb-banner canvas')[0].toDataURL('image/png'); 
     $(this).attr('download', 'test.png'); 
     document.getElementById('download--' + name).href = dataURL; 
    }); 
} 

Canvas_to_img.prototype = { 
    updateContent: function(area, field, value){ 
     this.content_areas[area].fields[field].value = value; 
    }, 

    updateCanvas: function(wrapper) { 
     $('.canvas-temp--'+this.name+' canvas').remove(); 
     wrapper.layers[1].destroy(); 

     var textLayer = new Concrete.Layer(); 
     wrapper.add(textLayer); 

     content_areas = this.content_areas; 

     for (key in content_areas){ 
      textLayer.sceneCanvas.context.fillStyle = content_areas[key].colour; 
      textLayer.sceneCanvas.context.font = "bold 24px Open Sans"; 
      textLayer.sceneCanvas.context.textAlign = content_areas[key].alignment; 
      layer_content = ''; 
      for (subkey in content_areas[key].fields){ 
       //console.log(content_areas[key].fields[subkey]); 
       layer_content += content_areas[key].fields[subkey].prepend + " "; 
       layer_content += content_areas[key].fields[subkey].value; 
       layer_content += content_areas[key].fields[subkey].append + " "; 
       //console.log(layer_content); 
      } 
      textLayer.sceneCanvas.context.fillText(layer_content, content_areas[key].position_x, content_areas[key].position_y); 
     } 

     //ctx.fillText($(this).val(), cnvs.width/2, 300); 
     // textLayer.sceneCanvas.context.fillText('Test', 325, 300); 
     var canvas = wrapper.toCanvas({ 
      pixelRatio: 1 
     }); 
     //console.log(canvas.canvas); 
     $('.canvas-temp--'+this.name).append(canvas.canvas); 
    }, 
    update: function(){ 

    } 
}; 



var content_areas = { 
    1: { 
     position_x: 425, 
     position_y: 300, 
     alignment: 'center', 
     colour: '#fff', 
     font: 'Open Sans', 
     size: '24px', 
     weight: 600, 
     fields: { 
      field_1: { 
       name: 'date', 
       value: '', 
       prepend: '', 
       append: ',' 
      }, 
      field_2: { 
       name: 'venue', 
       value: '', 
       prepend: '', 
       append: '' 
      } 
     } 
    } 
} 

var content_areas_2 = { 
    1: { 
     position_x: 425, 
     position_y: 300, 
     alignment: 'center', 
     colour: '#fff', 
     font: 'Open Sans', 
     size: '24px', 
     weight: 600, 
     fields: { 
      field_1: { 
       name: 'date', 
       value: '', 
       prepend: '', 
       append: ',' 
      }, 
      field_2: { 
       name: 'venue', 
       value: '', 
       prepend: '', 
       append: '' 
      }, 
      field_3: { 
       name: 'time', 
       value: '', 
       prepend: '', 
       append: '' 
      } 
     } 
    } 
} 

var facebook_banner = new Canvas_to_img('fb-banner', $('.banner-container'), 'http://localhost:1234/images/mainsite5/bb-fb-cover.jpg', 315, 851, content_areas); 
var facebook_banner_2 = new Canvas_to_img('fb-banner-2', $('.banner-container-2'), 'http://localhost:1234/images/mainsite5/bb-fb-cover.jpg', 315, 851, content_areas_2); 

は、これらのオブジェクトに関連付けする必要がある関数呼び出しです:

OBJECTNAME.updateContent(area, field, value) 
OBJECTNAME.updateCanvas(wrapper); 

は、私はおそらく代わりに、オブジェクト自体にリンクされているこのイベントリスナーを作成する必要がありますか?私はそれがどうやっているのかは分かりません。

+0

これをデモするには、(https://jsfiddle.net/) –

答えて

0

インスタンスを要素に保存すると便利です。

var facebook_banner = new Canvas_to_img('fb-banner', $('.banner-container'), 'http://localhost:1234/images/mainsite5/bb-fb-cover.jpg', 315, 851, content_areas); 

とその要素のdataプロパティに設定する:あなたはここに割り当てられたインスタンスを取ることによってこれを行うことができます

$('.banner-container').data('canvas_to_img', facebook_banner); 

今、あなたは、あなたがそれを必要とするとき、そのインスタンスを取得することができます:

$('.banner-container').data('canvas_to_img'); 

それとも、すでにその要素のコンテキスト内なら:

$(this).data('canvas_to_img'); 
+0

ありがとう、これはうまくいきました。ヘルプをよろしくお願いいたします。オブジェクトに要素を渡したり返さなくても、これを行う方法があるはずです。 – user3429445

1

updateContentおよびupdateCanvasは、コードの下部に作成するオブジェクトのプロトタイプです。通常、this.updateContent(area, field, value)でアクセスします。 しかし、コールバック関数の内部にあるので、thisはその関数のスコープを参照しています。

これまでのコードでは、object = this;(なぜオブジェクトグローバルb.t.w.ですか?)を設定しているので、コールバック内でアクセスする必要がある変数にthisを格納しています。だからあなたのコードは次のようになります。

object.updateContent(area, field, value);を、など//オブジェクトがあなたのthis

Hereある別の似ているが、単純化した質問です。

+0

'object'を使用すると、作成された最後のオブジェクトが取得されるだけで、すべての変更が最後のイメージに適用されます。 'this.object = this'を試しましたが、それがオブジェクトに割り当てられているので、コールバック関数で参照することはできません。 – user3429445

+0

これは、オブジェクトがグローバルスコープにあり、とにかく悪いためです。 'Canvas_to_img'関数の最初の行として' var that = this; 'を試してください。次に、あなたはそれを行うことができます.updateContent(area、field、value); – Hinrich

関連する問題