对比新文件 |
| | |
| | | <template> |
| | | <el-color-picker |
| | | v-model="theme" |
| | | :predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]" |
| | | class="theme-picker" |
| | | popper-class="theme-picker-dropdown" |
| | | /> |
| | | </template> |
| | | |
| | | <script> |
| | | const version = require('element-ui/package.json').version // element-ui version from node_modules |
| | | const ORIGINAL_THEME = '#409EFF' // default color |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | chalk: '', // content of theme-chalk css |
| | | theme: '' |
| | | } |
| | | }, |
| | | computed: { |
| | | defaultTheme() { |
| | | return this.$store.state.settings.theme |
| | | } |
| | | }, |
| | | watch: { |
| | | defaultTheme: { |
| | | handler: function(val, oldVal) { |
| | | this.theme = val |
| | | }, |
| | | immediate: true |
| | | }, |
| | | async theme(val) { |
| | | await this.setTheme(val) |
| | | } |
| | | }, |
| | | created() { |
| | | if(this.defaultTheme !== ORIGINAL_THEME) { |
| | | this.setTheme(this.defaultTheme) |
| | | } |
| | | }, |
| | | |
| | | methods: { |
| | | async setTheme(val) { |
| | | const oldVal = this.chalk ? this.theme : ORIGINAL_THEME |
| | | if (typeof val !== 'string') return |
| | | const themeCluster = this.getThemeCluster(val.replace('#', '')) |
| | | const originalCluster = this.getThemeCluster(oldVal.replace('#', '')) |
| | | |
| | | const getHandler = (variable, id) => { |
| | | return () => { |
| | | const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', '')) |
| | | const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster) |
| | | |
| | | let styleTag = document.getElementById(id) |
| | | if (!styleTag) { |
| | | styleTag = document.createElement('style') |
| | | styleTag.setAttribute('id', id) |
| | | document.head.appendChild(styleTag) |
| | | } |
| | | styleTag.innerText = newStyle |
| | | } |
| | | } |
| | | |
| | | if (!this.chalk) { |
| | | const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css` |
| | | await this.getCSSString(url, 'chalk') |
| | | } |
| | | |
| | | const chalkHandler = getHandler('chalk', 'chalk-style') |
| | | |
| | | chalkHandler() |
| | | |
| | | const styles = [].slice.call(document.querySelectorAll('style')) |
| | | .filter(style => { |
| | | const text = style.innerText |
| | | return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text) |
| | | }) |
| | | styles.forEach(style => { |
| | | const { innerText } = style |
| | | if (typeof innerText !== 'string') return |
| | | style.innerText = this.updateStyle(innerText, originalCluster, themeCluster) |
| | | }) |
| | | |
| | | this.$emit('change', val) |
| | | }, |
| | | |
| | | updateStyle(style, oldCluster, newCluster) { |
| | | let newStyle = style |
| | | oldCluster.forEach((color, index) => { |
| | | newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index]) |
| | | }) |
| | | return newStyle |
| | | }, |
| | | |
| | | getCSSString(url, variable) { |
| | | return new Promise(resolve => { |
| | | const xhr = new XMLHttpRequest() |
| | | xhr.onreadystatechange = () => { |
| | | if (xhr.readyState === 4 && xhr.status === 200) { |
| | | this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '') |
| | | resolve() |
| | | } |
| | | } |
| | | xhr.open('GET', url) |
| | | xhr.send() |
| | | }) |
| | | }, |
| | | |
| | | getThemeCluster(theme) { |
| | | const tintColor = (color, tint) => { |
| | | let red = parseInt(color.slice(0, 2), 16) |
| | | let green = parseInt(color.slice(2, 4), 16) |
| | | let blue = parseInt(color.slice(4, 6), 16) |
| | | |
| | | if (tint === 0) { // when primary color is in its rgb space |
| | | return [red, green, blue].join(',') |
| | | } else { |
| | | red += Math.round(tint * (255 - red)) |
| | | green += Math.round(tint * (255 - green)) |
| | | blue += Math.round(tint * (255 - blue)) |
| | | |
| | | red = red.toString(16) |
| | | green = green.toString(16) |
| | | blue = blue.toString(16) |
| | | |
| | | return `#${red}${green}${blue}` |
| | | } |
| | | } |
| | | |
| | | const shadeColor = (color, shade) => { |
| | | let red = parseInt(color.slice(0, 2), 16) |
| | | let green = parseInt(color.slice(2, 4), 16) |
| | | let blue = parseInt(color.slice(4, 6), 16) |
| | | |
| | | red = Math.round((1 - shade) * red) |
| | | green = Math.round((1 - shade) * green) |
| | | blue = Math.round((1 - shade) * blue) |
| | | |
| | | red = red.toString(16) |
| | | green = green.toString(16) |
| | | blue = blue.toString(16) |
| | | |
| | | return `#${red}${green}${blue}` |
| | | } |
| | | |
| | | const clusters = [theme] |
| | | for (let i = 0; i <= 9; i++) { |
| | | clusters.push(tintColor(theme, Number((i / 10).toFixed(2)))) |
| | | } |
| | | clusters.push(shadeColor(theme, 0.1)) |
| | | return clusters |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style> |
| | | .theme-message, |
| | | .theme-picker-dropdown { |
| | | z-index: 99999 !important; |
| | | } |
| | | |
| | | .theme-picker .el-color-picker__trigger { |
| | | height: 26px !important; |
| | | width: 26px !important; |
| | | padding: 2px; |
| | | } |
| | | |
| | | .theme-picker-dropdown .el-color-dropdown__link-btn { |
| | | display: none; |
| | | } |
| | | </style> |