1
1
<template >
2
- <div class =" sticky-theme" :style =" stickyThemeStyle" >
3
- <div class =" theme-status" >
4
- <p class =" theme-status-title" >{{ title }}</p >
5
- <p class =" theme-status-subtitle" >{{ subtitleText }}</p >
2
+ <div class =" sticky-theme" :style =" stickyThemeStyle" v-if =" !!theme" >
3
+ <div class =" theme-status" ></div >
4
+ <div v-if =" isAnimating" class =" theme-status color-transition" ></div >
5
+ <div class =" theme-text" >
6
+ <p class =" theme-text-title" >{{ title }}</p >
7
+ <p class =" theme-text-subtitle" >{{ subtitleText }}</p >
6
8
</div >
7
9
</div >
8
10
</template >
9
11
<script >
10
- import langMixin from " ../i18n/mixin" ;
12
+ import langMixin from ' ../i18n/mixin' ;
11
13
export default {
12
- name: " StickyExport" ,
14
+ name: ' StickyExport' ,
13
15
props: {
14
16
top: Number ,
15
17
theme: {
16
18
type: Object ,
17
19
},
18
20
},
19
21
mixins: [langMixin],
22
+ data () {
23
+ return {
24
+ isAnimating: false ,
25
+ brandColor: null ,
26
+ styleObserver: null ,
27
+ };
28
+ },
20
29
computed: {
21
30
stickyThemeStyle () {
22
31
return {
@@ -30,32 +39,73 @@ export default {
30
39
return this .theme .subtitleText ;
31
40
},
32
41
},
42
+ mounted () {
43
+ this .brandColor = getComputedStyle (document .documentElement ).getPropertyValue (' --td-brand-color' ).trim ();
44
+ this .setupStyleObserver ();
45
+ },
46
+ methods: {
47
+ setupStyleObserver () {
48
+ this .styleObserver = new MutationObserver (this .checkBrandColorChange );
49
+ this .styleObserver .observe (document .documentElement , {
50
+ attributes: true ,
51
+ attributeFilter: [' style' , ' class' ],
52
+ });
53
+ },
54
+ checkBrandColorChange () {
55
+ const newColor = getComputedStyle (document .documentElement ).getPropertyValue (' --td-brand-color' ).trim ();
56
+ if (newColor && newColor !== this .brandColor ) {
57
+ this .brandColor = newColor;
58
+ this .isAnimating = true ;
59
+
60
+ setTimeout (() => {
61
+ this .isAnimating = false ;
62
+ }, 1000 );
63
+ }
64
+ },
65
+ },
66
+ beforeDestroy () {
67
+ if (this .styleObserver ) {
68
+ this .styleObserver .disconnect ();
69
+ }
70
+ },
33
71
};
34
72
</script >
73
+
35
74
<style scoped lang="less">
36
75
.sticky-theme {
76
+ position : relative ;
37
77
display : flex ;
38
78
flex-direction : column ;
39
79
align-items : center ;
40
80
padding : 8px ;
81
+ margin-bottom : 5px ;
41
82
left : 0 ;
42
83
}
43
84
44
85
.theme-status {
86
+ position : absolute ;
45
87
background-color : var (--td-brand-color );
88
+ transition : background- color 1s ease ;
46
89
width : 332px ;
47
90
height : 72px ;
48
91
padding : 8px 12px ;
49
92
border-radius : 12px ;
93
+ z-index : 0 ;
94
+ inset : 0 ;
95
+ }
96
+
97
+ .theme-text {
98
+ width : 100% ;
99
+ padding : 2px 8px ;
100
+ z-index : 1 ;
50
101
51
102
&-title {
52
103
font-size : 20px ;
53
104
line-height : 24px ;
54
105
font-weight : 700 ;
55
106
color : #fff ;
56
107
margin : 0 0 10px 0 ;
57
- font-family : ui-monospace , SFMono- Regular, " SF Mono" , Menlo, Consolas,
58
- " Liberation Mono" , monospace ;
108
+ font-family : ui-monospace , SFMono- Regular, ' SF Mono' , Menlo, Consolas, ' Liberation Mono' , monospace ;
59
109
}
60
110
61
111
&-subtitle {
@@ -65,4 +115,18 @@ export default {
65
115
margin : 0 ;
66
116
}
67
117
}
118
+
119
+ .color-transition {
120
+ animation : prev- to- current 1s ease ;
121
+ }
122
+
123
+ @keyframes prev- to- current {
124
+ from {
125
+ clip-path : polygon (0 0 , 0 0 , calc (tan (8deg ) * -100vh ) 100% , calc (tan (8deg ) * -100vh ) 100% );
126
+ }
127
+
128
+ to {
129
+ clip-path : polygon (0 0 , calc ((tan (8deg ) * 100vh ) + 100% ) 0 , 100% 100% , calc (tan (8deg ) * -100vh ) 100% );
130
+ }
131
+ }
68
132
</style >
0 commit comments