スマホアプリ「ドラッグ王子とマトリ姫」UIを
HTMLとCSSで再現した話

HTML & CSS | JS 2019.05.05

table of contents目次

Task実現させたいことを書き出します

今回実現したいことを考えます。制作することによってどういったことが身につくのか、ということですね。
作って終わりにしたくないので、こうしてまとめることにしました。

まずは今回の課題です。
スマートフォン向けノベルゲームアプリ「ドラッグ王子とマトリ姫」のキャラクタープロフィール画面をウェブ上で再現できるか

ひとまず、今回は下記のような目標を設定することにしました。
他にもやりたいことはたくさんあるけれど、それはまた別の機会にでも。

  • 背景グラデーション(グレー→透明)をCSSで再現
  • 背景ストライプのパターンをCSSで再現
  • アプリと同じ挙動をさせる(ボタンをクリックすると裏面が表示される)
  • 画像を使用するのはキャラクターの顔アイコンのみ(チャートグラフはSVGを使う)

Designデザインを起こします

Photoshopでデザインを作ります。菅野くん推しなので、菅野くんで作りました。
自分がiPhoneSEユーザーなので、パーツのサイズ感は全てSEで見たときのサイズで。
パーツ分けするとだいたいこんな感じ。

Photoshop CC 2019

ボタンの左右にハートが入っていなかったり、プロフィールに境界線が入っていなかったり、細かい部分は省略していますが、コーディング時に実装します。

  • フォントは全て「UDタイポス515 Std」です。
  • 捜査一課カラーは「#8ab978」を使用しています。
  • フレーム(背景)はグレーのグラデーションと半透明のストライプパターンの二つのレイヤーを重ねています。
  • チャートグラフについて、ここではPhotoshopで制作していますが、後々のことを考えるとIllustratorで制作した方が絶対にいい(SVG書き出しという意味で)

HTML markup | FrontHTMLを書きます(表面編)

私はHTML→SCSS(CSS)→JSという順番で実装しますが、自分のやりやすい方法でいいと思います。CSSから書き始める人もいらっしゃるようですし。
まずはフロント部分のHTMLを書いていきます。

<section id="card front" class="card front">
	<div class="cardOuter">
		<div class="cardInner sugano">

			<div class="imageArea">
				<div class="thumbBox">
					<div class="thumb">
						<span>菅野夏樹</span>
					</div>
				</div>
				<div class="thumbCopy">
					<p>
						<span>俺</span>
						<span>の</span>
						<span>理</span>
						<span>想</span>
						<span>は</span>
						<span>正</span>
						<span>義</span>
						<span>の</span>
						<span>ヒ</span>
						<span>ー</span>
						<span>ロ</span>
						<span>ー</span>
						<span>だ</span>
						<span>か</span>
						<span>ら</span>
						<span>!</span>
					</p>
				</div>
				<div class="btnArea">
					<button class="button" id="button_back">
						<span class="htL-front"></span>カレと恋人になると…?<span class="htR-front"></span>
					</button>
				</div>
			</div>

			<div class="textArea">
				<div class="copyLiner"></div>
				<h3>お調子者ムードメーカー×究極の自己犠牲男子</h3>
				<h2 class="name">菅野 夏樹<span>[Sugano Natsuki]</span></h2>

				<div class="profileBox">
					<table>
						<tbody>
							<tr>
								<th>年齢</th>
								<td>26歳</td>
								<th>所属</th>
								<td>捜査一課</td>
							</tr>
							<tr>
								<th>身長</th>
								<td>176cm</td>
								<th>趣味</th>
								<td class="sm">ヒーローフィギュア集め<br />体を動かす事</td>
							</tr>
							<tr>
								<th>体重</th>
								<td>62kg</td>
								<th>好き</th>
								<td>フランスパン</td>
							</tr>
						</tbody>
					</table>
				</div>

				<div class="notes">
					<span class="b_top"></span>
					<span class="b_right"></span>
					<span class="b_bottom"></span>
					<span class="b_left"></span>
					<p>
						明るく前向きな同い年。<br />
						だけど、カレは『痛み』を感じない体質を持っていて…体だけじゃなく、心の痛みに鈍感なカレの笑顔の裏側は…?
					</p>
				</div>
			</div>
		</div>
	</div>
