Quantcast
Channel: CSSタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8925

画像の狙った座標に他の画像をぴったり重ねる方法

$
0
0
Webアプリにて、カード置き場の画像に描かれた枠内に、カード画像をきっちり並べる、というコンポーネントを実装する機会があったので、そのとき用いた方法を記します。 (フレームワークにReactを用いましたが、カードの配置自体はCSSの機能で実装可能です) 実装イメージ: 用いる画像 カードの画像: cardBack.png / cardFace.png ボード(カード置き場)の画像: board.png 予めボード画像の大きさやカードの座標を以下のように調べておきます 実装コード カード1枚の場合 まずは簡単に、1枚だけカードを配置してみます。 Boardクラス ボード画像を、ウィンドウの高さに合わせて表示します(height: 100vh) ボード画像とカード画像を重ねて表示するため、基準となる親要素のdivを作ります divを、子要素であるボード画像のサイズに合わせます(display: inline-block, height: 100vh) divを基準にカードを配置するため、position: relativeとします Cardクラス カードのスタイルをcreateCardImageStyle関数を用いて作成します 親要素であるdiv(= ボード画像と同じサイズ)を基準に配置するため、position: absoluteとします カードの位置は、ボードの元画像における座標と、ボードの元画像のサイズから、割合を計算して指定します。割合で指定することにより、画面上の画像サイズに依存せずに位置を指定することができます(top、leftを%指定) カードのサイズも同様に、ボードの元画像における枠の比率に合わせます(widthを%指定) ここではカードの左上ではなく中央を基準に揃えるため、カードの高さの半分だけ上に、幅の半分だけ左にずらします(transform: translate(-50%, -50%)) index.js import React from 'react'; import ReactDOM from 'react-dom'; const cardImage = "./cardBack.png"; // カード画像 const boardImage = "./board.png"; // ボード画像 const boardImageWidth = 1757; // ボード画像の幅(ピクセル数) const boardImageHeight = 2126; // ボード画像の高さ(ピクセル数) const firstLeftPosition = 318; // カードを置く座標(左から何ピクセル目か) const firstTopPosition = 395; // カードを置く座標(上から何ピクセル目か) const frameWidth = 340; // ボード画像に描かれたカード用の枠の幅(ピクセル数)。カード画像の幅ではないことに注意 function createCardImageStyle(leftPosition, topPosition, frameWidth) { return { position: "absolute", top: (topPosition / boardImageHeight) * 100 + "%", left: (leftPosition / boardImageWidth) * 100 + "%", width: (frameWidth / boardImageWidth) * 100 + "%", transform: "translate(-50%, -50%)", }; } class Card extends React.Component { render(){ return ( <img src={cardImage} style={createCardImageStyle(firstLeftPosition, firstTopPosition, frameWidth)} /> ); } } class Board extends React.Component { render(){ return ( <div style={{display: "inline-block", position: "relative", height: "100vh"}}> <img src={boardImage} style={{height: "100vh"}} /> <Card/> </div> ); } } ReactDOM.render( <React.StrictMode> <Board /> </React.StrictMode>, document.getElementById('root') ); 実行結果: カード複数枚の場合 1枚のときと考え方は変わりません。 for文を用いて、配列にカードを格納します。 Boardクラス Cardの代わりにCardsコンポーネントを使います Cardsクラス for文を用いて、縦横3つずつカードを作り、cards配列に格納します 必要な情報を、propsを経由してカードへ渡します。keyは要素の識別用です。 srcは使用するカード画像のソースです。ここでは交互に表裏になるよう並べるため、i % 2 == j % 2による判定を入れています leftPositionは、1枚目のカードの座標(firstLeftPosition)に、対象のカードまでの差分(leftPositionDiff * i)を足して求めます topPositionも同様です Cardクラス props経由で取得した情報を用いて、カードを表示します index.js import React from 'react'; import ReactDOM from 'react-dom'; const cardBackImage = "./cardBack.png"; // カード画像 const cardFaceimage = "./cardFace.png"; // カード画像2 const boardImage = "./board.png"; // ボード画像 const boardImageWidth = 1757; // ボード画像の幅(ピクセル数) const boardImageHeight = 2126; // ボード画像の高さ(ピクセル数) const firstLeftPosition = 318; // 1枚目のカードを置く座標(左から何ピクセル目か) const firstTopPosition = 395; // 1枚目のカードを置く座標(上から何ピクセル目か) const leftPositionDiff = 554; // カード同士の座標の差 const topPositionDiff = 682; // カード同士の座標の差 const frameWidth = 340; // ボード画像に描かれたカード用の枠の幅(ピクセル数)。カード画像の幅ではないことに注意 function createCardImageStyle(leftPosition, topPosition, frameWidth) { return { position: "absolute", top: (topPosition / boardImageHeight) * 100 + "%", left: (leftPosition / boardImageWidth) * 100 + "%", width: (frameWidth / boardImageWidth) * 100 + "%", transform: "translate(-50%, -50%)", }; } class Card extends React.Component { render(){ return ( <img src={this.props.src} style={createCardImageStyle(this.props.leftPosition, this.props.topPosition, frameWidth)} /> ); } } class Cards extends React.Component { render(){ const cards = []; for (let j = 0; j < 3; j++){ for (let i = 0; i < 3; i++){ cards.push(<Card key={"card" + i + "_" + j} src={(i % 2 == j % 2)?cardBackImage:cardFaceimage} leftPosition={firstLeftPosition + leftPositionDiff * i} topPosition={firstTopPosition + topPositionDiff * j} />); } } return ( <span> {cards} </span> ); } } class Board extends React.Component { render(){ return ( <div style={{display: "inline-block", position: "relative", height: "100vh"}}> <img src={boardImage} style={{height: "100vh"}} /> <Cards/> </div> ); } } ReactDOM.render( <React.StrictMode> <Board /> </React.StrictMode>, document.getElementById('root') ); 実行結果: ウィンドウサイズを変更しても、ボード画像に合わせてカードが配置されます

Viewing all articles
Browse latest Browse all 8925

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>