2017-01-11 40 views
2

私は、提供されている画像のリストから画像を選択するアプリを開発しています。ユーザーがリストからイメージをクリックすると、選択したイメージがキャンバス上に背景として表示されます。私はreactjs、reduxとfabricjsを使ってこれを開発しています。キャンバスに選択された画像が表示されない

私は setCanvasBackgroundに更新することができますので、私は this.props.getSelectedImage.image.imageを行う際に、選択した画像を得るいけません。

画像list.js

class Images extends React.Component { 
    renderImages() { 
    const { images, selectImage } = this.props; 
    return _.map(images, (image, key) => 
     <li key={key}> 
     <img 
      src={image.image} 
      alt={image.id} 
      className="responsive-img default-images" 
      width="400px" 
      onClick={() => selectImage(image)} 
     /> 
     </li> 
    ); 
    } 
    render() { 
    return (
     <ul className="image-list"> 
     {this.renderImages()} 
     </ul> 
    ); 
    } 
} 

const mapStateToProps = (state) => { 
    return { 
    images: state.images 
    } 
}; 

const mapDispatchToProps = (dispatch) => { 
    return bindActionCreators({ selectImage: selectImage }, dispatch); 
} 

export default connect(mapStateToProps, mapDispatchToProps)(Images); 

をactions.js

export function selectImage(image) { 
    return { 
    type: 'SELECT_IMAGE', 
    payload: image 
    } 
} 

reducers.js

const initialState = { 
    selectedImage: require('./img/image1.jpg') 
}; 

export function getSelectedImage(state = initialState, action) { 
    switch (action.type) { 
    case 'SELECT_IMAGE': 
     return Object.assign({}, state, { selectedImage: action.payload.image }) 
    default: 
     return state; 
    } 
} 

画像board.js

class ImageBoard extends React.Component { 
    constructor() { 
    super(); 
    this.state = { 
     canvas: undefined, 
     selected: undefined 
    }; 
    } 

    componentDidMount() { 
    const canvas = new fabric.Canvas('canvas'); 
    this.setCanvasBackground(this.props.getSelectedImage.selectedImage, canvas); 
    } 

    setCanvasBackground(image, canvas) { 
    canvas.setBackgroundImage(image, function(e) { 
    let iw = canvas.backgroundImage.width, 
      ih = canvas.backgroundImage.height, 
      cw = canvas.getWidth(), 
      ch = canvas.getHeight(); 

    let iar = iw/ih, 
     car = cw/ch; 

    let nw = cw, 
     nh = ch; 

    if (iar > car){ 
     nh = ch; 
     nw = nh * iar; 
    } 
    else if (iar < car){ 
     nw = cw; 
     nh = cw/iar; 
    } 
    canvas.backgroundImage.width = nw; 
    canvas.backgroundImage.height = nh; 
    canvas.renderAll(); 
    }.bind(this)); 
    } 

    render() { 
    return(
     <div className="image-board"> 
     <canvas 
      id="canvas" 
      className="z-depth-1" 
      width={600} 
      height={400} 
     /> 
     </div> 
    ); 
    } 
} 

const mapStateToProps = (state) => { 
    console.log('state', state); 
    return { 
    images: state.images, 
    getSelectedImage: state.getSelectedImage 
    } 
}; 

export default connect(mapStateToProps)(ImageBoard); 

今私は、デフォルトの画像を表示することができますが、リストから画像がclicked.Howeverあるとき、私は取得機能をレンダリングする内部console.log('image selected', this.props.getSelectedImage.image.image);を入れたときにキャンバスの背景画像を変更することができませんでした選択したイメージを表示できますが、これをsetBackgroundImageで設定できませんでした。選択したイメージをキャンバスに表示できます。

どうすればいいですか?

はv15.4.2を反応

UPDATE

componentDidUpdate() { 
    console.log('componentDidUpdate'); 
    const canvas = new fabric.Canvas('canvas'); 
    this.setCanvasBackground(this.props.getSelectedImage.selectedImage, canvas); 
    } 

私はcomponentDidUpdateライフサイクルメソッドを使用している場合、それは動作しますが、私は次のような結果を得るために使用されてきました。多くのキャンバスは再作成され、キャンバスを更新するためにcomponentDidUpdateにキャンバスのオブジェクトを作成したので、そのことを知っています。どうすればいいですか?

enter image description here

+1

私は、 'const canvas = new fabric.Canvas( 'canvas');'という行を使って複数のキャンバス要素をDOMに追加していることを暗示しています。 DOMをチェックして、レンダリングするたびに新しいキャンバス要素があるかどうか確認できますか? –

+0

新しいキャンバス要素を作成するたびに、リストの新しい画像形式を選択します。私はそれがcomponentDidUpdateのためだと知っていますが、もし私が選択したイメージがキャンバスに表示されないようにしてください。あなたは私を助けてくれますか? – Serenity

答えて

0

私はこれには2つの潜在的な解決策を参照してください。

How to destroy/reload the canvas in html 5?

  • は、DOM(これだけ新しいものを持っています)から古いキャンバスを削除します。
    componentDidUpdate() { 
        console.log('componentDidUpdate'); 
        // Get the old canvas and remove it 
        var oldCanvas = document.getElementById('canvas'); 
        oldCanvas = null; 
    
        // Add your completely new canvas 
        const canvas = new fabric.Canvas('canvas'); 
        this.setCanvasBackground(this.props.getSelectedImage.selectedImage,  canvas); 
    } 
    
    • クリア新しいものを再描画する前に、古いキャンバス:

    Redrawing Canvas in HTML5 using Javascript

    あなたは上記のリンクに記載されたものを実行する必要があるキャンバスをクリアします。この方法を使用している場合は、componentDidUpdate()のページに新しいキャンバスを追加しないでください。

    2番目の解決方法のリンクでは、キャンバスをクリアしないと描画された要素が重なって表示されると具体的に言及されています。

+0

キャンバスをクリアしたい場合は、キャンバス要素を作成する直前にcomponentDidUpdateからclear関数を呼び出す必要があります。 – Serenity

+0

キャンバスをクリアする場合は、document.getElementById( 'canvas')を使って古いキャンバスを取得し、それをcomponenentDidUpdateでクリアすることができます。 –

+0

私はcomponentDidUpdate()を行った{ const oldCanvas = document.getElementById( 'canvas'); oldCanvas.clear(); const canvas = new fabric.Canvas( 'canvas');これは、 } しかし、私はoldCanvas.clearが関数エラーではありません – Serenity

関連する問題