</section>
HTML | Front

左側のコンテンツをimageArea、右側のコンテンツをtextAreaとし、CSS記述の際にflexで横並びレイアウトにします。

キャラクターイラスト部分はHTMLにimgを入れずに、backgroundとしてCSSに記述。
イラストに重なるテキスト部分「俺の理想は正義のヒーローだから!」を一文字ずつspanで囲っているのは、アニメーションを実装する際に一文字ずつ出現させるためです。アニメーションをつけない場合はspanをそのまま消してもOK。

<button class="button" id="button_back">
	<span class="htL-front"></span>カレと恋人になると…?<span class="htR-front"></span>
</button>

32行目〜34行目がボタンになります。最終的には、ここをクリックすると裏面が表示させるという形にします。
33行目の<span class="htL-front"></span><span class="htR-front"></span>はデザイン時はめんどくさくて再現していなかったハートのアイコンです。
このハートもCSSで再現していますので、後述。

右側のコンテンツについては改めて記載するほど難しいのはないのですが一点だけ。

<span class="b_top"></span>
<span class="b_right"></span>
<span class="b_bottom"></span>
<span class="b_left"></span>

69行目〜72行目のspanタグはアニメーション用です。不要な場合はそのまま削除でOK。

HTML markup | BackHTMLを書きます(裏面編)

<section id="card back" class="card back">
	<div class="cardOuter">
		<div class="cardInner sugano">

			<div class="imageArea">
				<div class="thumbBox">
					<div class="thumb">
						<span>菅野夏樹</span>
					</div>
				</div>
				<div class="thumbCopy">
					<p class="p1">
						<span>…</span>
						<span>お</span>
						<span>前</span>
						<span>に</span>
						<span>泣</span>
						<span>か</span>
						<span>れ</span>
						<span>る</span>
						<span>と</span>
					</p>
					<p class="p2">
						<span>こ</span>
						<span>ん</span>
						<span>な</span>
						<span>に</span>
						<span>痛</span>
						<span>い</span>
						<span>ん</span>
						<span>だ</span>
						<span>ね</span>
					</p>
				</div>
				<div class="btnArea">
					<button class="button" id="button_front"><span class="htL-back"></span>プロフィール<span class="htR-back"></span></button>
				</div>
			</div>

			<div class="textArea">
				<div class="chart">

					<div id="svgInner" class="svgInner">
						<svg width="509" height="316" viewBox="-16 -16 158 158">
							<g fill="none" fill-rule="evenodd">
								<g fill="#ffffff" stroke-width="1" stroke="#5b5755" stroke-opacity=".6" fill-opacity=".8" transform="translate(0 6)">
									<polygon points="33  0   99  0   132    57.5  99  115    33  115    0     57.5"/>
									<polygon points="40  12  92  12  119.5  57.5  92  103    40  103    12.5  57.5"/>
									<polygon points="47  24  85  24  105    57.5  85  91     47  91     27    57.5"/>
									<polygon points="54  34  78  34  92   57.5  78  81     54  81     40  57.5"/>
									<polygon points="59  46  73  46  79   57.5  73  69     59  69     53  57.5"/>
								</g>
								<polygon class="polymorph" fill="#8ab978" fill-opacity=".8"  stroke-width="1" stroke="#8ab978" points="60,52,72,52,79,64,73,74,59,74,53,64"/>
							</g>
						</svg>
						<div class="chartText">
							<ul>
								<li>仕事への情熱</li>
								<li>経済力</li>
								<li>器用さ</li>
								<li>一途さ</li>
								<li>理性</li>
								<li>心の広さ</li>
							</ul>
						</div>
					</div>
				</div>

				<div class="comments">
					<div class="copyLiner"></div>
					<h3>カレの副作用</h3>

					<p class="bd-t">カレのどこか悲しそうな笑顔の真意、そして</p>
					<p>他人の痛みには誰よりも敏感だと知ってしまったら、</p>
					<p>ずっと側にいてあげなくちゃと思ってしまうかも!</p>
				</div>
			</div>

		</div>
	</div>


