2017-11-07 15 views
0

CSS3 Matrix3D変換を使用してキャンバスに画像を描画する方法があるかどうかを知りたいと思います。使用されているコンテキストは、スタックされたレイヤーをレンダリングするために使用される2Dと、その上にmatrix3Dで変換されたイメージレイヤーです(キャンバスに描画することはできませんでした)。CSS3 matrix3Dをキャンバス2D要素に描画する

基本的に私が達成したいのは、transform: matrix3d(0.87, 0, 0.5, -0.00025, 0, 1, 0, 0, -0.5, 0, 0.87, 0, 0, 550, 0, 1)を2Dコンテキストで描画キャンバスに変換することです。

可能ですか?今のところ、私はキャンバスの上のCSS3レイヤーでかなりうまくいますが、私が開発しているアプリケーションでは、キャンバスを実際のイメージファイル(ユーザーに送信される)にエクスポートする必要があります。

ここに、私の現在の変換レイヤの表示方法を示すスニペットがあります。だから、ここでの目標は、実際にキャンバスに「プレースホルダ」変換画像をレンダリングすることです将来、読者の要件に合わないかもしれませんが、これを行うことができますハックの1本の経糸があり

#canvas { 
 
    background: tomato; 
 
    height: 100vh; 
 
    width: 100vw; 
 
    position: relative; 
 
} 
 

 
.viewport .transformed-layer { 
 
    height: 72%; 
 
    position: absolute; 
 
    left: 35%; 
 
    top: calc(21% - 550px); 
 
    -webkit-transform: rotate(-1.5deg) matrix3d(0.87, 0, 0.5, -0.00025, 0, 1, 0, 0, -0.5, 0, 0.87, 0, 0, 550, 0, 1); 
 
    transform: rotate(-1.5deg) matrix3d(0.87, 0, 0.5, -0.00025, 0, 1, 0, 0, -0.5, 0, 0.87, 0, 0, 550, 0, 1); 
 
    opacity: .9; 
 
}
<div class='viewport'> 
 
    <div id='canvas'>This is a div simulating the canvas element with some drawed image</div> 
 
    <img class='transformed-layer' src='http://via.placeholder.com/300x300' /> 
 
</div>

+0

... SVGのiamgeがその上に描かれた時はいつでもIEの古いバージョンでは、キャンバスを汚染チェックなかったことに注意してくださいキャンバス・コンテキストは、理由のためにその名前に2Dを持ちます。答えは2Dキャンバスで3D変換を使用できないということです。 – Blindman67

+0

ありがとうございます。 CSSは2Dコンテキストでも使用されますが(明示的ではない場合でも)、matrix3Dは3D動作を偽造するために使用できます。私は、2Dキャンバスに似たものがあるかどうか疑問に思っていました。 – 3Dos

+0

3Dトランスフォームについての偽装はありません。また、2Dコンテキストでの3Dレンダリング用のネイティブAPIもありません。あなたはjavascript(それはレンダリング)で行うことができますが、それはピクセル単位であり、遅くなります。キャンバス上で3Dをしたいのであれば、webGLを使うだけです。 – Blindman67

答えて

2

キャンバスはSVG画像を描くことができ、SVG画像はCSSを介して変換することができます。 したがって、現在のキャンバスをdataURLに変換するには、このdataURLをSVGImage要素のhrefとして設定します。これはCSSTransformを適用する前にキャンバスに描画するsvgイメージとしてエクスポートします。ここで

は、コンセプトのラフな証拠である:

function getTransformedCanvas(canvas, CSSTransform){ 
 
    return new Promise(function(res, rej){ 
 
    var dim = getTransformedDimensions(canvas, CSSTransform); 
 
    var xlinkNS = "http://www.w3.org/1999/xlink", 
 
     svgNS = 'http://www.w3.org/2000/svg'; 
 
    var svg = document.createElementNS(svgNS, 'svg'), 
 
     defs = document.createElementNS(svgNS, 'defs'), 
 
     style = document.createElementNS(svgNS, 'style'), 
 
    image = document.createElementNS(svgNS, 'image'); 
 
    image.setAttributeNS(xlinkNS, 'href', canvas.toDataURL()); 
 
    image.setAttribute('width', canvas.width); 
 
    image.setAttribute('height', canvas.height); 
 
    style.innerHTML = 'image{transform:'+CSSTransform+';}'; 
 
    svg.appendChild(defs); 
 
    defs.appendChild(style); 
 
    var rect = document.createElement('rect'); 
 

 
    svg.appendChild(image); 
 
    svg.setAttribute('width', dim.width); 
 
    svg.setAttribute('height', dim.height); 
 
    var svgStr = new XMLSerializer().serializeToString(svg); 
 
    var img = new Image(); 
 
    img.onload = function(){res(img)}; 
 
    img.onerror = rej; 
 
    img.src = URL.createObjectURL(new Blob([svgStr], {type:'image/svg+xml'})); 
 
    }); 
 
} 
 

 
function getTransformedDimensions(canvas, CSSTransform){ 
 
    var orphan = !canvas.parentNode; 
 
    if(orphan) document.body.appendChild(canvas); 
 
    var oldTrans = getComputedStyle(canvas).transform; 
 
    canvas.style.transform = CSSTransform; 
 
    var rect = canvas.getBoundingClientRect(); 
 
    canvas.style.transform = oldTrans; 
 
    if(orphan) document.body.removeChild(canvas); 
 
    return rect; 
 
} 
 

 
// create a simple checkerboard 
 
var canvas = document.createElement('canvas'); 
 
canvas.width = canvas.height = 30; 
 
var ctx = canvas.getContext('2d'); 
 
ctx.fillStyle = 'orange'; 
 
ctx.fillRect(0,0,15, 15); 
 
ctx.fillRect(15,15,15, 15); 
 
var pattern = ctx.createPattern(canvas, 'repeat'); 
 
canvas.width = canvas.height = 300; 
 
ctx.fillStyle = pattern; 
 
ctx.fillRect(0,0,300,300); 
 
getTransformedCanvas(canvas, 
 
'translateY(-540px) rotate(-1.5deg) matrix3d(0.87, 0, 0.5, -0.00025, 0, 1, 0, 0, -0.5, 0, 0.87, 0, 0, 550, 0, 1)' 
 
) 
 
.then(function(img){ 
 
    inScreen.width = img.width; 
 
    inScreen.height = img.height; 
 
    inScreen.getContext('2d').drawImage(img, 0,0); 
 
    }) 
 
.catch(console.error);
canvas { 
 
    border:1px solid; 
 
}
<canvas id="inScreen"></canvas>

しかし

+0

ああ!私は絶対にsvg埋め込みCSSについて考えなかった。私は今日または明日これを試し、あなたに私のフィードバックを与えます。既に概念が完全に私の問題を強調しているとしてupvoted。すでにありがとう! – 3Dos

+0

私のためにうまくいきませんでした!私にこのリードを見せていただきありがとうございます。一部の 'matrix3d'はクロムで動作しますが、すべてではありません。 FirefoxとSafariでは、画像はまったくレンダリングされません。だから、私はバックエンドソリューションか単純なキャンバストランスフォームのいずれかに行くつもりです。 – 3Dos

関連する問題