2017-07-19 3 views
0

Ich habe ein Dienstprogramm, das ein Thumbnail für ein Video erzeugt und es als zurückgibt. Ich möchte dieses Element machen in Reaktion, etwa so:Wie rende ich ein `HTMLcanvasElement` in React?

render() { 
    return (
     <div className='video-thumbnail'> 
     {this.props.videoThumbnailCanvas} 
     </div> 
    ); 
} 

Aber wenn ich versuche, dass ich einen Fehler, dass:

Error: Objects are not valid as a React child (found: [object HTMLCanvasElement]).

Was ist ein guter Weg, dies zu tun? Eine Idee besteht darin, eine direkte DOM-Manipulation von componentDidMount (z. B. React.getDOMNode(this).appendChild(this.props.videoThumbnailCanvas)) durchzuführen, aber das scheint ziemlich hackig zu sein.

+0

Steuern Sie die Dienstprogrammfunktion? Kannst du es stattdessen ein ' '' JSX Element zurückgeben lassen? –

+0

@DannyDelott - Ich kontrolliere es. Es sieht im Moment in etwa so aus: ' Funktion getThumb() { let Canvas: HTMLCanvasElement = document.createElement (' Leinwand '); Lassen Sie Kontext = canvas.getContext ('2d'); if (Kontext) { context.drawImage (videoElement, 0, 0, w, h); } Rückkehr Canvas; } ' Ich bin mir nicht sicher, wie ich mit einem JSX-Element in den Kontext ziehen würde. – allenrabinovich

+0

Ich glaube, Sie können 'document.creteElement' nicht in Ihrem' getThumb() ' – Muhaimin

Antwort

0

bekam ich das gleiche Problem und Sie können auf 2 Arten lösen:

der einfache Weg:

render() { 
    const src = this.props.videoThumbnailCanvas.toDataUrl(); 
    return (
     <div className='video-thumbnail'> 
     <img src={src} /> 
     </div> 
    ); 
} 

andersrum ich mehr mag (aber ist persönlich):

onComponentDidMount() { 
    const element = document.getElementById('uniquePlaceHolderKey'); 
    element.parentNode.replaceChild(this.props.videoThumbnailCanvas, element); 
} 

render() { 
    return (
     <div className='video-thumbnail'> 
     <div id="uniquePlaceHolderKey" ></div> 
     </div> 
    ); 
} 

Mit dieser zweiten Lösung können Sie ein temporäres Element laden, das Sie mit Ihrer eigenen bemalten Leinwandinstanz austauschen. Ich habe keine passende Lösung gefunden, um das Anfügen eines vorgerenderten Canvas-Elements zu erzwingen. Es gibt geeignete Reaktivierungsmethoden, um ein Element einer Komponente zu erhalten (wie this.findDomNode()), die seit der Arbeit an der Komponenteninstanz der Methode getElementById vorzuziehen sind.

+0

so dachte ich über die Verwendung von ToDataURL, aber leider funktioniert das nur, wenn das Video, aus dem die Leinwand erfasst wurde, stammt aus der gleichen Domäne oder Cross-Domain, die den Zugriff ermöglicht. Dies ist in meinem Fall nicht gewährleistet. Wenn dies nicht der Fall ist, schlägt toDataURL() mit einem Fehler fehl, der "getained" (geschrieben mit Daten aus einer anderen Domäne) Canvas kann nicht exportiert werden. Ihr zweiter Vorschlag beinhaltet eine direkte DOM-Einfügung, die ich auch mit der tatsächlichen Zeichenfläche machen kann (ohne toDataURL()). Dies steht derzeit als der vernünftigste Weg, aber es scheint für React sehr anti-pattern zu sein. – allenrabinovich

+0

ist es ein Anti-Muster. Sie fügen etwas ein, was reaktion nicht weiß. Ist auch wahr, react gibt dir keine Alternative. Ist mehr Leistung von DataRel und Sie können es am Leben bleiben mit dem Lebenszyklus der Reaktionskomponente – AndreaBogazzi

+0

oh ja die DataRel im zweiten Beispiel ist ein Copy Paste-Fehler – AndreaBogazzi

Verwandte Themen