</section>
HTML | Back

Frontと同じように書いていけばいいだけなので特にないですが、全体的に見ても一番ネックとなってくるのがチャートグラフの部分です。
キャラクターイラスト以外、画像を使わないという謎縛りをしているのですが、チャート部分はSVGにしました。
SVGについては説明する必要はないと思うので割愛します。

<svg width="509" height="316" viewBox="-16 -16 158 158">
	<g fill="none" fill-rule="evenodd">
		<g fill="#ffffff" stroke-width="1" stroke="#5b5755" stroke-opacity=".6" fill-opacity=".8" transform="translate(0 6)">
			<polygon points="33  0   99  0   132    57.5  99  115    33  115    0     57.5"/>
			<polygon points="40  12  92  12  119.5  57.5  92  103    40  103    12.5  57.5"/>
			<polygon points="47  24  85  24  105    57.5  85  91     47  91     27    57.5"/>
			<polygon points="54  34  78  34  92   57.5  78  81     54  81     40  57.5"/>
			<polygon points="59  46  73  46  79   57.5  73  69     59  69     53  57.5"/>
		</g>
		<polygon class="polymorph" fill="#8ab978" fill-opacity=".8"  stroke-width="1" stroke="#8ab978" points="60,52,72,52,79,64,73,74,59,74,53,64"/>
	</g>
</svg>

44行目からsvgの描画が始まりますが、数値でそれぞれ書かれているのが分かると思います。(47行目〜51行目)
47行目〜51行目までは、六角形の数値。47行目から外側の数値、51行目が一番内側の数値になります。
X(左からの距離)→Y(上からの距離)が六角形それぞれの点の位置になるので、位置を表す数値が12個ずつあれば良いってことです。

47行目の数値を見てみましょう。

<polygon points="33  0   99  0   132    57.5  99  115    33  115    0     57.5"/>

最初の33がX(左からの距離)、次の0がY(上からの距離)。その次の99がX、次の0がYとあります。
この二つの数値が何を意味しているのかというと、六角形の左上の数値を表すのがX軸33とY軸0、右上の数値を表すのがX軸99とY軸0ということです。

それでは、一体どこからの距離なんじゃって思うかもしれません。ごもっとも。
svgの描画が44行目から始まると書きましたが、44行目に書かれているのが、svg全体のサイズです。つまり、箱です。

<svg width="509" height="316" viewBox="-16 -16 158 158">

書いてある通り、横幅が509px、縦幅が316pxです。これがSVG全体の箱だと認識していただければ良いかと思います。
その後すぐにviewBoxというのがありますが、こちらがいわゆるチャートグラフそのものの大きさになります。

viewBox="-16 -16 158 158"viewBox="X Y Width Height"になります。 つまり、左からの距離・上からの距離・横幅・高さということですね。

viewBoxのXYは、基本的に0ということが多いですが、ここではマイナス表記になっています。それはなぜか。
今回実装した菅野夏樹くんのチャートグラフは、仕事への情熱と心の広さが六角形の枠からはみ出ています。
原因はここで、もしXYを0としてしまうと、このはみ出ている部分が再現できないのです。(箱の外に出てしまうので、緑のグラフが途切れてしまう)
widthとheightは158ですが、六角形の大きさそのままになっています。
もちろん、XY軸を0にして、チャートグラフをはみ出さないようにもできますが、その場合は、まずviewboxのwidthとheightをグラフも含めて収まるような数値にして、44行目〜48行目の数値を調整する必要があります。多分。

viewBoxと47行目〜51行目を実装する(53行目以外を実装する)と、このような形になります。

それでは53行目を見てみましょう。

<polygon class="polymorph" fill="#8ab978" fill-opacity=".8"  stroke-width="1" stroke="#8ab978" points="60,52,72,52,79,64,73,74,59,74,53,64"/>

チャートグラフにアニメーションつけてみたら面白くね?と思ったので、この数値は全てアニメーション前の数値(0の状態)です。
この数値は最終的なものではなく、最終段階に向かう前の状態のものなので、実装するとこのような形になります。

