transformを使用して要素を中央配置する機会は多いと思います。
しかし、思ったように中央配置できない場合、translateとscaleの記述の順番が影響しているかもしれません。
ポイント:scaleとtranslateの併用時は順番に注意する
中央配置したい要素をscaleを使用して大きさを変更し、translateで中央配置したい場合、先にscaleを行わないとtranslateで中央配置したいと思っても、うまく中央に配置できません。cssとKotlinで具体例を見ていきます。
cssでの具体例
1. scale → translate の順番 : 中央に配置できる
サンプルコード
<style>
.container {
width: 300px;
height: 300px;
position: relative;
margin-bottom: 40px;
}
.circle-correct {
width: 50px;
height: 50px;
background: #14b2a4;
position: absolute;
left: 50%;
top: 50%;
/* 下記の順番だと中央に配置できる */
transform: scale(2) translate(-50%, -50%); /* 先にscaleを行う */
transform-origin: top left;
}
.label {
margin-bottom: 8px;
font-weight: bold;
}
</style>
<div class="label">✅ scale → translate(ズレなし)</div>
<div class="container">
<div class="circle-correct"></div>
</div>
サンプルコードをブラウザで表示したとき
✅ scale → translate(ズレなし)
2. translate → scale の順番 : ずれてしまい、中央に配置できない
サンプルコード
<style>
.container {
width: 300px;
height: 300px;
position: relative;
}
.circle-wrong {
width: 50px;
height: 50px;
background: #14b2a4;
position: absolute;
left: 50%;
top: 50%;
/* 下記の順番だと中央に配置できない */
transform: translate(-50%, -50%) scale(2); /* 後からscaleを行う */
transform-origin: top left;
}
.label {
margin-bottom: 8px;
font-weight: bold;
}
</style>
<div class="label">❌ translate → scale(ズレる)</div>
<div class="container">
<div class="circle-wrong"></div>
</div>
サンプルコードをブラウザで実行したとき
❌ translate → scale(ズレる)
Kotlinでの具体例
下記のコードで中央に配置できます。
val canvasSize = size
// パスのバウンディングボックス(パス全体の矩形範囲)を取得
val bounds = path.getBounds()
// 中央に配置するためのオフセットを計算
val offsetX = (canvasSize.width - bounds.width) / 2f - bounds.left
val offsetY = (canvasSize.height - bounds.height) / 2f - bounds.top
// パスのサイズをキャンバス(縦と横のいずれか小さい方)のサイズに合わせる
val scale = minOf(
canvasSize.width / bounds.width,
canvasSize.height / bounds.height
)
// パスを変換して描画
withTransform({
scale(scale) // ← translateの前にスケーリングする
translate(offsetX, offsetY)
}) {
drawPath(path)
}
}