Kiet
10/31/2024, 5:49 AMKiet
10/31/2024, 5:51 AM@OptIn(ExperimentalComposeUiApi::class)
fun main() = application {
Window(
title = "Test",
state = rememberWindowState(
size = DpSize(1600.dp, 800.dp)
),
undecorated = false,
onCloseRequest = ::exitApplication
) {
var scale by remember { mutableStateOf(1f) }
var rotation by remember { mutableStateOf(0f) }
var offset by remember { mutableStateOf(Offset.Zero) }
val state = rememberTransformableState { zoomChange, offsetChange, rotationChange ->
scale *= zoomChange
rotation += rotationChange
offset += offsetChange * scale
}
Box(modifier = Modifier
.onRotaryScrollEvent { e ->
println("Got scroll event: $e")
true
}
.onPointerEvent(PointerEventType.Scroll) { e ->
val event = e.changes.firstOrNull()
if (event != null) {
println("scrollDelta: ${event.scrollDelta.toString()}")
val y = event.scrollDelta.y
val scaleFactor = 0.1f
scale = max(scale * (1 - (y * scaleFactor)), 0.5f)
}
}
.graphicsLayer(
scaleX = scale,
scaleY = scale,
rotationZ = rotation,
translationX = offset.x,
translationY = offset.y,
clip = false
)
.transformable(state)
) {
PeriodicTable()
}
}
}
KarolK
10/31/2024, 6:15 AMKiet
11/01/2024, 3:44 AM@Composable
fun PeriodicTable() {
Column(
verticalArrangement = Arrangement.spacedBy(3.dp),
modifier = Modifier
.horizontalScroll(rememberScrollState())
) {
val spaceNum = 10
val horizontalSpacing = 3.dp
Row(horizontalArrangement = Arrangement.spacedBy(horizontalSpacing)) {
PeriodicItem(
"1", "1.0080", "H", "Hydrogen", "Nonmetal"
)
PeriodicSpacer()
repeat(spaceNum + 5) {
PeriodicSpacer()
}
PeriodicItem(
"2", "4.00260", "He", "Helium", "Noble Gas"
)
}
Row(horizontalArrangement = Arrangement.spacedBy(horizontalSpacing)) {
PeriodicItem(
"3", "7.0", "Li", "Lithium", "Alkali Metal"
)
PeriodicItem(
"4", "9.012183", "Be", "Beryllium", "Alkaline Earth Metal"
)
repeat(spaceNum) {
PeriodicSpacer()
}
PeriodicItem(
"5", "10.91", "B", "Boron", "Metalloid"
)
PeriodicItem(
"6", "12.011", "C", "Carbon", "Nonmetal"
)
PeriodicItem(
"7", "14.007", "N", "Nitrogen", "Nonmetal"
)
PeriodicItem(
"8", "15.999", "O", "Oxygen", "Nonmetal"
)
PeriodicItem(
"9", "18.99840316", "F", "Fluorine", "Halogen"
)
PeriodicItem(
"10", "20.180", "Ne", "Neon", "Noble Gas"
)
}
Row(horizontalArrangement = Arrangement.spacedBy(horizontalSpacing)) {
PeriodicItem(
"11", "22.9897693", "Na", "Sodium", "Alkali Metal"
)
PeriodicItem(
"12", "24.305", "Mg", "Magnesium", "Alkaline Earth Metal"
)
repeat(spaceNum) {
PeriodicSpacer()
}
PeriodicItem(
"13", "26.981538", "Al", "Aluminum", "Post-Transition Metal"
)
PeriodicItem(
"14", "28.085", "Si", "Silicon", "Metalloid"
)
PeriodicItem(
"15", "30.97376200", "P", "Phosphorus", "Nonmetal"
)
PeriodicItem(
"16", "32.07", "S", "Sulfur", "Nonmetal"
)
PeriodicItem(
"17", "35.45", "Cl", "Chlorine", "Halogen"
)
PeriodicItem(
"18", "39.9", "Ar", "Argon", "Noble Gas"
)
}
Row(horizontalArrangement = Arrangement.spacedBy(horizontalSpacing)) {
PeriodicItem(
"19", "39.0983", "K", "Potassium", "Alkali Metal"
)
PeriodicItem(
"20", "40.08", "Ca", "Calcium", "Alkaline Earth Metal"
)
PeriodicItem(
"21", "44.95591", "Sc", "Scandium", "Transition Metal"
)
PeriodicItem(
"22", "47.867", "Ti", "Titanium", "Transition Metal"
)
PeriodicItem(
"23", "50.9415", "V", "Vanadium", "Transition Metal"
)
PeriodicItem(
"24", "51.996", "Cr", "Chromium", "Transition Metal"
)
PeriodicItem(
"25", "54.93804", "Mn", "Manganese", "Transition Metal"
)
PeriodicItem(
"26", "55.84", "Fe", "Iron", "Transition Metal"
)
PeriodicItem(
"27", "58.93319", "Co", "Cobalt", "Transition Metal"
)
PeriodicItem(
"28", "58.693", "Ni", "Nickel", "Transition Metal"
)
PeriodicItem(
"29", "63.55", "Cu", "Copper", "Transition Metal"
)
PeriodicItem(
"30", "65.4", "Zn", "Zinc", "Transition Metal"
)
PeriodicItem(
"31", "69.723", "Ga", "Gallium", "Post-Transition Metal"
)
PeriodicItem(
"32", "72.63", "Ge", "Germanium", "Metalloid"
)
PeriodicItem(
"33", "74.92159", "As", "Arsenic", "Metalloid"
)
PeriodicItem(
"34", "78.97", "Se", "Selenium", "Nonmetal"
)
PeriodicItem(
"35", "79.90", "Br", "Bromine", "Halogen"
)
PeriodicItem(
"36", "83.80", "Kr", "Krypton", "Noble Gas"
)
}
Row(horizontalArrangement = Arrangement.spacedBy(horizontalSpacing)) {
PeriodicItem(
"37", "85.468", "Rb", "Rubidium", "Alkali Metal"
)
PeriodicItem(
"38", "87.62", "Sr", "Strontium", "Alkaline Earth Metal"
)
PeriodicItem(
"39", "88.90584", "Y", "Yttrium", "Transition Metal"
)
PeriodicItem(
"40", "91.22", "Zr", "Zirconium", "Transition Metal"
)
PeriodicItem(
"41", "92.90637", "Nb", "Niobium", "Transition Metal"
)
PeriodicItem(
"42", "95.95", "Mo", "Molybdenum", "Transition Metal"
)
PeriodicItem(
"43", "96.90636", "Tc", "Technetium", "Transition Metal"
)
PeriodicItem(
"44", "101.1", "Ru", "Ruthenium", "Transition Metal"
)
PeriodicItem(
"45", "102.9055", "Rh", "Rhodium", "Transition Metal"
)
PeriodicItem(
"46", "106.42", "Pd", "Palladium", "Transition Metal"
)
PeriodicItem(
"47", "107.868", "Ag", "Silver", "Transition Metal"
)
PeriodicItem(
"48", "112.41", "Cd", "Cadmium", "Transition Metal"
)
PeriodicItem(
"49", "114.818", "In", "Indium", "Post-Transition Metal"
)
PeriodicItem(
"50", "118.71", "Sn", "Tin", "Post-Transition Metal"
)
PeriodicItem(
"51", "121.760", "Sb", "Antimony", "Metalloid"
)
PeriodicItem(
"52", "127.6", "Te", "Tellurium", "Metalloid"
)
PeriodicItem(
"53", "126.9045", "I", "Iodine", "Halogen"
)
PeriodicItem(
"54", "131.29", "Xe", "Xenon", "Noble Gas"
)
}
Row(horizontalArrangement = Arrangement.spacedBy(horizontalSpacing)) {
PeriodicItem(
"55", "<tel:132.9054520|132.9054520>", "Cs", "Cesium", "Alkali Metal"
)
PeriodicItem(
"56", "137.33", "Ba", "Barium", "Alkaline Earth Metal"
)
PeriodicSpacer()
PeriodicItem(
"72", "178.49", "Hf", "Hafnium", "Transition Metal"
)
PeriodicItem(
"73", "180.9479", "Ta", "Tantalum", "Transition Metal"
)
PeriodicItem(
"74", "183.84", "W", "Tungsten", "Transition Metal"
)
PeriodicItem(
"75", "186.207", "Re", "Rhenium", "Transition Metal"
)
PeriodicItem(
"76", "190.2", "Os", "Osmium", "Transition Metal"
)
PeriodicItem(
"77", "192.22", "Ir", "Iridium", "Transition Metal"
)
PeriodicItem(
"78", "195.08", "Pt", "Platinum", "Transition Metal"
)
PeriodicItem(
"79", "196.96657", "Au", "Gold", "Transition Metal"
)
PeriodicItem(
"80", "200.59", "Hg", "Mercury", "Transition Metal"
)
PeriodicItem(
"81", "204.383", "Tl", "Thallium", "Post-Transition Metal"
)
PeriodicItem(
"82", "207", "Pb", "Lead", "Post-Transition Metal"
)
PeriodicItem(
"83", "208.98040", "Bi", "Bismuth", "Post-Transition Metal"
)
PeriodicItem(
"84", "208.98243", "Po", "Polonium", "Metalloid"
)
PeriodicItem(
"85", "209.98715", "At", "Astatine", "Halogen"
)
PeriodicItem(
"86", "222.01758", "Rn", "Radon", "Noble Gas"
)
}
Row(horizontalArrangement = Arrangement.spacedBy(horizontalSpacing)) {
PeriodicItem(
"87", "223.01973", "Fr", "Francium", "Alkali Metal"
)
PeriodicItem(
"88", "226.02541", "Ra", "Radium", "Alkaline Earth Metal"
)
PeriodicSpacer()
PeriodicItem(
"104", "267.122", "Rf", "Rutherfordium", "Transition Metal"
)
PeriodicItem(
"105", "268.126", "Db", "Dubnium", "Transition Metal"
)
PeriodicItem(
"106", "269.128", "Sg", "Seaborgium", "Transition Metal"
)
PeriodicItem(
"107", "270.133", "Bh", "Bohrium", "Transition Metal"
)
PeriodicItem(
"108", "269.1336", "Hs", "Hassium", "Transition Metal"
)
PeriodicItem(
"109", "277.154", "Mt", "Meitnerium", "Transition Metal"
)
PeriodicItem(
"110", "282.166", "Ds", "Darmstadtium", "Transition Metal"
)
PeriodicItem(
"111", "282.169", "Rg", "Roentgenium", "Transition Metal"
)
PeriodicItem(
"112", "286.179", "Cn", "Copernicium", "Transition Metal"
)
PeriodicItem(
"113", "286.182", "Nh", "Nihonium", "Post-Transition Metal"
)
PeriodicItem(
"114", "290.192", "Fl", "Flerovium", "Post-Transition Metal"
)
PeriodicItem(
"115", "290.196", "Mc", "Moscovium", "Post-Transition Metal"
)
PeriodicItem(
"116", "293.205", "Lv", "Livermorium", "Metalloid"
)
PeriodicItem(
"117", "294.211", "Ts", "Tennessine", "Halogen"
)
PeriodicItem(
"118", "295.216", "Og", "Oganesson", "Noble Gas"
)
}
// last row ommitted (too long)
}
Kiet
11/01/2024, 3:44 AM@Composable
fun PeriodicItem(
number: String,
atomicNumber: String,
symbol: String,
name: String,
chemicalGroupBlock: String,
) {
var atomicNumberFontSize by remember { mutableStateOf(13.sp) }
var atomicNumberTextWidth by remember { mutableStateOf(0f) }
var nameFontSize by remember { mutableStateOf(13.sp) }
var nameTextWidth by remember { mutableStateOf(0f) }
var chemicalGroupBlockFontSize by remember { mutableStateOf(13.sp) }
var chemicalGroupBlockTextWidth by remember { mutableStateOf(0f) }
var boxWidth by remember { mutableStateOf(0f) }
val atomicNumberLength = atomicNumber.length
val atomicNumberRatio = if (atomicNumberLength >= 3) 0.6 else 0.7
Column(horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceBetween,
modifier = periodicItemModifier(Color.Black)
.onGloballyPositioned { layoutCoordinates ->
// Measure the width of the Box
boxWidth = layoutCoordinates.boundsInParent().width
}) {
Row(
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxWidth().padding(start = 3.dp, end = 3.dp)
) {
Text(number)
Text(atomicNumber,
fontSize = atomicNumberFontSize,
modifier = Modifier.onGloballyPositioned { textCoordinates ->
atomicNumberTextWidth = textCoordinates.boundsInParent().width
println("name: $name, $chemicalGroupBlock, boxWidth: $boxWidth, textWidth: $chemicalGroupBlockTextWidth")
// Adjust font size if text is wider than the available box width
if ((atomicNumberTextWidth) >= (boxWidth * atomicNumberRatio)) {
atomicNumberFontSize *= 0.95f // Reduce font size by 5%
}
})
}
Text(symbol, fontSize = 25.sp, fontWeight = FontWeight.Bold)
Text(name, fontSize = nameFontSize, fontWeight = FontWeight.SemiBold,
maxLines = 1,
modifier = Modifier.onGloballyPositioned { textCoordinates ->
nameTextWidth = textCoordinates.boundsInParent().width
if ((nameTextWidth) >= (boxWidth * 0.95)) {
nameFontSize *= 0.95f // Reduce font size by 5%
}
})
Text(chemicalGroupBlock, maxLines = 1,
fontSize = chemicalGroupBlockFontSize,
modifier = Modifier
.onGloballyPositioned { textCoordinates ->
// Measure the width of the text
chemicalGroupBlockTextWidth = textCoordinates.boundsInParent().width
println("$chemicalGroupBlock, boxWidth: $boxWidth, textWidth: $chemicalGroupBlockTextWidth")
// Adjust font size if text is wider than the available box width
if ((chemicalGroupBlockTextWidth + 10) >= boxWidth) {
chemicalGroupBlockFontSize *= 0.95f // Reduce font size by 5%
}
})
}
}
@Composable
fun PeriodicSpacer() {
var boxWidth by remember { mutableStateOf(0f) }
Column(
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceBetween,
modifier = periodicItemModifier(Color.Transparent)
) {
}
}
Kiet
11/01/2024, 4:40 AM@OptIn(ExperimentalComposeUiApi::class)
fun main() = application {
Window(
title = "Test",
state = rememberWindowState(
size = DpSize(1600.dp, 800.dp)
),
undecorated = false,
onCloseRequest = ::exitApplication
) {
var scale by remember { mutableStateOf(1f) }
var rotation by remember { mutableStateOf(0f) }
var offset by remember { mutableStateOf(Offset.Zero) }
val state = rememberTransformableState { zoomChange, offsetChange, rotationChange ->
scale *= zoomChange
rotation += rotationChange
offset += offsetChange * scale
}
val stateVertical = rememberScrollState(0)
Box(modifier = Modifier
.fillMaxSize()
.onRotaryScrollEvent { e ->
println("Got scroll event: $e")
true
}
.onPointerEvent(PointerEventType.Scroll) { e ->
val event = e.changes.firstOrNull()
if (event != null) {
println("scrollDelta: ${event.scrollDelta.toString()}")
val y = event.scrollDelta.y
val scaleFactor = 0.1f
scale = max(scale * (1 - (y * scaleFactor)), 0.5f)
}
}
.verticalScroll(stateVertical, enabled = false)
.graphicsLayer(
scaleX = scale,
scaleY = scale,
rotationZ = rotation,
translationX = offset.x,
translationY = offset.y,
clip = false
)
.transformable(state)
) {
PeriodicTable()
}
}
}
Kiet
11/01/2024, 4:42 AMAlbert Chang
11/01/2024, 6:08 AMModifier.graphicsLayer()
only changes how the content is drawn. It doesn't change the layout size. What you actually need is likely a .wrapContentSize(align = Alignment.TopStart, unbounded = true)
before .graphicsLayer()
.
Also please don't post long code snippets to the channel.Kiet
11/01/2024, 6:32 AM