そして、最終的にはこうなります。
この数値に関しては、アニメーション後の数値になるので、JSの方に記述します。HTMLには書きません。

以上、二つの<section>を一つの<article>で囲んでHTMLの記述は終了です。

CSS markupCSSを書きます

この段階ではアニメーションのことは何も考えず、ひたすらデザイン通りになるように書いていきます。
少しでもCSS触ったことのある人なら難なくできると思うので、完成品は参考までに。
SCSSになりますので、分からない人はググってください(丸投げ)

こちらはCSSアニメーションも入ったものが書かれています。
抜き出すのがめんどくさかったのでCSSアニメーションの詳しいことに関しては後日更新予定のアニメーションのセクションで書きますが、ここでは触れません。

$police : #8ab978;

body {
	color: #5b5755;
	font-family: UDタイポス512;
}

.pk {
	background:#d199ad;
}
.ppl {
	background:#83799e;
}

#wrapper {
	min-width: 1200px;
	.innerBox {
		margin: 180px auto;
		max-width: 1070px;
		height: 574px;
		position: relative;
		&:after {
			content: '';
			display: block;
			float: none;
			clear: both;
		}
	}
	article {
		position: absolute;
		height: 574px;
		&.flip {
			.front {
				-webkit-transform: rotateY(180deg);
				transform: rotateY(180deg);
				z-index: 900;
			}
			.back {
				-webkit-transform: rotateY(0deg);
				transform: rotateY(0deg);
				z-index: 1000;
			}
		}
	}
	section {
		position: absolute;
		overflow: hidden;

		margin: 0 auto;
		transform-style: preserve-3d;
		backface-visibility: hidden;
		transition: all 1s cubic-bezier(0.545, 0.080, 0.520, 0.975);
		&.front {
			z-index: 900;
			-webkit-transform: rotateY(0deg);
			transform: rotateY(0deg);
		}
		&.back {
			z-index: 800;
			-webkit-transform: rotateY(-180deg);
			transform: rotateY(-180deg);
		}
		&.card {
			display: flex;
			justify-content: center;
			align-items: center;
			p {
				font-family: UDタイポス512;
			}
			.cardOuter {
				width: 1062px;
				height: 566px;
				position: relative;

				background: linear-gradient(to bottom, rgba(248,248,248,1) 0%,rgba(229,229,228,1) 80%);

				border:4px solid #6d6c84;
				border-radius: 24px;
				&:before , &:after {
					position: absolute;
					left: 0;
					right: 0;
					top: 0;
					bottom: 0;
					z-index: 0;
					border-radius: 24px;
				}
				&:before {
					content: '';
					background:repeating-linear-gradient(-45deg, #ffffff 0, #ffffff 10px, #fafafa 10px, #fafafa 20px);
				}
				&:after {
					content: '';
					background: linear-gradient(rgba(248,248,248,1) 0, rgba(255,255,255,.7) 20%, rgba(255,255,255,0) 80%);
				}
				.cardInner {
					position: relative;
					padding:43px 72px 53px 47px;
					z-index: 10;

					display: flex;
					justify-content: center;
					align-items: center;
					.imageArea {
						width: 356px;
						margin-right: 78px;
						.thumbBox {
							position: relative;
							width: 338px;
							height: 338px;
							background:#eee;
							border:9px solid #fff;
							border-radius: 29px;
							box-shadow:0px 0px 10px 0px #737373;
							.thumb {
								@include text_replace();
								width: 268px;
								height: 272px;
								background: url("キャラクターイラストのURLを貼ってくれよな!") no-repeat center center;
								position: absolute;
								left: 0;
								right: 0;
								top: 0;
								bottom: 0;
								margin:auto;
							}
						}
						.thumbCopy {
							max-width: 366px;
							width: 100%;
							color: #fff;
							transform: rotate(-7deg);
							text-shadow: 1px 1px 0 #5b5755 , -1px 1px 0 #5b5755 , 1px -1px 0 #5b5755 , -1px -1px 0 #5b5755;
							position: absolute;
							top: 380px;
							text-align: center;
							p {
								font-size: 22px;
								letter-spacing: -4px;
								span {
									opacity: 0;
								}
								&.p1 {
									text-align: left;
								}
								&.p2 {
									text-align: right;
								}
							}
						}
						.btnArea {
							position: relative;
							margin-top: 40px;
							text-align: center;
							button {
								max-width: 352px;
								width: 90%;
								background: linear-gradient(to top, rgba(216,216,216,1) 0%,rgba(236,236,236,1) 100%);
								box-shadow:0px 0px 5px 0px #adadae;

								border:4px solid #fff;
								border-radius: 10px;

								font-family: UDタイポス512;
								font-size: 20px;
								line-height: 42px;
								color: #615e5c;

								position: relative;
								transition: .3s;
								&:hover {
									opacity: 0.8;
									box-shadow:0px 0px 25px 0px #adadae;
								}
							}
							.htL-front , .htR-front , .htL-back , .htR-back {
								position: absolute;
								width: 10px;
								height: 9px;
								top: 0;
								bottom: 0;
								margin: auto 0;
								&:before , &:after {
									position: absolute;
									content: "";
									left: 5px;
									top: 0;
									width: 5px;
									height: 8px;
									border-radius: 5px 5px 0 0;
									transform: rotate(-45deg);
									transform-origin: 0 100%;
								}
								&:after {
									left: 0;
									transform: rotate(45deg);
									transform-origin :100% 100%;
								}
							}
							.htL-front , .htL-back {
								left: 10px;
							}
							.htR-front , .htR-back {
								right: 10px;
							}
							.htL-front:before , .htL-front:after , .htR-front:before , .htR-front:after {
								background: #d199ad;
							}
							.htL-back:before , .htL-back:after , .htR-back:before , .htR-back:after {
								background: #83799e;
							}
						}
					}
					.textArea {
						position: relative;
						.copyLiner {
							display: block;
							background:$police;
							position: relative;
						}
						h3 {
							position: absolute;
							font-family: UDタイポス512;
							font-size: 21px;
							color: #fff;
							padding:10px 13px;
							top: 0;
						}
						h2 {
							font-family: UDタイポス512;
							font-size: 50px;
							margin:13px 0 30px;
							span {
								font-family: UDタイポス512;
								font-size: 19px;
								padding-left: 20px;
							}
						}
						.profileBox {
							table {
								width: 100%;
								font-size: 19px;
								font-family: UDタイポス512;
								tbody {
									tr {
										border-bottom: 2px dotted #5b5755;
										line-height: 48px;
										&:last-child {
											border-bottom: none;
										}
										th {
											width: 14%;
											opacity: 0;
										}
										td {
											width: 36%;
											opacity: 0;
											&.sm {
												font-size: 12px;
												line-height: 13px;
											}
										}
									}
								}
							}
						}
						.notes {
							display: block;
							background:#fafafa;
							box-shadow:0px 0px 30px 0px #eee inset;
							position: relative;
							.b_top , .b_right , .b_bottom , .b_left {
								background: #6d6c84;
								position: absolute;
							}
							.b_top {
								top: 0;
								right: 0;
								width: 100%;
								height: 4px;
							}
							.b_right {
								right: 0;
								bottom: 0;
								width: 4px;
								height: 100%;
							}
							.b_bottom {
								bottom: 0;
								right: 0;
								width: 100%;
								height: 4px;
							}
							.b_left {
								left: 0;
								bottom: 0;
								width: 4px;
								height: 100%;
							}
							p {
								padding:34px;
								font-size: 19px;
								line-height: 30px;
								opacity: 1;
							}
						}

						#svgInner {
							width: 509px;
							height: 322px;
							margin: auto;
							position: relative;
							svg {
								width: 100%;
								margin:0 auto;
							}
							.chartText {
								position: absolute;
								top: 0;
								bottom: 0;
								left: 0;
								right: 0;
								margin: auto;
								ul {
									li {
										position: absolute;
										font-size: 23px;
										&:nth-child(1) {
											top: 10px;
											left: 76px;
										}
										&:nth-child(2) {
											top: 10px;
											left: 326px;
										}
										&:nth-child(3) {
											top: 147px;
											left: 410px;
										}
										&:nth-child(4) {
											top: 286px;
											left: 328px;
										}
										&:nth-child(5) {
											top: 286px;
											left: 146px;
										}
										&:nth-child(6) {
											top: 147px;
											left: 18px;
										}
									}
								}
							}
						}
						.comments {
							position: relative;
							width: 94%;
							margin:10px auto 0;
							p {
								font-size: 19px;
								line-height: 32px;
								border-bottom: 2px dotted #5b5755;
								display: block;
								&.bd-t {
									border-top: 2px dotted #5b5755;
								}
							}
						}
					}
				}
			}
		}
	}
}
SCSS

