mirror of
https://akkoma.dev/AkkomaGang/akkoma-fe
synced 2025-04-30 11:09:30 +08:00
During code review a much better way was pointed out to do the emoji scaling, by using `em`. *key uses 2em for emoji, which is smaller than Akkoma has. I now kept the 38px for Akkoma, but when "zoom" (ie x2, x3, x4, tada) happens, we set to 2em and zoom from there.
423 lines
9.6 KiB
SCSS
423 lines
9.6 KiB
SCSS
/**
|
|
* "FEP-c16b: Formatting MFM functions" attributes that Akkoma supports
|
|
*/
|
|
|
|
.StatusContent:not(.mfm-disabled) {
|
|
/* The following are the non-animated MFM */
|
|
.mfm-center {
|
|
display: block;
|
|
text-align: center;
|
|
}
|
|
|
|
.mfm-flip {
|
|
display: inline-block;
|
|
transform: scaleX(-1);
|
|
}
|
|
|
|
.mfm-flip[data-mfm-v] {
|
|
transform: scaleY(-1);
|
|
}
|
|
|
|
.mfm-flip[data-mfm-v][data-mfm-h] {
|
|
transform: scale(-1, -1);
|
|
}
|
|
|
|
.mfm-font[data-mfm-serif] {
|
|
font-family: serif;
|
|
}
|
|
|
|
.mfm-font[data-mfm-monospace] {
|
|
font-family: monospace;
|
|
}
|
|
|
|
.mfm-font[data-mfm-cursive] {
|
|
font-family: cursive;
|
|
}
|
|
|
|
.mfm-font[data-mfm-fantasy] {
|
|
font-family: fantasy;
|
|
}
|
|
|
|
.mfm-font[data-mfm-emoji] {
|
|
font-family: emoji;
|
|
}
|
|
|
|
.mfm-font[data-mfm-math] {
|
|
font-family: math;
|
|
}
|
|
|
|
.mfm-blur {
|
|
filter: blur(6px);
|
|
transition: filter 0.3s;
|
|
|
|
&:hover {
|
|
filter: blur(0);
|
|
}
|
|
}
|
|
|
|
.mfm-rotate {
|
|
display: inline-block;
|
|
transform: rotate(calc(var(--mfm-deg, 90) * 1deg));
|
|
transform-origin: center center;
|
|
}
|
|
|
|
.mfm-x2 {
|
|
--mfm-zoom-size: 200%;
|
|
}
|
|
|
|
.mfm-x3 {
|
|
--mfm-zoom-size: 400%;
|
|
}
|
|
|
|
.mfm-x4 {
|
|
--mfm-zoom-size: 600%;
|
|
}
|
|
|
|
.mfm-x2,
|
|
.mfm-x3,
|
|
.mfm-x4,
|
|
.mfm-tada {
|
|
.emoji {
|
|
--emoji-size: 2em;
|
|
}
|
|
font-size: var(--mfm-zoom-size);
|
|
|
|
.mfm-x2,
|
|
.mfm-x3,
|
|
.mfm-x4,
|
|
.mfm-tada {
|
|
/* only half effective */
|
|
font-size: calc(var(--mfm-zoom-size) / 2 + 50%);
|
|
|
|
.mfm-x2,
|
|
.mfm-x3,
|
|
.mfm-x4,
|
|
.mfm-tada {
|
|
/* disabled */
|
|
font-size: 100%;
|
|
}
|
|
}
|
|
}
|
|
|
|
.mfm-position {
|
|
display: inline-block;
|
|
transform: translate(calc(var(--mfm-x, 0) * 1em), calc(var(--mfm-y, 0) * 1em));
|
|
}
|
|
|
|
.mfm-scale {
|
|
display: inline-block;
|
|
transform: scale(var(--mfm-x, 1), var(--mfm-y, 1));
|
|
}
|
|
|
|
.mfm-fg {
|
|
color: var(--mfm-color, #f00);
|
|
}
|
|
|
|
.mfm-bg {
|
|
background-color: var(--mfm-color, #0f0);
|
|
}
|
|
|
|
/* The following are the animated MFM */
|
|
|
|
/* .mfm-hover means that we should only play animation when hovering over the StatusContent
|
|
* So either StatusContent does not have this class,
|
|
* or it has the class and we are hovering over StatusContent
|
|
*/
|
|
&:not(.mfm-hover:not(:hover)) {
|
|
.mfm-jelly {
|
|
display: inline-block;
|
|
animation: mfm-rubberBand var(--mfm-speed, 1s) linear infinite both;
|
|
}
|
|
|
|
.mfm-twitch {
|
|
display: inline-block;
|
|
animation: mfm-twitch var(--mfm-speed, 0.5s) ease infinite;
|
|
}
|
|
|
|
.mfm-shake {
|
|
display: inline-block;
|
|
animation: mfm-shake var(--mfm-speed, 0.5s) ease infinite;
|
|
}
|
|
|
|
.mfm-spin {
|
|
display: inline-block;
|
|
animation: mfm-spin var(--mfm-speed, 1.5s) linear infinite;
|
|
}
|
|
|
|
.mfm-spin[data-mfm-y] {
|
|
animation-name: mfm-spinY;
|
|
}
|
|
|
|
.mfm-spin[data-mfm-x] {
|
|
animation-name: mfm-spinX;
|
|
}
|
|
|
|
.mfm-spin[data-mfm-alternate] {
|
|
animation-direction: alternate;
|
|
}
|
|
|
|
.mfm-spin[data-mfm-left] {
|
|
animation-direction: reverse;
|
|
}
|
|
|
|
.mfm-jump {
|
|
display: inline-block;
|
|
animation: mfm-jump var(--mfm-speed, 0.75s) linear infinite;
|
|
}
|
|
|
|
.mfm-bounce {
|
|
display: inline-block;
|
|
animation: mfm-bounce var(--mfm-speed, 0.75s) linear infinite;
|
|
transform-origin: center bottom;
|
|
}
|
|
|
|
.mfm-rainbow {
|
|
animation: mfm-rainbow var(--mfm-speed, 1s) linear infinite;
|
|
}
|
|
|
|
.mfm-tada {
|
|
display: inline-block;
|
|
animation: mfm-tada var(--mfm-speed, 1s) linear infinite both;
|
|
|
|
--mfm-zoom-size: 150%;
|
|
}
|
|
}
|
|
|
|
/* animation keyframes */
|
|
|
|
@keyframes mfm-spin {
|
|
0% { transform: rotate(0deg); }
|
|
100% { transform: rotate(360deg); }
|
|
}
|
|
|
|
@keyframes mfm-spinX {
|
|
0% { transform: perspective(128px) rotateX(0deg); }
|
|
100% { transform: perspective(128px) rotateX(360deg); }
|
|
}
|
|
|
|
@keyframes mfm-spinY {
|
|
0% { transform: perspective(128px) rotateY(0deg); }
|
|
100% { transform: perspective(128px) rotateY(360deg); }
|
|
}
|
|
|
|
@keyframes mfm-jump {
|
|
0% { transform: translateY(0); }
|
|
25% { transform: translateY(-16px); }
|
|
50% { transform: translateY(0); }
|
|
75% { transform: translateY(-8px); }
|
|
100% { transform: translateY(0); }
|
|
}
|
|
|
|
@keyframes mfm-bounce {
|
|
0% { transform: translateY(0) scale(1, 1); }
|
|
25% { transform: translateY(-16px) scale(1, 1); }
|
|
50% { transform: translateY(0) scale(1, 1); }
|
|
75% { transform: translateY(0) scale(1.5, 0.75); }
|
|
100% { transform: translateY(0) scale(1, 1); }
|
|
}
|
|
|
|
@keyframes mfm-twitch {
|
|
0% { transform: translate(7px, -2px); }
|
|
5% { transform: translate(-3px, 1px); }
|
|
10% { transform: translate(-7px, -1px); }
|
|
15% { transform: translate(0, -1px); }
|
|
20% { transform: translate(-8px, 6px); }
|
|
25% { transform: translate(-4px, -3px); }
|
|
30% { transform: translate(-4px, -6px); }
|
|
35% { transform: translate(-8px, -8px); }
|
|
40% { transform: translate(4px, 6px); }
|
|
45% { transform: translate(-3px, 1px); }
|
|
50% { transform: translate(2px, -10px); }
|
|
55% { transform: translate(-7px, 0); }
|
|
60% { transform: translate(-2px, 4px); }
|
|
65% { transform: translate(3px, -8px); }
|
|
70% { transform: translate(6px, 7px); }
|
|
75% { transform: translate(-7px, -2px); }
|
|
80% { transform: translate(-7px, -8px); }
|
|
85% { transform: translate(9px, 3px); }
|
|
90% { transform: translate(-3px, -2px); }
|
|
95% { transform: translate(-10px, 2px); }
|
|
100% { transform: translate(-2px, -6px); }
|
|
}
|
|
|
|
@keyframes mfm-shake {
|
|
0% { transform: translate(-3px, -1px) rotate(-8deg); }
|
|
5% { transform: translate(0, -1px) rotate(-10deg); }
|
|
10% { transform: translate(1px, -3px) rotate(0deg); }
|
|
15% { transform: translate(1px, 1px) rotate(11deg); }
|
|
20% { transform: translate(-2px, 1px) rotate(1deg); }
|
|
25% { transform: translate(-1px, -2px) rotate(-2deg); }
|
|
30% { transform: translate(-1px, 2px) rotate(-3deg); }
|
|
35% { transform: translate(2px, 1px) rotate(6deg); }
|
|
40% { transform: translate(-2px, -3px) rotate(-9deg); }
|
|
45% { transform: translate(0, -1px) rotate(-12deg); }
|
|
50% { transform: translate(1px, 2px) rotate(10deg); }
|
|
55% { transform: translate(0, -3px) rotate(8deg); }
|
|
60% { transform: translate(1px, -1px) rotate(8deg); }
|
|
65% { transform: translate(0, -1px) rotate(-7deg); }
|
|
70% { transform: translate(-1px, -3px) rotate(6deg); }
|
|
75% { transform: translate(0, -2px) rotate(4deg); }
|
|
80% { transform: translate(-2px, -1px) rotate(3deg); }
|
|
85% { transform: translate(1px, -3px) rotate(-10deg); }
|
|
90% { transform: translate(1px, 0) rotate(3deg); }
|
|
95% { transform: translate(-2px, 0) rotate(-3deg); }
|
|
100% { transform: translate(2px, 1px) rotate(2deg); }
|
|
}
|
|
|
|
@keyframes mfm-rubberBand {
|
|
0% { transform: scale3d(1, 1, 1); }
|
|
30% { transform: scale3d(1.25, 0.75, 1); }
|
|
40% { transform: scale3d(0.75, 1.25, 1); }
|
|
50% { transform: scale3d(1.15, 0.85, 1); }
|
|
65% { transform: scale3d(0.95, 1.05, 1); }
|
|
75% { transform: scale3d(1.05, 0.95, 1); }
|
|
100% { transform: scale3d(1, 1, 1); }
|
|
}
|
|
|
|
@keyframes mfm-rainbow {
|
|
0% { filter: hue-rotate(0deg) contrast(150%) saturate(150%); }
|
|
100% { filter: hue-rotate(360deg) contrast(150%) saturate(150%); }
|
|
}
|
|
|
|
@keyframes mfm-tada {
|
|
0%,
|
|
100% { transform: scale3d(1, 1, 1); }
|
|
|
|
10%,
|
|
20% { transform: scale3d(0.9, 0.9, 0.9) rotate3d(0, 0, 1, -3deg); }
|
|
|
|
30%,
|
|
50%,
|
|
70%,
|
|
90% { transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); }
|
|
|
|
40%,
|
|
60%,
|
|
80% { transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); }
|
|
}
|
|
|
|
/**
|
|
* Legacy MFM
|
|
* This is for backwards compatibility with posts formatted on Akkoma before support for FEP-c16b
|
|
* Note that it uses the keyframes as defined above for the FEP-c16b compatible MFM representation
|
|
*/
|
|
|
|
.mfm {
|
|
display: inline-block;
|
|
}
|
|
|
|
/* The following are the legacy non-animated MFM */
|
|
._mfm_flip_[data-h][data-v] {
|
|
transform: scale(-1, -1);
|
|
}
|
|
|
|
._mfm_flip_[data-v] {
|
|
transform: scaleY(-1);
|
|
}
|
|
|
|
._mfm_flip_:not([data-v]) {
|
|
transform: scaleX(-1);
|
|
}
|
|
|
|
._mfm_x2_ {
|
|
font-size: 200%;
|
|
}
|
|
|
|
._mfm_x3_ {
|
|
font-size: 400%;
|
|
}
|
|
|
|
._mfm_x4_ {
|
|
font-size: 600%;
|
|
}
|
|
|
|
._mfm_x2_ {
|
|
.emoji {
|
|
height: 100px;
|
|
}
|
|
}
|
|
|
|
._mfm_x3_ {
|
|
.emoji {
|
|
height: 150px;
|
|
}
|
|
}
|
|
|
|
._mfm_x4_ {
|
|
.emoji {
|
|
height: 200px;
|
|
}
|
|
}
|
|
|
|
._mfm_blur_ {
|
|
filter: blur(6px);
|
|
transition: filter 0.3s;
|
|
}
|
|
|
|
._mfm_blur_:hover {
|
|
filter: blur(0);
|
|
}
|
|
|
|
._mfm_rotate_ {
|
|
transform: rotate(90deg);
|
|
transform-origin: center center;
|
|
}
|
|
|
|
/* The following are the legacy animated MFM */
|
|
|
|
/* .mfm-hover means that we should only play animation when hovering over the StatusContent
|
|
* So either StatusContent does not have this class,
|
|
* or it has the class and we are hovering over StatusContent
|
|
*/
|
|
&:not(.mfm-hover:not(:hover)) {
|
|
._mfm_tada_ {
|
|
font-size: 150%;
|
|
animation: mfm-tada 1s linear infinite both;
|
|
}
|
|
|
|
._mfm_jelly_ {
|
|
animation: mfm-rubberBand 1s linear infinite both;
|
|
}
|
|
|
|
._mfm_twitch_ {
|
|
animation: mfm-twitch 0.5s ease infinite;
|
|
}
|
|
|
|
._mfm_shake_ {
|
|
animation: mfm-shake 0.5s ease infinite;
|
|
}
|
|
|
|
._mfm_spin_ {
|
|
animation: mfm-spin 0.5s linear infinite;
|
|
}
|
|
|
|
._mfm_spin_[data-x] {
|
|
animation-name: mfm-spinX;
|
|
}
|
|
|
|
._mfm_spin_[data-y] {
|
|
animation-name: mfm-spinY;
|
|
}
|
|
|
|
._mfm_spin_[left] {
|
|
animation-direction: reverse;
|
|
}
|
|
|
|
._mfm_spin_[alternate] {
|
|
animation-direction: alternate;
|
|
}
|
|
|
|
._mfm_jump_ {
|
|
animation: mfm-jump 0.75s linear infinite;
|
|
}
|
|
|
|
._mfm_bounce_ {
|
|
animation: mfm-bounce 0.75s linear infinite;
|
|
transform-origin: center bottom;
|
|
}
|
|
|
|
._mfm_rainbow_ {
|
|
animation: mfm-rainbow 1s linear infinite;
|
|
}
|
|
}
|
|
}
|