グラデーション+ストライプ実装
背景にはグレーのグラデーションを、その擬似要素としてストライプを実装しています。

.cardOuter {
	width: 1062px;
	height: 566px;
	position: relative;

	background: linear-gradient(to bottom, rgba(248,248,248,1) 0%,rgba(229,229,228,1) 80%);

	border:4px solid #6d6c84;
	border-radius: 24px;

	...
	&:before , &:after {
		position: absolute;
		left: 0;
		right: 0;
		top: 0;
		bottom: 0;
		z-index: 0;
		border-radius: 24px;
	}
	&:before {
		content: '';
		background:repeating-linear-gradient(-45deg, #ffffff 0, #ffffff 10px, #fafafa 10px, #fafafa 20px);
	}
	&:after {
		content: '';
		background: linear-gradient(rgba(248,248,248,1) 0, rgba(255,255,255,.7) 20%, rgba(255,255,255,0) 80%);
	}

キャラクターイラスト
Box部分に境界線とボックスシャドウを記述し、中身(thumb)にキャラクターイラストをbackgroundで設定します。

.thumbBox {
	position: relative;
	width: 338px;
	height: 338px;
	background:#eee;
	border:9px solid #fff;
	border-radius: 29px;
	box-shadow:0px 0px 10px 0px #737373;
	.thumb {
		@include text_replace();
		width: 268px;
		height: 272px;
		background: url("キャラクターイラストのURLを貼ってくれよな!") no-repeat center center;
		position: absolute;
		left: 0;
		right: 0;
		top: 0;
		bottom: 0;
		margin:auto;
	}
}

キャラクターイラスト下のテキスト
テキストはposition:absoluteで位置を決め、テキストが斜めになるようにtransform: rotate(-7deg);を指定。
テキストには境界線(text-shadow)がかかるようにします。

.thumbCopy {
		max-width: 366px;
		width: 100%;
		color: #fff;
		transform: rotate(-7deg);
		text-shadow: 1px 1px 0 #5b5755 , -1px 1px 0 #5b5755 , 1px -1px 0 #5b5755 , -1px -1px 0 #5b5755;
		position: absolute;
		top: 380px;
		text-align: center;
	}

ボタン
最終的にはここをクリックすると捲れるようなアニメーションをつけますが、まずはボタンをデザイン通りにします。

button {
	max-width: 352px;
	width: 90%;
	background: linear-gradient(to top, rgba(216,216,216,1) 0%,rgba(236,236,236,1) 100%);
	box-shadow:0px 0px 5px 0px #adadae;

	border:4px solid #fff;
	border-radius: 10px;

	font-family: UDタイポス512;
	font-size: 20px;
	line-height: 42px;
	color: #615e5c;

	position: relative;
	transition: .3s;
...

ハートはこんな感じ
ハートの左側半分はbefore、右半分はafterで擬似要素を使っており、backgroundで塗りつぶした色をwidthとheightを使ってサイズを調整、transform:rotateで傾けて、positio:absoluteで位置を指定するというような方法です。

.htL-front , .htR-front , .htL-back , .htR-back {
	position: absolute;
	width: 10px;
	height: 9px;
	top: 0;
	bottom: 0;
	margin: auto 0;
	&:before , &:after {
		position: absolute;
		content: "";
		left: 5px;
		top: 0;
		width: 5px;
		height: 8px;
		border-radius: 5px 5px 0 0;
		transform: rotate(-45deg);
		transform-origin: 0 100%;
	}
	&:after {
		left: 0;
		transform: rotate(45deg);
		transform-origin :100% 100%;
	}
}
.htL-front , .htL-back {
	left: 10px;
}
.htR-front , .htR-back {
	right: 10px;
}
.htL-front:before , .htL-front:after , .htR-front:before , .htR-front:after {
	background: #d199ad;
}
.htL-back:before , .htL-back:after , .htR-back:before , .htR-back:after {
	background: #83799e;
}
...

キャラクター名は普通にfont-size等だけです。
プロフィールの表はテーブルコーディングにしているので説明も不要かと思うので割愛。
dl dt ddとかの方が良かったかもしれない…

プロフィール下の紹介文ですが、ここのボックスにはうっっっっっっっっっすら内側にシャドウが入ってます。
特に難しいことはしていないので説明は省略します。

裏面の方も表面とほぼ同じです。SVGの描画もHTMLの方でやっているので、サクッと。
チャートグラフの各要素名はチャート全体に被せるようにテキスト用のボックスを作成し、position:absoluteで要素名を配置していくだけです。

.chartText {
	position: absolute;
	top: 0;
	bottom: 0;
	left: 0;
	right: 0;
	margin: auto;
	ul {
		li {
			position: absolute;
			font-size: 23px;
			&:nth-child(1) {
				top: 10px;
				left: 76px;
			}
			&:nth-child(2) {
				top: 10px;
				left: 326px;
			}
			&:nth-child(3) {
				top: 147px;
				left: 410px;
			}
			&:nth-child(4) {
				top: 286px;
				left: 328px;
			}
			&:nth-child(5) {
				top: 286px;
				left: 146px;
			}
			&:nth-child(6) {
				top: 147px;
				left: 18px;
			}
		}
	}
}
...

Java Scriptクリックで発火させる

ここではボタンをクリックするとカードが捲れるというようなアニメーションを実装します。
「捲れる」というアニメーションはCSSで実装します。

「クリックで発火させる」という動きになるので、下記のような一連の動作が必要となります。

  • ボタンをクリックすると(JS)
  • 要素にクラス名が追加され(JS)
  • 追加されたクラス名に、指定していたアニメーションが実行される(CSS)

CSSに関しては、前述した中に「flip」というクラス名があるので、そちらを参照ください。
jqueryを入れた上で下記の通りとなります。

(function () {
	const showBtn = document.querySelectorAll('.button');
	const box = document.querySelector('article');

	showBtn.forEach(btn => {
		btn.addEventListener('click', () => {
			box.classList.toggle('flip');
		}, false);
	});
})();
Java Script

2行目と3行目は変数の宣言
6行目:.buttonをクリックすると
7行目:articleに.flipというクラスが追加させる

という動きが実装できます。

flipにCSSで指定していたアニメーションを記述していると、
ボタンをクリックしたタイミングでそのアニメーションが実行されるということです。

Java ScriptTweenmaxで全体にアニメーションを導入する

Java ScriptAnimeJSでチャートグラフにアニメーションをつける

以上の二つのコンテンツについては今後追加予定です。
なお、実装済みのものはこちらで確認できます。

当ページは株式会社coly「”ドラッグ王子とマトリ姫”」の画像(動画)を利用しております 該当画像の転載・配布等は禁止しております。
©coly

当ページ及び、デモページのソースコードは、
配信中のアプリUIを再現した二次創作物となっておりますので、
商用・個人ともに無断転用は一切禁止とさせていただいております。
©Design SOLALAB

COMMENTコメント

わたしだ

2019年2月半ばでスタマイを始めて2年経ったので、その記念?としてマトリ姫UIをウェブで作りました。完成は3月だったのに作って満足するタイプの人間なので、アウトプットするのに時間がかかってしまった…二次創作と言い張る。
SVGは仕事でも結構使うのですが、チャートを作るのは初めてで、viewBoxとかはいい勉強になった…今までイラレで作ったのをそのまま書き出して使ってただけだったので勉強不足を超実感…
アニメーションの記事は後日書く予定ですが、全てTweenMaxでやるよりは、気になってたAnimeJSも使ってみたいなぁと思い、せっかくだから二つ使いました。仕事では絶対やりません…。重くなるし。こちらもお楽しみ