├── .babelrc
├── .editorconfig
├── .gitignore
├── README.md
├── build
├── build.js
├── check-versions.js
├── dev-client.js
├── dev-server.js
├── utils.js
├── webpack.base.conf.js
├── webpack.dev.conf.js
└── webpack.prod.conf.js
├── config
├── dev.env.js
├── index.js
└── prod.env.js
├── index.html
├── less
├── colors.less
├── mixins.less
├── theme-vars.less
├── theme.less
└── vars.less
├── npm-debug.log.2541962448
├── package-lock.json
├── package.json
├── src
├── App.vue
├── assets
│ └── logo.png
├── components
│ ├── AppSide.vue
│ ├── Controls.vue
│ ├── Lyric.vue
│ └── SongList.vue
├── main.js
├── router.js
├── store
│ ├── TencentMusicAPI.php
│ ├── api.js
│ └── index.js
├── styles
│ ├── base.less
│ ├── colors.less
│ ├── import.less
│ ├── mixins.less
│ ├── normalize.css
│ ├── themes
│ │ ├── carbon.less
│ │ ├── dark.less
│ │ ├── default.less
│ │ └── teal.less
│ ├── vars.less
│ └── zIndex.less
└── views
│ ├── index.vue
│ └── player.vue
└── static
├── .gitkeep
├── hot_all.js
├── playlist.js
└── vue-animated-list.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "stage-2"],
3 | "plugins": ["transform-runtime"],
4 | "comments": false,
5 | "env": {
6 | "test": {
7 | "plugins": [ "istanbul" ]
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | dist/
4 | npm-debug.log
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-music-qq
2 |
3 | > A Vue.js project for music
4 | ### Use
5 | * vuejs-2.1.7
6 | * vue-cli
7 | * vue-router
8 | * vuex
9 | * muse-ui
10 |
11 |
12 | ## Support
13 | * Chrome
14 | * Firefox
15 | * Mobile browser
16 |
17 | ## Build Setup
18 |
19 | ``` bash
20 | # install dependencies
21 | npm install
22 |
23 | # serve with hot reload at localhost:8080
24 | npm run dev
25 |
26 | # build for production with minification
27 | npm run build
28 | ```
29 | ## Demo site
30 |
31 | http://weixin.nmict.cn/vue-music-qq/
32 |
33 | # Conatct
34 |
35 | - Tencent QQ: 342878509
36 | - E-mail: xiongmao1114@163.com
37 | - Github: https://github.com/pluto1114/vue-music-qq
38 |
--------------------------------------------------------------------------------
/build/build.js:
--------------------------------------------------------------------------------
1 | // https://github.com/shelljs/shelljs
2 | require('./check-versions')()
3 | require('shelljs/global')
4 | env.NODE_ENV = 'production'
5 |
6 | var path = require('path')
7 | var config = require('../config')
8 | var ora = require('ora')
9 | var webpack = require('webpack')
10 | var webpackConfig = require('./webpack.prod.conf')
11 |
12 | console.log(
13 | ' Tip:\n' +
14 | ' Built files are meant to be served over an HTTP server.\n' +
15 | ' Opening index.html over file:// won\'t work.\n'
16 | )
17 |
18 | var spinner = ora('building for production...')
19 | spinner.start()
20 |
21 | var assetsPath = path.join(config.build.assetsRoot, config.build.assetsSubDirectory)
22 | rm('-rf', assetsPath)
23 | mkdir('-p', assetsPath)
24 | cp('-R', 'static/*', assetsPath)
25 |
26 | webpack(webpackConfig, function (err, stats) {
27 | spinner.stop()
28 | if (err) throw err
29 | process.stdout.write(stats.toString({
30 | colors: true,
31 | modules: false,
32 | children: false,
33 | chunks: false,
34 | chunkModules: false
35 | }) + '\n')
36 | })
37 |
--------------------------------------------------------------------------------
/build/check-versions.js:
--------------------------------------------------------------------------------
1 | var semver = require('semver')
2 | var chalk = require('chalk')
3 | var packageConfig = require('../package.json')
4 | var exec = function (cmd) {
5 | return require('child_process')
6 | .execSync(cmd).toString().trim()
7 | }
8 |
9 | var versionRequirements = [
10 | {
11 | name: 'node',
12 | currentVersion: semver.clean(process.version),
13 | versionRequirement: packageConfig.engines.node
14 | },
15 | {
16 | name: 'npm',
17 | currentVersion: exec('npm --version'),
18 | versionRequirement: packageConfig.engines.npm
19 | }
20 | ]
21 |
22 | module.exports = function () {
23 | var warnings = []
24 | for (var i = 0; i < versionRequirements.length; i++) {
25 | var mod = versionRequirements[i]
26 | if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
27 | warnings.push(mod.name + ': ' +
28 | chalk.red(mod.currentVersion) + ' should be ' +
29 | chalk.green(mod.versionRequirement)
30 | )
31 | }
32 | }
33 |
34 | if (warnings.length) {
35 | console.log('')
36 | console.log(chalk.yellow('To use this template, you must update following to modules:'))
37 | console.log()
38 | for (var i = 0; i < warnings.length; i++) {
39 | var warning = warnings[i]
40 | console.log(' ' + warning)
41 | }
42 | console.log()
43 | process.exit(1)
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/build/dev-client.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | require('eventsource-polyfill')
3 | var hotClient = require('webpack-hot-middleware/client?noInfo=true&reload=true')
4 |
5 | hotClient.subscribe(function (event) {
6 | if (event.action === 'reload') {
7 | window.location.reload()
8 | }
9 | })
10 |
--------------------------------------------------------------------------------
/build/dev-server.js:
--------------------------------------------------------------------------------
1 | require('./check-versions')()
2 | var config = require('../config')
3 | if (!process.env.NODE_ENV) process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
4 | var path = require('path')
5 | var express = require('express')
6 | var webpack = require('webpack')
7 | var opn = require('opn')
8 | var proxyMiddleware = require('http-proxy-middleware')
9 | var webpackConfig = require('./webpack.dev.conf')
10 |
11 | // default port where dev server listens for incoming traffic
12 | var port = process.env.PORT || config.dev.port
13 | // Define HTTP proxies to your custom API backend
14 | // https://github.com/chimurai/http-proxy-middleware
15 | var proxyTable = config.dev.proxyTable
16 |
17 | var app = express()
18 | var compiler = webpack(webpackConfig)
19 |
20 | var devMiddleware = require('webpack-dev-middleware')(compiler, {
21 | publicPath: webpackConfig.output.publicPath,
22 | quiet: true
23 | })
24 |
25 | var hotMiddleware = require('webpack-hot-middleware')(compiler, {
26 | log: () => {}
27 | })
28 | // force page reload when html-webpack-plugin template changes
29 | compiler.plugin('compilation', function (compilation) {
30 | compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
31 | hotMiddleware.publish({ action: 'reload' })
32 | cb()
33 | })
34 | })
35 |
36 | // proxy api requests
37 | Object.keys(proxyTable).forEach(function (context) {
38 | var options = proxyTable[context]
39 | if (typeof options === 'string') {
40 | options = { target: options }
41 | }
42 | app.use(proxyMiddleware(context, options))
43 | })
44 |
45 | // handle fallback for HTML5 history API
46 | app.use(require('connect-history-api-fallback')())
47 |
48 | // serve webpack bundle output
49 | app.use(devMiddleware)
50 |
51 | // enable hot-reload and state-preserving
52 | // compilation error display
53 | app.use(hotMiddleware)
54 |
55 | // serve pure static assets
56 | var staticPath = path.posix.join(config.dev.assetsPublicPath, config.dev.assetsSubDirectory)
57 | app.use(staticPath, express.static('./static'))
58 |
59 | var uri = 'http://localhost:' + port
60 |
61 | devMiddleware.waitUntilValid(function () {
62 | console.log('> Listening at ' + uri + '\n')
63 | })
64 |
65 | module.exports = app.listen(port, function (err) {
66 | if (err) {
67 | console.log(err)
68 | return
69 | }
70 |
71 | // when env is testing, don't need open it
72 | if (process.env.NODE_ENV !== 'testing') {
73 | opn(uri)
74 | }
75 | })
76 |
--------------------------------------------------------------------------------
/build/utils.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var config = require('../config')
3 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
4 |
5 | exports.assetsPath = function (_path) {
6 | var assetsSubDirectory = process.env.NODE_ENV === 'production'
7 | ? config.build.assetsSubDirectory
8 | : config.dev.assetsSubDirectory
9 | return path.posix.join(assetsSubDirectory, _path)
10 | }
11 |
12 | exports.cssLoaders = function (options) {
13 | options = options || {}
14 | // generate loader string to be used with extract text plugin
15 | function generateLoaders (loaders) {
16 | var sourceLoader = loaders.map(function (loader) {
17 | var extraParamChar
18 | if (/\?/.test(loader)) {
19 | loader = loader.replace(/\?/, '-loader?')
20 | extraParamChar = '&'
21 | } else {
22 | loader = loader + '-loader'
23 | extraParamChar = '?'
24 | }
25 | return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '')
26 | }).join('!')
27 |
28 | // Extract CSS when that option is specified
29 | // (which is the case during production build)
30 | if (options.extract) {
31 | return ExtractTextPlugin.extract('vue-style-loader', sourceLoader)
32 | } else {
33 | return ['vue-style-loader', sourceLoader].join('!')
34 | }
35 | }
36 |
37 | // http://vuejs.github.io/vue-loader/en/configurations/extract-css.html
38 | return {
39 | css: generateLoaders(['css']),
40 | postcss: generateLoaders(['css']),
41 | less: generateLoaders(['css', 'less']),
42 | sass: generateLoaders(['css', 'sass?indentedSyntax']),
43 | scss: generateLoaders(['css', 'sass']),
44 | stylus: generateLoaders(['css', 'stylus']),
45 | styl: generateLoaders(['css', 'stylus'])
46 | }
47 | }
48 |
49 | // Generate loaders for standalone style files (outside of .vue)
50 | exports.styleLoaders = function (options) {
51 | var output = []
52 | var loaders = exports.cssLoaders(options)
53 | for (var extension in loaders) {
54 | var loader = loaders[extension]
55 | output.push({
56 | test: new RegExp('\\.' + extension + '$'),
57 | loader: loader
58 | })
59 | }
60 | return output
61 | }
62 |
--------------------------------------------------------------------------------
/build/webpack.base.conf.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var config = require('../config')
3 | var utils = require('./utils')
4 | var projectRoot = path.resolve(__dirname, '../')
5 |
6 | var env = process.env.NODE_ENV
7 | // check env & config/index.js to decide whether to enable CSS source maps for the
8 | // various preprocessor loaders added to vue-loader at the end of this file
9 | var cssSourceMapDev = (env === 'development' && config.dev.cssSourceMap)
10 | var cssSourceMapProd = (env === 'production' && config.build.productionSourceMap)
11 | var useCssSourceMap = cssSourceMapDev || cssSourceMapProd
12 |
13 | module.exports = {
14 | entry: {
15 | app: './src/main.js'
16 | },
17 | output: {
18 | path: config.build.assetsRoot,
19 | publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath,
20 | filename: '[name].js'
21 | },
22 | resolve: {
23 | extensions: ['', '.js', '.vue', '.json'],
24 | fallback: [path.join(__dirname, '../node_modules')],
25 | alias: {
26 | 'vue$': 'vue/dist/vue.common.js',
27 | 'src': path.resolve(__dirname, '../src'),
28 | 'assets': path.resolve(__dirname, '../src/assets'),
29 | 'components': path.resolve(__dirname, '../src/components')
30 | }
31 | },
32 | resolveLoader: {
33 | fallback: [path.join(__dirname, '../node_modules')]
34 | },
35 | module: {
36 | loaders: [
37 | {
38 | test: /\.vue$/,
39 | loader: 'vue'
40 | },
41 | {
42 | test: /\.js$/,
43 | loader: 'babel',
44 | include: [
45 | path.join(projectRoot, 'src')
46 | ],
47 | exclude: /node_modules/
48 | },
49 | {
50 | test: /\.json$/,
51 | loader: 'json'
52 | },
53 | {
54 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
55 | loader: 'url',
56 | query: {
57 | limit: 10000,
58 | name: utils.assetsPath('img/[name].[hash:7].[ext]')
59 | }
60 | },
61 | {
62 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
63 | loader: 'url',
64 | query: {
65 | limit: 10000,
66 | name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
67 | }
68 | }
69 | ]
70 | },
71 | vue: {
72 | loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }),
73 | postcss: [
74 | require('autoprefixer')({
75 | browsers: ['last 20 versions']
76 | })
77 | ]
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/build/webpack.dev.conf.js:
--------------------------------------------------------------------------------
1 | var config = require('../config')
2 | var webpack = require('webpack')
3 | var merge = require('webpack-merge')
4 | var utils = require('./utils')
5 | var baseWebpackConfig = require('./webpack.base.conf')
6 | var HtmlWebpackPlugin = require('html-webpack-plugin')
7 | var FriendlyErrors = require('friendly-errors-webpack-plugin')
8 |
9 | // add hot-reload related code to entry chunks
10 | Object.keys(baseWebpackConfig.entry).forEach(function (name) {
11 | baseWebpackConfig.entry[name] = ['./build/dev-client'].concat(baseWebpackConfig.entry[name])
12 | })
13 |
14 | module.exports = merge(baseWebpackConfig, {
15 | module: {
16 | loaders: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
17 | },
18 | // eval-source-map is faster for development
19 | devtool: '#eval-source-map',
20 | plugins: [
21 | new webpack.DefinePlugin({
22 | 'process.env': config.dev.env
23 | }),
24 | // https://github.com/glenjamin/webpack-hot-middleware#installation--usage
25 | new webpack.optimize.OccurrenceOrderPlugin(),
26 | new webpack.HotModuleReplacementPlugin(),
27 | new webpack.NoErrorsPlugin(),
28 | // https://github.com/ampedandwired/html-webpack-plugin
29 | new HtmlWebpackPlugin({
30 | filename: 'index.html',
31 | template: 'index.html',
32 | inject: true
33 | }),
34 | new FriendlyErrors()
35 | ]
36 | })
37 |
--------------------------------------------------------------------------------
/build/webpack.prod.conf.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var config = require('../config')
3 | var utils = require('./utils')
4 | var webpack = require('webpack')
5 | var merge = require('webpack-merge')
6 | var baseWebpackConfig = require('./webpack.base.conf')
7 | var ExtractTextPlugin = require('extract-text-webpack-plugin')
8 | var HtmlWebpackPlugin = require('html-webpack-plugin')
9 | var env = config.build.env
10 |
11 | var webpackConfig = merge(baseWebpackConfig, {
12 | module: {
13 | loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true })
14 | },
15 | devtool: config.build.productionSourceMap ? '#source-map' : false,
16 | output: {
17 | path: config.build.assetsRoot,
18 | filename: utils.assetsPath('js/[name].[chunkhash].js'),
19 | chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
20 | },
21 | vue: {
22 | loaders: utils.cssLoaders({
23 | sourceMap: config.build.productionSourceMap,
24 | extract: true
25 | })
26 | },
27 | plugins: [
28 | // http://vuejs.github.io/vue-loader/en/workflow/production.html
29 | new webpack.DefinePlugin({
30 | 'process.env': env
31 | }),
32 | new webpack.optimize.UglifyJsPlugin({
33 | compress: {
34 | warnings: false
35 | }
36 | }),
37 | new webpack.optimize.OccurrenceOrderPlugin(),
38 | // extract css into its own file
39 | new ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')),
40 | // generate dist index.html with correct asset hash for caching.
41 | // you can customize output by editing /index.html
42 | // see https://github.com/ampedandwired/html-webpack-plugin
43 | new HtmlWebpackPlugin({
44 | filename: config.build.index,
45 | template: 'index.html',
46 | inject: true,
47 | minify: {
48 | removeComments: true,
49 | collapseWhitespace: true,
50 | removeAttributeQuotes: true
51 | // more options:
52 | // https://github.com/kangax/html-minifier#options-quick-reference
53 | },
54 | // necessary to consistently work with multiple chunks via CommonsChunkPlugin
55 | chunksSortMode: 'dependency'
56 | }),
57 | // split vendor js into its own file
58 | new webpack.optimize.CommonsChunkPlugin({
59 | name: 'vendor',
60 | minChunks: function (module, count) {
61 | // any required modules inside node_modules are extracted to vendor
62 | return (
63 | module.resource &&
64 | /\.js$/.test(module.resource) &&
65 | module.resource.indexOf(
66 | path.join(__dirname, '../node_modules')
67 | ) === 0
68 | )
69 | }
70 | }),
71 | // extract webpack runtime and module manifest to its own file in order to
72 | // prevent vendor hash from being updated whenever app bundle is updated
73 | new webpack.optimize.CommonsChunkPlugin({
74 | name: 'manifest',
75 | chunks: ['vendor']
76 | })
77 | ]
78 | })
79 |
80 | if (config.build.productionGzip) {
81 | var CompressionWebpackPlugin = require('compression-webpack-plugin')
82 |
83 | webpackConfig.plugins.push(
84 | new CompressionWebpackPlugin({
85 | asset: '[path].gz[query]',
86 | algorithm: 'gzip',
87 | test: new RegExp(
88 | '\\.(' +
89 | config.build.productionGzipExtensions.join('|') +
90 | ')$'
91 | ),
92 | threshold: 10240,
93 | minRatio: 0.8
94 | })
95 | )
96 | }
97 |
98 | module.exports = webpackConfig
99 |
--------------------------------------------------------------------------------
/config/dev.env.js:
--------------------------------------------------------------------------------
1 | var merge = require('webpack-merge')
2 | var prodEnv = require('./prod.env')
3 |
4 | module.exports = merge(prodEnv, {
5 | NODE_ENV: '"development"'
6 | })
7 |
--------------------------------------------------------------------------------
/config/index.js:
--------------------------------------------------------------------------------
1 | // see http://vuejs-templates.github.io/webpack for documentation.
2 | var path = require('path')
3 |
4 | module.exports = {
5 | build: {
6 | env: require('./prod.env'),
7 | index: path.resolve(__dirname, '../dist/index.html'),
8 | assetsRoot: path.resolve(__dirname, '../dist'),
9 | assetsSubDirectory: 'static',
10 | assetsPublicPath: './',
11 | productionSourceMap: true,
12 | // Gzip off by default as many popular static hosts such as
13 | // Surge or Netlify already gzip all static assets for you.
14 | // Before setting to `true`, make sure to:
15 | // npm install --save-dev compression-webpack-plugin
16 | productionGzip: false,
17 | productionGzipExtensions: ['js', 'css']
18 | },
19 | dev: {
20 | env: require('./dev.env'),
21 | port: 8080,
22 | assetsSubDirectory: 'static',
23 | assetsPublicPath: '/',
24 | proxyTable: {
25 | '/qq-m-api':{
26 | target:'http://c.y.qq.com/',
27 | changeOrigin:true,
28 | pathRewrite:{
29 | '^/qq-m-api':''
30 | }
31 | }
32 | },
33 | // CSS Sourcemaps off by default because relative paths are "buggy"
34 | // with this option, according to the CSS-Loader README
35 | // (https://github.com/webpack/css-loader#sourcemaps)
36 | // In our experience, they generally work as expected,
37 | // just be aware of this issue when enabling this option.
38 | cssSourceMap: false
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/config/prod.env.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | NODE_ENV: '"production"'
3 | }
4 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | vue-music-qq
7 |
8 |
9 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/less/colors.less:
--------------------------------------------------------------------------------
1 | @red50: #ffebee;
2 | @red100: #ffcdd2;
3 | @red200: #ef9a9a;
4 | @red300: #e57373;
5 | @red400: #ef5350;
6 | @red500: #f44336;
7 | @red600: #e53935;
8 | @red700: #d32f2f;
9 | @red800: #c62828;
10 | @red900: #b71c1c;
11 | @redA100: #ff8a80;
12 | @redA200: #ff5252;
13 | @redA400: #ff1744;
14 | @redA700: #d50000;
15 | @red: @red500;
16 |
17 | @pink50: #fce4ec;
18 | @pink100: #f8bbd0;
19 | @pink200: #f48fb1;
20 | @pink300: #f06292;
21 | @pink400: #ec407a;
22 | @pink500: #e91e63;
23 | @pink600: #d81b60;
24 | @pink700: #c2185b;
25 | @pink800: #ad1457;
26 | @pink900: #880e4f;
27 | @pinkA100: #ff80ab;
28 | @pinkA200: #ff4081;
29 | @pinkA400: #f50057;
30 | @pinkA700: #c51162;
31 | @pink: @pink500;
32 |
33 | @purple50: #f3e5f5;
34 | @purple100: #e1bee7;
35 | @purple200: #ce93d8;
36 | @purple300: #ba68c8;
37 | @purple400: #ab47bc;
38 | @purple500: #9c27b0;
39 | @purple600: #8e24aa;
40 | @purple700: #7b1fa2;
41 | @purple800: #6a1b9a;
42 | @purple900: #4a148c;
43 | @purpleA100: #ea80fc;
44 | @purpleA200: #e040fb;
45 | @purpleA400: #d500f9;
46 | @purpleA700: #aa00ff;
47 | @purple: @purple500;
48 |
49 | @deepPurple50: #ede7f6;
50 | @deepPurple100: #d1c4e9;
51 | @deepPurple200: #b39ddb;
52 | @deepPurple300: #9575cd;
53 | @deepPurple400: #7e57c2;
54 | @deepPurple500: #673ab7;
55 | @deepPurple600: #5e35b1;
56 | @deepPurple700: #512da8;
57 | @deepPurple800: #4527a0;
58 | @deepPurple900: #311b92;
59 | @deepPurpleA100: #b388ff;
60 | @deepPurpleA200: #7c4dff;
61 | @deepPurpleA400: #651fff;
62 | @deepPurpleA700: #6200ea;
63 | @deepPurple: @deepPurple500;
64 |
65 | @indigo50: #e8eaf6;
66 | @indigo100: #c5cae9;
67 | @indigo200: #9fa8da;
68 | @indigo300: #7986cb;
69 | @indigo400: #5c6bc0;
70 | @indigo500: #3f51b5;
71 | @indigo600: #3949ab;
72 | @indigo700: #303f9f;
73 | @indigo800: #283593;
74 | @indigo900: #1a237e;
75 | @indigoA100: #8c9eff;
76 | @indigoA200: #536dfe;
77 | @indigoA400: #3d5afe;
78 | @indigoA700: #304ffe;
79 | @indigo: @indigo500;
80 |
81 | @blue50: #e3f2fd;
82 | @blue100: #bbdefb;
83 | @blue200: #90caf9;
84 | @blue300: #64b5f6;
85 | @blue400: #42a5f5;
86 | @blue500: #2196f3;
87 | @blue600: #1e88e5;
88 | @blue700: #1976d2;
89 | @blue800: #1565c0;
90 | @blue900: #0d47a1;
91 | @blueA100: #82b1ff;
92 | @blueA200: #448aff;
93 | @blueA400: #2979ff;
94 | @blueA700: #2962ff;
95 | @blue: @blue500;
96 |
97 | @lightBlue50: #e1f5fe;
98 | @lightBlue100: #b3e5fc;
99 | @lightBlue200: #81d4fa;
100 | @lightBlue300: #4fc3f7;
101 | @lightBlue400: #29b6f6;
102 | @lightBlue500: #03a9f4;
103 | @lightBlue600: #039be5;
104 | @lightBlue700: #0288d1;
105 | @lightBlue800: #0277bd;
106 | @lightBlue900: #01579b;
107 | @lightBlueA100: #80d8ff;
108 | @lightBlueA200: #40c4ff;
109 | @lightBlueA400: #00b0ff;
110 | @lightBlueA700: #0091ea;
111 | @lightBlue: @lightBlue500;
112 |
113 | @cyan50: #e0f7fa;
114 | @cyan100: #b2ebf2;
115 | @cyan200: #80deea;
116 | @cyan300: #4dd0e1;
117 | @cyan400: #26c6da;
118 | @cyan500: #00bcd4;
119 | @cyan600: #00acc1;
120 | @cyan700: #0097a7;
121 | @cyan800: #00838f;
122 | @cyan900: #006064;
123 | @cyanA100: #84ffff;
124 | @cyanA200: #18ffff;
125 | @cyanA400: #00e5ff;
126 | @cyanA700: #00b8d4;
127 | @cyan: @cyan500;
128 |
129 | @teal50: #e0f2f1;
130 | @teal100: #b2dfdb;
131 | @teal200: #80cbc4;
132 | @teal300: #4db6ac;
133 | @teal400: #26a69a;
134 | @teal500: #009688;
135 | @teal600: #00897b;
136 | @teal700: #00796b;
137 | @teal800: #00695c;
138 | @teal900: #004d40;
139 | @tealA100: #a7ffeb;
140 | @tealA200: #64ffda;
141 | @tealA400: #1de9b6;
142 | @tealA700: #00bfa5;
143 | @teal: @teal500;
144 |
145 | @green50: #e8f5e9;
146 | @green100: #c8e6c9;
147 | @green200: #a5d6a7;
148 | @green300: #81c784;
149 | @green400: #66bb6a;
150 | @green500: #4caf50;
151 | @green600: #43a047;
152 | @green700: #388e3c;
153 | @green800: #2e7d32;
154 | @green900: #1b5e20;
155 | @greenA100: #b9f6ca;
156 | @greenA200: #69f0ae;
157 | @greenA400: #00e676;
158 | @greenA700: #00c853;
159 | @green: @green500;
160 |
161 | @lightGreen50: #f1f8e9;
162 | @lightGreen100: #dcedc8;
163 | @lightGreen200: #c5e1a5;
164 | @lightGreen300: #aed581;
165 | @lightGreen400: #9ccc65;
166 | @lightGreen500: #8bc34a;
167 | @lightGreen600: #7cb342;
168 | @lightGreen700: #689f38;
169 | @lightGreen800: #558b2f;
170 | @lightGreen900: #33691e;
171 | @lightGreenA100: #ccff90;
172 | @lightGreenA200: #b2ff59;
173 | @lightGreenA400: #76ff03;
174 | @lightGreenA700: #64dd17;
175 | @lightGreen: @lightGreen500;
176 |
177 | @lime50: #f9fbe7;
178 | @lime100: #f0f4c3;
179 | @lime200: #e6ee9c;
180 | @lime300: #dce775;
181 | @lime400: #d4e157;
182 | @lime500: #cddc39;
183 | @lime600: #c0ca33;
184 | @lime700: #afb42b;
185 | @lime800: #9e9d24;
186 | @lime900: #827717;
187 | @limeA100: #f4ff81;
188 | @limeA200: #eeff41;
189 | @limeA400: #c6ff00;
190 | @limeA700: #aeea00;
191 | @lime: @lime500;
192 |
193 | @yellow50: #fffde7;
194 | @yellow100: #fff9c4;
195 | @yellow200: #fff59d;
196 | @yellow300: #fff176;
197 | @yellow400: #ffee58;
198 | @yellow500: #ffeb3b;
199 | @yellow600: #fdd835;
200 | @yellow700: #fbc02d;
201 | @yellow800: #f9a825;
202 | @yellow900: #f57f17;
203 | @yellowA100: #ffff8d;
204 | @yellowA200: #ffff00;
205 | @yellowA400: #ffea00;
206 | @yellowA700: #ffd600;
207 | @yellow: @yellow500;
208 |
209 | @amber50: #fff8e1;
210 | @amber100: #ffecb3;
211 | @amber200: #ffe082;
212 | @amber300: #ffd54f;
213 | @amber400: #ffca28;
214 | @amber500: #ffc107;
215 | @amber600: #ffb300;
216 | @amber700: #ffa000;
217 | @amber800: #ff8f00;
218 | @amber900: #ff6f00;
219 | @amberA100: #ffe57f;
220 | @amberA200: #ffd740;
221 | @amberA400: #ffc400;
222 | @amberA700: #ffab00;
223 | @amber: @amber500;
224 |
225 | @orange50: #fff3e0;
226 | @orange100: #ffe0b2;
227 | @orange200: #ffcc80;
228 | @orange300: #ffb74d;
229 | @orange400: #ffa726;
230 | @orange500: #ff9800;
231 | @orange600: #fb8c00;
232 | @orange700: #f57c00;
233 | @orange800: #ef6c00;
234 | @orange900: #e65100;
235 | @orangeA100: #ffd180;
236 | @orangeA200: #ffab40;
237 | @orangeA400: #ff9100;
238 | @orangeA700: #ff6d00;
239 | @orange: @orange500;
240 |
241 | @deepOrange50: #fbe9e7;
242 | @deepOrange100: #ffccbc;
243 | @deepOrange200: #ffab91;
244 | @deepOrange300: #ff8a65;
245 | @deepOrange400: #ff7043;
246 | @deepOrange500: #ff5722;
247 | @deepOrange600: #f4511e;
248 | @deepOrange700: #e64a19;
249 | @deepOrange800: #d84315;
250 | @deepOrange900: #bf360c;
251 | @deepOrangeA100: #ff9e80;
252 | @deepOrangeA200: #ff6e40;
253 | @deepOrangeA400: #ff3d00;
254 | @deepOrangeA700: #dd2c00;
255 | @deepOrange: @deepOrange500;
256 |
257 | @brown50: #efebe9;
258 | @brown100: #d7ccc8;
259 | @brown200: #bcaaa4;
260 | @brown300: #a1887f;
261 | @brown400: #8d6e63;
262 | @brown500: #795548;
263 | @brown600: #6d4c41;
264 | @brown700: #5d4037;
265 | @brown800: #4e342e;
266 | @brown900: #3e2723;
267 | @brown: @brown500;
268 |
269 | @blueGrey50: #eceff1;
270 | @blueGrey100: #cfd8dc;
271 | @blueGrey200: #b0bec5;
272 | @blueGrey300: #90a4ae;
273 | @blueGrey400: #78909c;
274 | @blueGrey500: #607d8b;
275 | @blueGrey600: #546e7a;
276 | @blueGrey700: #455a64;
277 | @blueGrey800: #37474f;
278 | @blueGrey900: #263238;
279 | @blueGrey: @blueGrey500;
280 |
281 | @grey50: #fafafa;
282 | @grey100: #f5f5f5;
283 | @grey200: #eeeeee;
284 | @grey300: #e0e0e0;
285 | @grey400: #bdbdbd;
286 | @grey500: #9e9e9e;
287 | @grey600: #757575;
288 | @grey700: #616161;
289 | @grey800: #424242;
290 | @grey900: #212121;
291 | @grey: @grey500;
292 |
293 | @black: #000000;
294 | @white: #ffffff;
295 |
296 | @transparent: rgba(0, 0, 0, 0);
297 | @fullBlack: rgba(0, 0, 0, 1);
298 | @darkBlack: rgba(0, 0, 0, 0.87);
299 | @lightBlack: rgba(0, 0, 0, 0.54);
300 | @minBlack: rgba(0, 0, 0, 0.26);
301 | @faintBlack: rgba(0, 0, 0, 0.12);
302 | @fullWhite: rgba(255, 255, 255, 1);
303 | @darkWhite: rgba(255, 255, 255, 0.87);
304 | @lightWhite: rgba(255, 255, 255, 0.54);
305 |
--------------------------------------------------------------------------------
/less/mixins.less:
--------------------------------------------------------------------------------
1 | .transition(@d) {
2 | -webkit-transition-duration: @d;
3 | transition-duration: @d;
4 | }
5 | .delay(@d) {
6 | -webkit-transition-delay: @d;
7 | transition-delay: @d;
8 | }
9 | .transform(@t) {
10 | -webkit-transform: @t;
11 | transform: @t;
12 | }
13 | .transform-origin(@to) {
14 | -webkit-transform-origin: @to;
15 | transform-origin: @to;
16 | }
17 | .translate3d(@x:0, @y:0, @z:0) {
18 | -webkit-transform: translate3d(@x,@y,@z);
19 | transform: translate3d(@x,@y,@z);
20 | }
21 | .animation (@a) {
22 | -webkit-animation: @a;
23 | animation: @a;
24 | }
25 | .scrollable() {
26 | overflow: auto;
27 | -webkit-overflow-scrolling: touch;
28 | }
29 | .flex-shrink(@fs) {
30 | -webkit-box-flex: @fs;
31 | -webkit-flex-shrink: @fs;
32 | -ms-flex: 0 @fs auto;
33 | flex-shrink: @fs;
34 | }
35 | .clearfix() {
36 | &:after,
37 | &:before {
38 | content: " ";
39 | display: table;
40 | }
41 | &:after {
42 | clear: both;
43 | }
44 | }
45 | .hairline(@position, @color) when (@position = top) {
46 | &:before {
47 | content: '';
48 | position: absolute;
49 | left: 0;
50 | top: 0;
51 | bottom: auto;
52 | right: auto;
53 | height: 1px;
54 | width: 100%;
55 | background-color: @color;
56 | display: block;
57 | z-index: 15;
58 | // .transform-origin(50% 0%);
59 | html.pixel-ratio-2 & {
60 | .transform(scaleY(0.5));
61 | }
62 | html.pixel-ratio-3 & {
63 | .transform(scaleY(0.33));
64 | }
65 | }
66 | }
67 | .hairline(@position, @color) when (@position = left) {
68 | &:before {
69 | content: '';
70 | position: absolute;
71 | left: 0;
72 | top: 0;
73 | bottom: auto;
74 | right: auto;
75 | width: 1px;
76 | height: 100%;
77 | background-color: @color;
78 | display: block;
79 | z-index: 15;
80 | // .transform-origin(0% 50%);
81 | html.pixel-ratio-2 & {
82 | .transform(scaleX(0.5));
83 | }
84 | html.pixel-ratio-3 & {
85 | .transform(scaleX(0.33));
86 | }
87 | }
88 |
89 | }
90 | .hairline(@position, @color) when (@position = bottom) {
91 | &:after {
92 | content: '';
93 | position: absolute;
94 | left: 0;
95 | bottom: 0;
96 | right: auto;
97 | top: auto;
98 | height: 1px;
99 | width: 100%;
100 | background-color: @color;
101 | display: block;
102 | z-index: 15;
103 | html.pixel-ratio-2 & {
104 | .transform(scaleY(0.5));
105 | }
106 | html.pixel-ratio-3 & {
107 | .transform(scaleY(0.33));
108 | }
109 | }
110 | }
111 | .hairline(@position, @color) when (@position = right) {
112 | &:after {
113 | content: '';
114 | position: absolute;
115 | right: 0;
116 | top: 0;
117 | left: auto;
118 | bottom: auto;
119 | width: 1px;
120 | height: 100%;
121 | background-color: @color;
122 | display: block;
123 | z-index: 15;
124 | // .transform-origin(100% 50%);
125 | html.pixel-ratio-2 & {
126 | .transform(scaleX(0.5));
127 | }
128 | html.pixel-ratio-3 & {
129 | .transform(scaleX(0.33));
130 | }
131 | }
132 | }
133 | // For right and bottom
134 | .hairline-remove(@position) when not (@position = left) and not (@position = top) {
135 | &:after {
136 | display: none;
137 | }
138 | }
139 | // For left and top
140 | .hairline-remove(@position) when not (@position = right) and not (@position = bottom) {
141 | &:before {
142 | display: none;
143 | }
144 | }
145 | // For right and bottom
146 | .hairline-color(@position, @color) when not (@position = left) and not (@position = top) {
147 | &:after {
148 | background-color: @color;
149 | }
150 | }
151 | // For left and top
152 | .hairline-color(@position, @color) when not (@position = right) and not (@position = bottom) {
153 | &:before {
154 | background-color: @color;
155 | }
156 | }
157 | // Encoded SVG Background
158 | .encoded-svg-background(@svg) {
159 | @url: `encodeURIComponent(@{svg})`;
160 | background-image: url("data:image/svg+xml;charset=utf-8,@{url}");
161 | }
162 | // Preserve3D
163 | .preserve3d() {
164 | -webkit-transform-style: preserve-3d;
165 | -moz-transform-style: preserve-3d;
166 | -ms-transform-style: preserve-3d;
167 | transform-style: preserve-3d;
168 | }
169 | // Shadow
170 | .depth(@level:1) {
171 | & when (@level = 1) {
172 | box-shadow: rgba(0, 0, 0, 0.117647) 0px 1px 6px, rgba(0, 0, 0, 0.117647) 0px 1px 4px;
173 | }
174 | & when (@level = 2) {
175 | box-shadow: rgba(0, 0, 0, 0.156863) 0px 3px 10px, rgba(0, 0, 0, 0.227451) 0px 3px 10px;
176 | }
177 | & when (@level = 3) {
178 | box-shadow: rgba(0, 0, 0, 0.188235) 0px 10px 30px, rgba(0, 0, 0, 0.227451) 0px 6px 10px;
179 | }
180 | & when (@level = 4) {
181 | box-shadow: rgba(0, 0, 0, 0.247059) 0px 14px 45px, rgba(0, 0, 0, 0.219608) 0px 10px 18px;
182 | }
183 | & when (@level = 5) {
184 | box-shadow: rgba(0, 0, 0, 0.298039) 0px 19px 60px, rgba(0, 0, 0, 0.219608) 0px 15px 20px;
185 | }
186 | }
187 | // Highlighted Links
188 | .active-highlight(@color:rgba(255, 255, 255, 0.15)){
189 | &:before {
190 | content: '';
191 | width: 100%;
192 | height: 100%;
193 | position: absolute;
194 | left: 0;
195 | top: 0;
196 | background-color: @color;
197 | background-repeat: no-repeat;
198 | background-position: center;
199 | background-size: 100% 100%;
200 | opacity: 0;
201 | pointer-events: none;
202 | .transition(600ms);
203 | }
204 | &.active-state:before,
205 | html:not(.watch-active-state) &:active:before {
206 | opacity: 1;
207 | .transition(150ms);
208 | }
209 | }
210 | .active-highlight-color(@color) {
211 | &:before {
212 | background-image: -webkit-radial-gradient(center, circle cover, @color 66%, rgba(red(@color),green(@color),blue(@color),0) 66%);
213 | background-image: radial-gradient(circle at center, @color 66%, rgba(red(@color),green(@color),blue(@color),0) 66%);
214 | }
215 | }
216 | // No Scrollbar
217 | .no-scrollbar() {
218 | &::-webkit-scrollbar {
219 | display: none !important;
220 | width: 0 !important;
221 | height: 0 !important;
222 | -webkit-appearance: none;
223 | opacity: 0 !important;
224 | }
225 | }
226 |
227 |
228 | .ellipsis() {
229 | white-space:nowrap;
230 | text-overflow:ellipsis;
231 | overflow:hidden;
232 | word-wrap: break-word;
233 | }
234 |
--------------------------------------------------------------------------------
/less/theme-vars.less:
--------------------------------------------------------------------------------
1 | @appbarColor: @primaryColor;
2 | @appbarTextColor: @alternateTextColor;
3 |
4 | @avatarColor: @alternateTextColor;
5 | @avatarBackgroundColor: darken(@alternateTextColor, 26%);
6 |
7 | @badgeColor: @lighterPrimaryColor;
8 | @badgeTextColor: @alternateTextColor;
9 | @badgePrimaryColor: @primaryColor;
10 | @badgePrimaryTextColor: @alternateTextColor;
11 | @badgeSecondaryColor: @accentColor;
12 | @badgeSecondaryTextColor: @alternateTextColor;
13 |
14 | @baseFontFamily: @fontFamily;
15 | @baseTextColor: @textColor;
16 | @baseBackgroundColor: @backgroundColor;
17 | @baseLinkColor: @accentColor;
18 |
19 | @bottomNavBackgroundColor: @dialogBackgroundColor;
20 | @bottomNavShiftBackgroundColor: @primaryColor;
21 | @bottomNavUnselectedColor: @secondaryTextColor;
22 | @bottomNavShiftUnselectedColor: fade(@alternateTextColor, 70%);
23 | @bottomNavSelectedColor: @primaryColor;
24 | @bottomNavShiftSelectedColor: @alternateTextColor;
25 |
26 | @bottomSheetColor: @dialogBackgroundColor;
27 |
28 | @cardBackgroudColor: @backgroundColor;
29 | @cardTitleColor: fade(@textColor, 87%);
30 | @cardSubtitleColor: fade(@textColor, 54%);
31 | @cardMediaColor: @darkWhite;
32 | @cardMediaOverlayContentBackground: @lightBlack;
33 | @cardMediaTitleColor: @darkWhite;
34 | @cardMediaSubtitleColor: @lightWhite;
35 | @cardTextColor: @textColor;
36 |
37 | @checkboxColor: @textColor;
38 | @checkboxTextColor: @textColor;
39 | @checkboxDisabledColor: @disabledColor;
40 | @checkboxCheckedColor: @primaryColor;
41 |
42 | @chipColor: darken(@alternateTextColor, 12%);
43 | @chipHoverColor: rgb(206, 206, 206);
44 | @chipTextColor: fade(@textColor, 87%);
45 | @chipDeleteColor: fade(@textColor, 26%);
46 | @chipHoverDeleteColor: fade(fade(@textColor, 26%), 40%);
47 |
48 | @circularProgressColor: @primaryColor;
49 |
50 | @datePickerColor: @primaryColor;
51 | @datePickerTextColor: @alternateTextColor;
52 | @datePickerCalendarTextColor: @textColor;
53 | @datePickerSelectColor: @primaryColor;
54 | @datePickerSelectTextColor: @alternateTextColor;
55 | @datePickerCalendarYearBackgroundColor: @dialogBackgroundColor;
56 | @datePickerHeaderColor: @primaryColor;
57 |
58 | @dialogBorderColor: @borderColor;
59 | @dialogTitleColor: @textColor;
60 | @dialogBodyColor: fade(@textColor, 60%);;
61 | @dialogColor: @dialogBackgroundColor;
62 |
63 | @dropDownMenuTextColor: @textColor;
64 | @dropDownMenuIconColor: @borderColor;
65 | @dropDownMenuLineColor: @borderColor;
66 |
67 | // flatButton
68 | @flatButtonColor: transparent;
69 | @flatButtonTextColor: @textColor;
70 | @flatButtonPrimaryTextColor: @primaryColor;
71 | @flatButtonSecondaryTextColor: @accentColor;
72 |
73 | // floatButton
74 | @floatButtonColor: @primaryColor;
75 | @floatButtonIconColor: @alternateTextColor;
76 | @floatButtonSecondaryColor: @accentColor;
77 | @floatButtonSecondaryIconColor: @alternateTextColor;
78 | @floatButtonDisabledColor: darken(@alternateTextColor, 12%);
79 | @floatButtonDisabledIconColor: fade(@textColor, 30%);
80 |
81 | @gridListTextColor: @white;
82 | @gridListTitlebarColor: rgba(0, 0, 0, 0.4);
83 |
84 | // circle
85 | @circleColor: @primaryColor;
86 | @circleSecondaryColor: @accentColor;
87 |
88 | @linearProgressColor: @lighterPrimaryColor;
89 | @linearProgressFillColor: @primaryColor;
90 |
91 | // listItem
92 | @listTextColor: @textColor;
93 | @listHoverColor: fade(@listTextColor, 10%);
94 | @listSecondaryTextColor: @secondaryTextColor;
95 | @listLeftIconColor: @grey600;
96 | @listRightIconColor: @grey600;
97 | @listSelectedColor: @primaryColor;
98 |
99 | @menuTextColor: @textColor;
100 | @menuSelectColor: @accentColor;
101 | @menuHoverColor: rgba(0, 0, 0, .1);
102 | @menuDisabledColor: @disabledColor;
103 | @menuLeftIconColor: @grey600;
104 | @menuRightIconColor: @grey600;
105 |
106 | @paginationTextColor: @textColor;
107 | @paginationHoverBackgroundColor: rgba(0, 0, 0, .1);
108 | @paginationActiveBackgroundColor: @primaryColor;
109 | @paginationActiveColor: @white;
110 | @paginationDisabledColor: @disabledColor;
111 |
112 | @paperColor: @textColor;
113 | @paperBackgroundColor: @dialogBackgroundColor;
114 |
115 | @pickerColor: @dialogBackgroundColor;
116 | @pickerTextColor: @secondaryTextColor;
117 | @pickerSelectedTextColor: @textColor;
118 | @pickerBorderColor: @borderColor;
119 |
120 | @popoverColor: @dialogBackgroundColor;
121 |
122 | @popupColor: @dialogBackgroundColor;
123 |
124 | @radioColor: @textColor;
125 | @radioTextColor: @textColor;
126 | @radioDisabledColor: @disabledColor;
127 | @radioCheckedColor: @primaryColor;
128 |
129 | // raisedButton
130 | @raisedButtonColor: @alternateTextColor;
131 | @raisedButtonTextColor: @textColor;
132 | @raisedButtonPrimaryColor: @primaryColor;
133 | @raisedButtonSecondaryColor: @accentColor;
134 | @raisedButtonDisabledColor: darken(@alternateTextColor, 10%);
135 | @raisedButtonDisabledTextColor: fade(@textColor, 30%);
136 |
137 | @refreshControlColor: @primaryColor;
138 |
139 | @sliderTrackColor: @lighterPrimaryColor;
140 | @sliderSelectionColor: @primaryColor;
141 | @sliderDisabledColor: @lighterPrimaryColor;
142 | @sliderZeroColor: @alternateTextColor;
143 |
144 | @snackbarColor: @textColor;
145 | @snackbarTextColor: @alternateTextColor;
146 |
147 | @stepperBackgroundColor: transparent;
148 | @stepperHoverBackgroundColor: fade(@textColor, 6%);
149 | @stepperIconColor: @primaryColor;
150 | @stepperHoveredIconColor: @grey700;
151 | @stepperInactiveIconColor: @grey500;
152 | @stepperTextColor: @textColor;
153 | @stepperNumTextColor: @alternateTextColor;
154 | @stepperDisabledTextColor: @disabledColor;
155 | @stepperConnectorLineColor: @grey400;
156 |
157 | // subHeader
158 | @subHeaderColor: @secondaryTextColor;
159 |
160 | @switchThumbOnColor: @primaryColor;
161 | @switchThumbOffColor: @darkerAccentColor;
162 | @switchThumbDisabledColor: @grey300;
163 | @switchTrackOnColor: fade(@primaryColor, 50%);
164 | @switchTrackOffColor: @lighterPrimaryColor;
165 | @switchTrackDisabledColor: @lighterPrimaryColor;
166 | @switchTextColor: @textColor;
167 | @switchTextDisabledColor: @disabledColor;
168 |
169 | @tableBackgroundColor: @alternateTextColor;
170 | @tableBorderColor: @borderColor;
171 | @tableTextColor: @textColor;
172 | @tableRowSelectedBackgroundColor: @grey100;
173 | @tableRowHoverBackgroundColor: @grey200;
174 | @tableRowStripeBackgroundColor: fade(lighten(@primaryColor, 50%), 40%);
175 | @tableTheadTextColor: @secondaryTextColor;
176 |
177 | @tabsBackgroundColor: @primaryColor;
178 | @tabsLineColor: @accentColor;
179 | @tabsTextColor: fade(@alternateTextColor, 70%);
180 | @tabsSelectedTextColor: @alternateTextColor;
181 |
182 | @textFieldTextColor: @secondaryTextColor;
183 | @textFieldInputColor: @textColor;
184 | @textFieldHintColor: @disabledColor;
185 | @textFieldFocusTextColor: @primaryColor;
186 | @textFieldDisabledTextColor: @disabledColor;
187 | @textFieldErrorTextColor: @red;
188 | @textFieldLineColor: @borderColor;
189 | @textFieldFocusLineColor: @primaryColor;
190 | @textFieldErrorLineColor: @red;
191 | @textFieldDisabledLineColor: @disabledColor;
192 |
193 | @timePickerColor: @alternateTextColor;
194 | @timePickerClockColor: @textColor;
195 | @timePickerClockCircleColor: fade(@darkBlack, 7%);
196 | @timePickerSelectColor: @primaryColor;
197 | @timePickerSelectTextColor: @alternateTextColor;
198 | @timePickerHeaderColor: @primaryColor;
199 |
200 | @toastTextColor: @alternateTextColor;
201 | @toastColor: @textColor;
202 |
203 | @tooltipTextColor: @alternateTextColor;
204 | @tooltipRippleColor: @grey700;
205 |
--------------------------------------------------------------------------------
/less/theme.less:
--------------------------------------------------------------------------------
1 | .mu-appbar{
2 | background-color: @appbarColor;
3 | color: @appbarTextColor;
4 | }
5 |
6 | .mu-avatar {
7 | color: @avatarColor;
8 | background-color: @avatarBackgroundColor;
9 | }
10 |
11 | .mu-badge {
12 | background-color: @badgeColor;
13 | color: @badgeTextColor;
14 | }
15 |
16 | .mu-badge-primary {
17 | background-color: @badgePrimaryColor;
18 | color: @badgePrimaryTextColor;
19 | }
20 |
21 | .mu-badge-secondary {
22 | background-color: @badgeSecondaryColor;
23 | color: @badgeSecondaryTextColor;
24 | }
25 |
26 | body {
27 | background-color: @baseBackgroundColor;
28 | color: @baseTextColor;
29 | font-family: @baseFontFamily;
30 | }
31 |
32 | a {
33 | color: @baseLinkColor;
34 | }
35 |
36 | .mu-bottom-nav {
37 | background-color: @bottomNavBackgroundColor;
38 | }
39 |
40 | .mu-bottom-nav-shift{
41 | background-color: @bottomNavShiftBackgroundColor;
42 | }
43 |
44 | .mu-buttom-item {
45 | color: @bottomNavUnselectedColor;
46 | .mu-bottom-nav-shift & {
47 | color: @bottomNavShiftUnselectedColor;
48 | }
49 | }
50 |
51 | .mu-bottom-item-active{
52 | .mu-bottom-item-text {
53 | color: @bottomNavSelectedColor;
54 | .mu-bottom-nav-shift & {
55 | color: @bottomNavShiftSelectedColor;
56 | }
57 | }
58 | .mu-bottom-item-icon {
59 | color: @bottomNavSelectedColor;
60 | .mu-bottom-nav-shift & {
61 | color: @bottomNavShiftSelectedColor;
62 | }
63 | }
64 | }
65 |
66 | .mu-bottom-sheet {
67 | background-color: @bottomSheetColor;
68 | }
69 |
70 | .mu-card {
71 | background-color: @cardBackgroudColor;
72 | }
73 |
74 | .mu-card-header-title{
75 | .mu-card-title{
76 | color: @cardTitleColor;
77 | }
78 | .mu-card-sub-title{
79 | color: @cardSubtitleColor;
80 | }
81 | }
82 |
83 |
84 | .mu-card-media-title {
85 | background-color: @cardMediaOverlayContentBackground;
86 | .mu-card-title {
87 | color: @cardMediaTitleColor;
88 | }
89 | .mu-card-sub-title {
90 | color: @cardMediaSubtitleColor;
91 | }
92 | }
93 |
94 | .mu-card-title-container{
95 | .mu-card-title{
96 | color: @cardTitleColor;
97 | }
98 | .mu-card-sub-title{
99 | color: @cardSubtitleColor;
100 | }
101 | }
102 |
103 | .mu-card-text{
104 | color: @cardTextColor;
105 | }
106 |
107 | .mu-checkbox {
108 | input[type="checkbox"] {
109 | &:checked {
110 | + .mu-checkbox-wrapper {
111 | .mu-checkbox-icon-uncheck{
112 | color: @checkboxCheckedColor;
113 | }
114 | .mu-checkbox-ripple-wrapper{
115 | color: @checkboxCheckedColor;
116 | }
117 | }
118 |
119 | }
120 | }
121 | }
122 |
123 | .mu-checkbox-label {
124 | color: @checkboxTextColor;
125 | .mu-checkbox.disabled & {
126 | color: @checkboxDisabledColor;
127 | }
128 | }
129 |
130 | .mu-checkbox-icon-uncheck {
131 | color: @checkboxColor;
132 | .mu-checkbox.disabled & {
133 | color: @checkboxDisabledColor;
134 | }
135 | }
136 |
137 | .mu-checkbox-icon-checked {
138 | color: @checkboxCheckedColor;
139 | .mu-checkbox.disabled & {
140 | color: @checkboxDisabledColor;
141 | }
142 | }
143 |
144 | .mu-chip {
145 | background-color: @chipColor;
146 | color: @chipTextColor;
147 | &.hover{
148 | .mu-chip-delete-icon{
149 | color: @chipHoverDeleteColor;
150 | }
151 | background-color: @chipHoverColor;
152 | cursor: pointer;
153 | }
154 | }
155 |
156 | .mu-chip-delete-icon{
157 | color: @chipDeleteColor;
158 | }
159 |
160 | .mu-circular-progress-determinate-path{
161 | stroke: @circularProgressColor;
162 | }
163 |
164 | .mu-calendar {
165 | color: @datePickerCalendarTextColor;
166 | }
167 |
168 | .mu-calendar-year {
169 | background-color: @datePickerCalendarYearBackgroundColor;
170 | }
171 |
172 |
173 | .mu-date-display{
174 | background-color: @datePickerHeaderColor;
175 | color: @datePickerTextColor;
176 | }
177 |
178 |
179 | .mu-day-button-bg {
180 | background-color: @datePickerSelectColor;
181 | }
182 |
183 | .mu-day-button-text{
184 | font-weight: 400;
185 | position: relative;
186 | color: @datePickerCalendarTextColor;
187 | .mu-day-button.now & {
188 | color: @datePickerSelectColor;
189 | }
190 | .mu-day-button.hover &,
191 | .mu-day-button.selected &{
192 | color: @datePickerSelectTextColor;
193 | }
194 | }
195 |
196 | .mu-year-button-text {
197 | color: @datePickerCalendarTextColor;
198 | .mu-year-button.selected &{
199 | color: @datePickerSelectColor;
200 | }
201 | .mu-year-button.hover &{
202 | color: @datePickerSelectColor;
203 | }
204 | }
205 |
206 | .mu-dialog {
207 | background-color: @dialogColor;
208 | }
209 |
210 | .mu-dialog-footer,
211 | .mu-dialog-header {
212 | &.scrollable{
213 | border-bottom-color: @dialogBorderColor;
214 | }
215 | }
216 |
217 | .mu-dialog-title{
218 | color: @dialogTitleColor;
219 | }
220 |
221 | .mu-dialog-body {
222 | color: @dialogBodyColor
223 | }
224 |
225 | .mu-dropDown-menu-text {
226 | color: @dropDownMenuTextColor;
227 | }
228 |
229 | .mu-dropDown-menu-icon {
230 | color: @dropDownMenuIconColor;
231 | }
232 |
233 | .mu-dropDown-menu-line {
234 | background-color: @dropDownMenuLineColor;
235 | }
236 |
237 | // flatbutton
238 | .mu-flat-button {
239 | color: @flatButtonTextColor;
240 | background-color: @flatButtonColor;
241 | .mu-circle-ripple {
242 | color: @flatButtonTextColor;
243 | }
244 | }
245 |
246 | .mu-flat-button-primary{
247 | color: @flatButtonPrimaryTextColor;
248 | }
249 |
250 | .mu-flat-button-secondary{
251 | color: @flatButtonSecondaryTextColor;
252 | }
253 |
254 | .mu-float-button {
255 | background-color: @floatButtonColor;
256 | color: @floatButtonIconColor;
257 | &.disabled{
258 | color: @floatButtonDisabledIconColor;
259 | cursor: default;
260 | background-color: @floatButtonDisabledColor;
261 | }
262 | &.hover,
263 | &:active{
264 | .mu-float-button-wrapper {
265 | background-color: fade(@floatButtonIconColor, 30%);
266 | }
267 | }
268 | }
269 |
270 | .mu-float-button-secondary {
271 | background-color: @floatButtonSecondaryColor;
272 | color: @floatButtonSecondaryIconColor;
273 | }
274 |
275 | .mu-grid-tile-titlebar{
276 | background-color: @gridListTitlebarColor;
277 | }
278 |
279 | .mu-grid-tile-title-container{
280 | color: @gridListTextColor;
281 | }
282 |
283 | .mu-grid-tile-action {
284 | .mu-icon {
285 | color: @gridListTextColor;
286 | }
287 | }
288 |
289 |
290 | // circle
291 | .mu-circle-spinner{
292 | border-color: @circleColor;
293 | }
294 |
295 | .mu-circle-secondary {
296 | border-color: @circleSecondaryColor;
297 | }
298 |
299 | .mu-linear-progress{
300 | background-color: @linearProgressColor;
301 | }
302 |
303 | .mu-linear-progress-indeterminate{
304 | background-color: @linearProgressFillColor;
305 | }
306 |
307 | .mu-linear-progress-determinate{
308 | background-color: @linearProgressFillColor;
309 | }
310 |
311 |
312 | // list
313 | .mu-item-wrapper{
314 | &.hover {
315 | background-color: @listHoverColor;
316 | }
317 | }
318 | .mu-item {
319 | color: @listTextColor;
320 | &.selected {
321 | color: @listSelectedColor;
322 | }
323 | }
324 |
325 | .mu-item-link-icon{
326 | color: @listRightIconColor;
327 | }
328 |
329 | .mu-item-left{
330 | color: @listLeftIconColor;
331 | }
332 |
333 | .mu-item-right{
334 | color: @listRightIconColor;
335 | }
336 |
337 | .mu-item-after{
338 | color: @listSecondaryTextColor;
339 | }
340 |
341 | .mu-item-text{
342 | color: @listSecondaryTextColor;
343 | }
344 |
345 | .mu-menu-item-wrapper{
346 | color: @menuTextColor;
347 | &.active {
348 | color: @menuSelectColor;
349 | }
350 | &.hover {
351 | background-color: @menuHoverColor;
352 | }
353 | &.disabled {
354 | color: @menuDisabledColor;
355 | }
356 | }
357 |
358 | .mu-menu-item-left-icon{
359 | color: @menuLeftIconColor;
360 | }
361 |
362 | .mu-menu-item-right-icon {
363 | color: @menuRightIconColor;
364 | }
365 |
366 | .mu-pagination-item{
367 | color: @paginationTextColor;
368 | &.hover {
369 | background-color: @paginationHoverBackgroundColor;
370 | }
371 | &.active {
372 | color: @paginationActiveColor;
373 | background-color: @paginationActiveBackgroundColor;
374 | }
375 | &.disabled {
376 | color: @paginationDisabledColor;
377 | }
378 | }
379 |
380 | .mu-paper {
381 | background-color: @paperBackgroundColor;
382 | color: @paperColor;
383 | }
384 |
385 | .mu-picker{
386 | background-color: @pickerColor;
387 | }
388 |
389 | .mu-picker-center-highlight {
390 | &::before,
391 | &::after {
392 | background-color: @pickerBorderColor;
393 | }
394 | }
395 |
396 |
397 | .mu-picker-slot.mu-picker-slot-divider {
398 | color: @pickerSelectedTextColor;
399 | }
400 |
401 | .mu-picker-item{
402 | color: @pickerTextColor;
403 | &.selected {
404 | color: @pickerSelectedTextColor;
405 | }
406 | }
407 |
408 | .mu-popover {
409 | background-color: @popoverColor;
410 | }
411 |
412 | .mu-popup {
413 | background-color: @popupColor;
414 | }
415 |
416 | .mu-radio {
417 | input[type="radio"] {
418 | &:checked {
419 | + .mu-radio-wrapper {
420 | .mu-radio-icon-uncheck{
421 | color: @radioCheckedColor;
422 | }
423 | .mu-radio-ripple-wrapper{
424 | color: @radioCheckedColor;
425 | }
426 | }
427 |
428 | }
429 | }
430 | }
431 |
432 | .mu-radio-label {
433 | color: @radioTextColor;
434 | .mu-radio.disabled & {
435 | color: @radioDisabledColor;
436 | }
437 | }
438 |
439 | .mu-radio-icon-uncheck {
440 | color: @radioColor;
441 | .mu-radio.disabled & {
442 | color: @radioDisabledColor;
443 | }
444 | }
445 |
446 | .mu-radio-icon-checked {
447 | color: @radioCheckedColor;
448 | .mu-radio.disabled & {
449 | color: @radioDisabledColor;
450 | }
451 | }
452 |
453 |
454 |
455 | // raisedButton
456 | .mu-raised-button{
457 | background-color: @raisedButtonColor;
458 | color: @raisedButtonTextColor;
459 | &.hover {
460 | .mu-raised-button-wrapper {
461 | background-color: fade(@raisedButtonTextColor, 10%);
462 | }
463 | }
464 | &.disabled{
465 | color: @raisedButtonDisabledTextColor;
466 | background-color: @raisedButtonDisabledColor;
467 | }
468 | }
469 |
470 | .mu-raised-button-primary{
471 | background-color: @raisedButtonPrimaryColor;
472 | }
473 |
474 | .mu-raised-button-secondary{
475 | background-color: @raisedButtonSecondaryColor;
476 | }
477 |
478 | .mu-refresh-control {
479 | color: @refreshControlColor;
480 | }
481 |
482 | .mu-slider-track {
483 | background-color: @sliderTrackColor;
484 | }
485 |
486 |
487 | .mu-slider-fill{
488 | background-color: @sliderSelectionColor;
489 | &.disabled {
490 | background-color: @sliderDisabledColor;
491 | }
492 | }
493 |
494 | .mu-slider-thumb{
495 | background-color: @sliderSelectionColor;
496 | color: @sliderSelectionColor;
497 | .mu-slider.zero &,
498 | .mu-slider.disabled &{
499 | border-color: @sliderDisabledColor;
500 | color: @sliderDisabledColor;
501 | background-color: @sliderZeroColor;
502 | }
503 | }
504 |
505 | .mu-snackbar {
506 | color: @snackbarTextColor;
507 | background-color: @snackbarColor;
508 | }
509 |
510 | .mu-step-button {
511 | background-color: @stepperBackgroundColor;
512 | &.hover {
513 | background-color: @stepperHoverBackgroundColor
514 | }
515 | }
516 |
517 | .mu-step-connector-line {
518 | border-color: @stepperConnectorLineColor;
519 | }
520 |
521 | .mu-step-content{
522 | .mu-stepper-vertical & {
523 | border-left: 1px solid @stepperConnectorLineColor;
524 | }
525 | }
526 |
527 |
528 | .mu-step-label{
529 | color: @stepperTextColor;
530 | &.disabled {
531 | color: @stepperDisabledTextColor;
532 | }
533 | }
534 |
535 |
536 | .mu-step-label-icon {
537 | color: @stepperInactiveIconColor;
538 | .mu-step-label.disabled &{
539 | color: @stepperInactiveIconColor;
540 | }
541 | .mu-step-label.completed &,
542 | .mu-step-label.active & {
543 | color: @stepperIconColor;
544 | }
545 | }
546 |
547 | .mu-step-label-circle{
548 | background-color: @stepperInactiveIconColor;
549 | color: @stepperNumTextColor;
550 | .mu-step-label.disabled &{
551 | background-color: @stepperInactiveIconColor;
552 | }
553 | .mu-step-label.completed &,
554 | .mu-step-label.active & {
555 | background-color: @stepperIconColor;
556 | }
557 | }
558 |
559 | // subheader
560 | .mu-sub-header{
561 | color: @subHeaderColor;
562 | }
563 |
564 | .mu-switch {
565 | input[type="checkbox"] {
566 | &:checked {
567 | + .mu-switch-wrapper {
568 | .mu-switch-track{
569 | background-color: @switchTrackOnColor;
570 | }
571 | .mu-switch-thumb{
572 | background-color: @switchThumbOnColor;
573 | color: @switchThumbOnColor;
574 | }
575 | }
576 |
577 | }
578 | }
579 | &.disabled {
580 | input[type="checkbox"]:checked{
581 | + .mu-switch-wrapper {
582 | .mu-switch-track{
583 | background-color: @switchTrackDisabledColor;
584 | }
585 | .mu-switch-thumb{
586 | background-color: @switchThumbDisabledColor;
587 | }
588 | }
589 | }
590 | }
591 | }
592 |
593 |
594 | .mu-switch-label {
595 | color: @switchTextColor;
596 | .mu-switch.disabled & {
597 | color: @switchTextDisabledColor;
598 | }
599 | }
600 |
601 | .mu-switch-track {
602 | background-color: @switchTrackOffColor;
603 | .mu-switch.disabled & {
604 | background-color: @switchTrackDisabledColor;
605 | }
606 | }
607 |
608 | .mu-switch-thumb {
609 | color: @switchTextColor;
610 | background-color: @switchThumbOffColor;
611 | .mu-switch.disabled & {
612 | background-color: @switchThumbDisabledColor;
613 | }
614 | }
615 |
616 | .mu-table {
617 | background-color: @tableBackgroundColor;
618 | }
619 |
620 | .mu-thead {
621 | border-bottom-color: @tableBorderColor;
622 | }
623 |
624 | .mu-th {
625 | color: @tableTheadTextColor;
626 | }
627 |
628 | .mu-tr {
629 | border-bottom-color: @tableBorderColor;
630 | color: @tableTextColor;
631 | &.selected {
632 | background-color: @tableRowSelectedBackgroundColor;
633 | }
634 | &.hover {
635 | background-color: @tableRowHoverBackgroundColor;
636 | }
637 | &.stripe {
638 | background-color: @tableRowStripeBackgroundColor;
639 | }
640 |
641 | .mu-tfoot & {
642 | border-top-color: @tableBorderColor;
643 | }
644 | }
645 |
646 | .mu-tabs{
647 | background-color: @tabsBackgroundColor;
648 | }
649 | .mu-tab-link-highlight {
650 | background-color: @tabsLineColor;
651 | }
652 | .mu-tab-link{
653 | color: @tabsTextColor;
654 | }
655 | .mu-tab-active {
656 | color: @tabsSelectedTextColor;
657 | }
658 |
659 | .mu-text-field{
660 | color: @textFieldTextColor;
661 | &.focus-state {
662 | color: @textFieldFocusTextColor;
663 | &.error{
664 | color: @textFieldErrorTextColor;
665 | }
666 | }
667 | &.disabled {
668 | color: @textFieldDisabledTextColor;
669 | }
670 | }
671 |
672 | .mu-text-field-input {
673 | color: @textFieldInputColor;
674 | }
675 |
676 |
677 | .mu-text-field-help {
678 | .mu-text-field.error &{
679 | color: @textFieldErrorTextColor;
680 | }
681 | }
682 |
683 | .mu-text-field-line {
684 | background-color: @textFieldLineColor;
685 | &.disabled {
686 | border-color: @textFieldDisabledLineColor;
687 | }
688 | }
689 |
690 | .mu-text-field-focus-line{
691 | background-color: @textFieldFocusLineColor;
692 | &.error {
693 | background-color: @textFieldErrorLineColor;
694 | }
695 | }
696 |
697 |
698 | .mu-text-field-hint {
699 | color: @textFieldHintColor;
700 | }
701 | .mu-text-field-label {
702 | .mu-text-field.has-label &.float {
703 | color: @textFieldHintColor
704 | }
705 | }
706 |
707 | .mu-clock-circle {
708 | background-color: @timePickerClockCircleColor;
709 | }
710 |
711 | .mu-time-display {
712 | background-color: @timePickerHeaderColor;
713 | color: @timePickerColor;
714 | }
715 |
716 | .mu-clock-number{
717 | &.selected {
718 | background-color: @timePickerSelectColor;
719 | color: @timePickerSelectTextColor;
720 | }
721 | }
722 |
723 | .mu-clock-pointer {
724 | background-color: @timePickerSelectColor;
725 |
726 | }
727 |
728 | .mu-clock-pointer-mark {
729 | background-color: @timePickerSelectTextColor;
730 | border-color: @timePickerSelectColor;
731 | }
732 |
733 | .mu-toast {
734 | background-color: @toastColor;
735 | color: @toastTextColor;
736 | }
737 |
738 | .mu-tooltip{
739 | color: @tooltipTextColor;
740 | }
741 |
742 | .mu-tooltip-ripple.when-shown {
743 | background-color: @tooltipRippleColor;
744 | }
745 |
--------------------------------------------------------------------------------
/less/vars.less:
--------------------------------------------------------------------------------
1 | @import "./colors.less";
2 | @fontFamily: Roboto, Lato, sans-serif;
3 |
4 | // primary and accent
5 | @primaryColor: @lightBlue; // 主色
6 | @darkerPrimaryColor: @lightBlue700;
7 | @lighterPrimaryColor: @grey400;
8 | @accentColor: @pinkA200;
9 | @darkerAccentColor: @grey100;
10 | @lighterAccentColor: @grey500;
11 |
12 | // textColor or borderColor
13 | @textColor: @darkBlack;
14 | @secondaryTextColor: fade(@fullBlack, 54%);
15 | @alternateTextColor: @white;
16 | @borderColor: fade(@fullBlack, 12%);
17 | @disabledColor: fade(@fullBlack, 38%);
18 |
19 | // background
20 | @backgroundColor: @white;
21 | @statusBarBackgroundColor: @grey300;
22 | @appbarBackgroundColor: @grey100;
23 | @dialogBackgroundColor: @white; // dialogs or cards
24 |
25 | // icon color
26 | @activeIconColor: fade(@fullBlack, 54%);
27 | @inActiveIconColor: fade(@fullBlack, 38%);
28 |
29 | // spaceing
30 | @iconSize: 24px;
31 | @desktopGutter: 24px;
32 | @desktopGutterMore: 32px;
33 | @desktopGutterLess: 16px;
34 | @desktopGutterMini: 8px;
35 | @desktopKeylineIncrement: 64px;
36 | @desktopDropDownMenuItemHeight: 32px;
37 | @desktopDropDownMenuFontSize: 15px;
38 | @desktopDrawerMenuItemHeight: 48px;
39 | @desktopSubheaderHeight: 48px;
40 | @desktopToolbarHeight: 56px;
41 |
42 | // animate
43 | @easeOutFunction: cubic-bezier(0.23, 1, 0.32, 1);
44 | @easeInOutFunction: cubic-bezier(0.445, 0.05, 0.55, 0.95);
45 |
--------------------------------------------------------------------------------
/npm-debug.log.2541962448:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pluto1114/vue-music-qq/d95f93cfe0c4fbb7c42540dfffead952f8c1fa57/npm-debug.log.2541962448
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-music-qq",
3 | "version": "1.0.0",
4 | "description": "A Vue.js project",
5 | "author": "xiongmao1114@163.com ",
6 | "private": true,
7 | "scripts": {
8 | "dev": "node build/dev-server.js",
9 | "build": "node build/build.js"
10 | },
11 | "dependencies": {
12 | "base64-decode-utils": "0.0.2",
13 | "js-base64": "^2.1.9",
14 | "keycode": "^2.1.7",
15 | "muse-ui": "^2.0.0-rc.5",
16 | "text-encoding": "^0.6.4",
17 | "vue": "^2.1.7",
18 | "vue-resource": "^1.2.0",
19 | "vue-router": "^2.2.0",
20 | "vuex": "^2.1.1"
21 | },
22 | "devDependencies": {
23 | "autoprefixer": "^6.4.0",
24 | "babel-core": "^6.0.0",
25 | "babel-loader": "^6.0.0",
26 | "babel-plugin-transform-runtime": "^6.0.0",
27 | "babel-preset-es2015": "^6.0.0",
28 | "babel-preset-stage-2": "^6.0.0",
29 | "babel-register": "^6.0.0",
30 | "chalk": "^1.1.3",
31 | "connect-history-api-fallback": "^1.1.0",
32 | "css-loader": "^0.25.0",
33 | "eventsource-polyfill": "^0.9.6",
34 | "express": "^4.13.3",
35 | "extract-text-webpack-plugin": "^1.0.1",
36 | "fastclick": "^1.0.6",
37 | "file-loader": "^0.9.0",
38 | "friendly-errors-webpack-plugin": "^1.1.2",
39 | "function-bind": "^1.0.2",
40 | "html-webpack-plugin": "^2.8.1",
41 | "http-proxy-middleware": "^0.17.2",
42 | "json-loader": "^0.5.4",
43 | "semver": "^5.3.0",
44 | "opn": "^4.0.2",
45 | "ora": "^0.3.0",
46 | "shelljs": "^0.7.4",
47 | "lodash": "^4.15.0",
48 | "postcss-loader": "^1.1.1",
49 | "less": "^2.7.1",
50 | "less-loader": "^2.2.3",
51 | "url-loader": "^0.5.7",
52 | "vue-loader": "^10.0.0",
53 | "vue-style-loader": "^1.0.0",
54 | "vue-template-compiler": "^2.1.0",
55 | "webpack": "^1.13.2",
56 | "webpack-dev-middleware": "^1.8.3",
57 | "webpack-hot-middleware": "^2.12.2",
58 | "webpack-merge": "^0.14.1"
59 | },
60 | "engines": {
61 | "node": ">= 4.0.0",
62 | "npm": ">= 3.0.0"
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Home
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
94 |
95 |
148 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pluto1114/vue-music-qq/d95f93cfe0c4fbb7c42540dfffead952f8c1fa57/src/assets/logo.png
--------------------------------------------------------------------------------
/src/components/AppSide.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | History List
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/src/components/Controls.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{playing?'pause_circle_outline':'play_circle_outline'}}
5 |
6 |
7 |
8 | {{currentTimeStr}}
9 |
10 |
11 |
12 | {{totalTimeStr}}
13 |
14 |
15 |
16 |
17 |
18 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/src/components/Lyric.vue:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/src/components/SongList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{x.songname}}
5 |
6 |
7 |
8 |
9 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | // The Vue build version to load with the `import` command
2 | // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3 | import Vue from 'vue'
4 | import App from './App'
5 | import MuseUI from 'muse-ui'
6 | import 'muse-ui/dist/muse-ui.css'
7 |
8 | import FastClick from 'fastclick'
9 | import router from './router'
10 | import store from './store'
11 | import VueResource from 'vue-resource'
12 |
13 | Vue.use(VueResource)
14 | Vue.use(MuseUI)
15 |
16 |
17 | FastClick.attach(document.body)
18 | /* eslint-disable no-new */
19 |
20 | new Vue({
21 | el: '#app',
22 | template: '',
23 | components: { App },
24 | router,
25 | store
26 | })
27 |
--------------------------------------------------------------------------------
/src/router.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 |
4 | Vue.use(VueRouter)
5 | const router = new VueRouter({
6 | mode: 'hash',
7 | base: __dirname,
8 | routes: [
9 | //{ path: '/' },
10 | { path: '/index',component:require('./views/index')},
11 | { path: '/player/:albumid/:songid/:songmid', component: require('./views/player') },
12 | // { path: '/song/:id', component:require('./views/Song') },
13 | { path: '*', redirect: '/index' }
14 | ]
15 | })
16 |
17 | export default router
18 |
--------------------------------------------------------------------------------
/src/store/TencentMusicAPI.php:
--------------------------------------------------------------------------------
1 | _REFERER);
27 | curl_setopt($curl,CURLOPT_COOKIE,$this->_COOKIE);
28 | curl_setopt($curl,CURLOPT_USERAGENT,$this->_USERAGENT);
29 | curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
30 | $result=curl_exec($curl);
31 | curl_close($curl);
32 | return $result;
33 | }
34 | // main function
35 | public function search($s,$limit=30,$offset=0,$type=1){
36 | $url='http://c.y.qq.com/soso/fcgi-bin/search_cp?';
37 | $data=array(
38 | 'p'=>$offset+1,
39 | 'n'=>$limit,
40 | 'w'=>$s,
41 | 'aggr'=>1,
42 | 'lossless'=>1,
43 | 'cr'=>1,
44 | );
45 | return substr($this->curl($url.http_build_query($data)),9,-1);
46 | }
47 | public function artist($artist_mid){
48 | $url='http://c.y.qq.com/v8/fcg-bin/fcg_v8_singer_track_cp.fcg?';
49 | $data=array(
50 | 'singermid'=>$artist_mid,
51 | 'order'=>'listen',
52 | 'begin'=>0,
53 | 'num'=>30,
54 | );
55 | return substr($this->curl($url.http_build_query($data)),0,-1);
56 | }
57 | public function album($album_mid){
58 | $url='http://c.y.qq.com/v8/fcg-bin/fcg_v8_album_info_cp.fcg?';
59 | $data=array(
60 | 'albummid'=>$album_mid,
61 | );
62 | return substr($this->curl($url.http_build_query($data)),1);
63 | }
64 | public function detail($song_mid){
65 | $url='http://c.y.qq.com/v8/fcg-bin/fcg_play_single_song.fcg?';
66 | $data=array(
67 | 'songmid'=>$song_mid,
68 | 'format'=>'json',
69 | );
70 | return $this->curl($url.http_build_query($data));
71 | }
72 | private function genkey(){
73 | $this->_GUID=rand(1,2147483647)*(microtime())%10000000000;
74 | $data=$this->curl('https://c.y.qq.com/base/fcgi-bin/fcg_musicexpress.fcg?json=3&guid='.$this->_GUID);
75 | $this->_KEY=json_decode(substr($data,13,-2),1)['key'];
76 | //$this->_CDN=json_decode(substr($data,13,-2),1)['sip'][0];
77 | $this->_CDN='http://dl.stream.qqmusic.qq.com/';
78 | }
79 | public function url($song_mid){
80 | self::genkey();
81 |
82 | $url='http://c.y.qq.com/v8/fcg-bin/fcg_play_single_song.fcg?';
83 | $data=array(
84 | 'songmid'=>$song_mid,
85 | 'format'=>'json',
86 | );
87 | $data=$this->curl($url.http_build_query($data));
88 | $data=json_decode($data,1)['data'][0]['file'];
89 | $type=array(
90 | 'size_320mp3'=>array('M800','mp3'),
91 | 'size_128mp3'=>array('M500','mp3'),
92 | 'size_96aac'=>array('C400','m4a'),
93 | 'size_48aac'=>array('C200','m4a'),
94 | );
95 | $url=array();
96 | foreach($type as $key=>$vo){
97 | if($data[$key])$url[substr($key,5)]=$this->_CDN.$vo[0].$data['media_mid'].'.'.$vo[1].
98 | '?vkey='.$this->_KEY.'&guid='.$this->_GUID.'&fromtag=30';
99 | }
100 | return json_encode($url);
101 | }
102 | public function playlist($playlist_id){
103 | $url='http://c.y.qq.com/qzone/fcg-bin/fcg_ucc_getcdinfo_byids_cp.fcg?';
104 | $data=array(
105 | 'disstid'=>$playlist_id,
106 | 'utf8'=>1,
107 | 'type'=>1,
108 | );
109 | return substr($this->curl($url.http_build_query($data)),13,-1);
110 | }
111 | public function lyric($song_mid){
112 | $url='http://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric.fcg?';
113 | $data=array(
114 | 'songmid'=>$song_mid,
115 | 'nobase64'=>'1',
116 | );
117 | return substr($this->curl($url.http_build_query($data)),18,-1);
118 | }
119 | }
120 |
121 | $api = new TencentMusicAPI();
122 |
123 | # Get data
124 | // $result = $api->search('hello');
125 | // $result = $api->artist('003CoxJh1zFPpx');
126 | // $result = $api->detail('001icUif3vTGcO');
127 | // $result = $api->album('002rBshp4WPAut');
128 | // $result = $api->playlist('801491460');
129 | // $result = $api->url('001icUif3vTGcO');
130 | $result = $api->lyric('001icUif3vTGcO');
131 |
132 | # return JSON, just use it
133 | var_dump(json_decode($result));
134 |
--------------------------------------------------------------------------------
/src/store/api.js:
--------------------------------------------------------------------------------
1 |
2 | import Vue from 'vue'
3 | import VueResource from 'vue-resource'
4 | var querystring = require('querystring');
5 |
6 | Vue.use(VueResource)
7 |
8 | //Vue.http.options.emulateJSON = true;
9 | var qqAPI={
10 |
11 |
12 | album: {
13 | url: 'https://c.y.qq.com/v8/fcg-bin/fcg_v8_album_info_cp.fcg',
14 | params: (id) => {
15 | return {
16 | albummid: id,
17 | g_tk: 5381,
18 | loginUin: 0,
19 | hostUin: 0,
20 | format: 'jsonp',
21 | inCharset: 'utf8',
22 | outCharset: 'utf-8',
23 | notice: 0,
24 | platform: 'yqq',
25 | needNewCode: 0
26 | }
27 | },
28 |
29 | },
30 | song_info: {
31 | url: '/qq-m-api/v8/fcg-bin/fcg_play_single_song.fcg',
32 | params: (mid) => {
33 | return {
34 | 'songmid':mid,
35 | 'format':'json',
36 | }
37 | },
38 |
39 | },
40 | search: {
41 | url: 'http://c.y.qq.com/soso/fcgi-bin/search_cp?',
42 | params: (key) => {
43 | return {
44 | 'p':1,
45 | 'n':15,
46 | 'w':key,
47 | 'aggr':1,
48 | 'lossless':1,
49 | 'cr':1,
50 | }
51 | }
52 |
53 | },
54 | hotkey: {
55 | url: 'https://c.y.qq.com/splcloud/fcgi-bin/gethotkey.fcg',
56 | params: () => {
57 | return {
58 | g_tk: 5381,
59 | loginUin: 0,
60 | hostUin: 0,
61 | format: 'jsonp',
62 | jsonp: 'jsonpCallback',
63 | inCharset: 'utf8',
64 | outCharset: 'utf-8',
65 | notice: 0,
66 | platform: 'yqq',
67 | needNewCode: 0
68 | }
69 | },
70 |
71 | },
72 |
73 | lyric: {
74 | url: 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric.fcg',
75 | params: (id) => {
76 | return {
77 | nobase64:1,
78 | musicid:id,
79 | songtype:0
80 | }
81 | },
82 |
83 | },
84 |
85 |
86 |
87 | }
88 |
89 | export function search (word) {
90 | var p=Vue.http.jsonp(qqAPI.search.url,{params:qqAPI.search.params(word),jsonp: 'jsonpCallback'});
91 | console.log(qqAPI.search.url+querystring.stringify(qqAPI.search.params(word)))
92 | p.then(resp => {
93 | console.log(resp.data);
94 | }, resp => {
95 | console.log("request error");
96 | });
97 | return p;
98 | }
99 |
100 | export function fetchSongInfo (song_mid) {
101 | var p=Vue.http.get(qqAPI.song_info.url,{params:qqAPI.song_info.params(song_mid)});
102 | //var p=Vue.http.get("/qq-m-api/v8/fcg-bin/fcg_play_single_song.fcg?songmid=001Ud2bQ0u61uC&format=json");
103 | console.log(qqAPI.song_info.url+'?'+querystring.stringify(qqAPI.song_info.params(song_mid)))
104 | p.then(resp => {
105 | console.log(resp.data);
106 | }, resp => {
107 | console.log("request error");
108 | });
109 | return p;
110 | }
111 |
112 | export function fetchHotkey () {
113 | var p=Vue.http.jsonp(qqAPI.hotkey.url,qqAPI.hotkey.params());
114 | p.then(resp => {
115 | console.log(resp.data);
116 | }, resp => {
117 | console.log("request error");
118 | });
119 | return p;
120 | }
121 | export function fetchAlbum (albummid) {
122 | var p=Vue.http.jsonp(qqAPI.album.url,{params:qqAPI.album.params(albummid),jsonp: 'jsonpCallback',});
123 | p.then(resp => {
124 | console.log(resp.data);
125 | }, resp => {
126 | console.log("request error");
127 | });
128 | return p;
129 | }
130 |
131 | export function fetchLyric (songid) {
132 | var p=Vue.http.jsonp('https://api.darlin.me/music/lyric/'+songid+'/',{params:qqAPI.lyric.params(songid),jsonp:'callback'});
133 | p.then(resp => {
134 | console.log(resp);
135 | }, resp => {
136 | console.log(resp);
137 | console.log("request error");
138 | });
139 | return p;
140 | }
141 | export function fetchHitAll () {
142 | var p=Vue.http.jsonp(baseListUrl+'/musicbox/shop/v3/data/hit/hit_all.js');
143 | p.then(resp=>{
144 | console.log(resp.data);
145 | },resp=>{
146 | console.log("request error");
147 | });
148 | return p;
149 | }
150 |
151 | export function fetchHitNewSong () {
152 | var p=Vue.http.jsonp(baseListUrl+'/musicbox/shop/v3/data/hit/hit_newsong.js');
153 | p.then(resp=>{
154 | console.log(resp.data);
155 | },resp=>{
156 | console.log("request error");
157 | });
158 | return p;
159 | }
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import {fetchSongInfo,fetchAlbum,fetchLyric,search} from '../store/api'
4 | import _ from 'lodash'
5 | Vue.use(Vuex)
6 | const store = new Vuex.Store({
7 | state: {
8 | hisSongArr: localStorage.hisSongArr ? JSON.parse(localStorage.hisSongArr) : [],
9 | lyricArr: [],
10 | lrcTimeArr: [],
11 | playing:false,
12 | audio:new Audio(),
13 | currentTime:0,
14 | lrcCurIndex:0
15 | },
16 | getters: {
17 |
18 | },
19 | actions: {
20 | FETCH_SONG_LIST(context, word) {
21 | let p = search(word);
22 | return p;
23 | },
24 | FETCH_SONG_INFO(context, song_mid) {
25 | let p = fetchSongInfo(song_mid);
26 | console.log("p",p)
27 | return p;
28 | },
29 | FETCH_LYRIC(context, music_id) {
30 | let p = fetchLyric(music_id);
31 | return p;
32 | },
33 |
34 | },
35 | mutations: {
36 |
37 | addHisSong(state, payload) {
38 |
39 | state.hisSongArr.unshift(payload.song);
40 |
41 | if (state.hisSongArr.length > 10) {
42 | state.hisSongArr = state.hisSongArr.slice(0, 10);
43 | }
44 |
45 | localStorage.hisSongArr = JSON.stringify(state.hisSongArr);
46 | },
47 |
48 | loadLyric(state, payload) {
49 | state.lyricArr = payload.lyricArr;
50 | state.lrcTimeArr=_.map(state.lyricArr,'time');
51 | },
52 | play(state){
53 | state.playing=true;
54 | state.audio.play();
55 | },
56 | pause(state){
57 | state.playing=false;
58 | state.audio.pause();
59 | },
60 | changePlayPos(state,time){
61 | state.audio.currentTime=time;
62 | },
63 | changeCurrentTime(state,currentTime){
64 | state.currentTime=currentTime;
65 | state.lrcCurIndex=_.sortedIndex(state.lrcTimeArr, currentTime);
66 | for (var i = 0; i < state.lyricArr.length; i++) {
67 | state.lyricArr[i].selected = false;
68 | }
69 | if (state.lrcCurIndex > 0) {
70 | state.lyricArr[state.lrcCurIndex - 1].selected = true;
71 | }
72 |
73 | },
74 | }
75 |
76 | });
77 |
78 |
79 | export default store
80 |
--------------------------------------------------------------------------------
/src/styles/base.less:
--------------------------------------------------------------------------------
1 | @import "./normalize.css";
2 | @import "./vars.less";
3 | *,
4 | *:before,
5 | *:after {
6 | box-sizing: border-box;
7 | }
8 | html{
9 | font-size: 62.5%;
10 | }
11 |
12 | body{
13 | font-family: @fontFamily;
14 | line-height: 1.5;
15 | font-size: 14px;
16 | font-weight: 400;
17 | width: 100%;
18 | -webkit-tap-highlight-color:rgba(0, 0, 0, 0);
19 | background-color: @backgroundColor;
20 | color: @textColor;
21 | }
22 |
23 | body,html{
24 | overflow-x:hidden;
25 | overflow-y: auto;
26 | }
27 |
28 | pre{
29 | white-space: pre-wrap;
30 | word-break: break-all;
31 | margin: 0;
32 | }
33 |
34 | a{
35 | text-decoration: none;
36 | color: @accentColor;
37 | user-select: none;
38 | -webkit-user-select: none;
39 | }
40 |
--------------------------------------------------------------------------------
/src/styles/colors.less:
--------------------------------------------------------------------------------
1 | @red50: #ffebee;
2 | @red100: #ffcdd2;
3 | @red200: #ef9a9a;
4 | @red300: #e57373;
5 | @red400: #ef5350;
6 | @red500: #f44336;
7 | @red600: #e53935;
8 | @red700: #d32f2f;
9 | @red800: #c62828;
10 | @red900: #b71c1c;
11 | @redA100: #ff8a80;
12 | @redA200: #ff5252;
13 | @redA400: #ff1744;
14 | @redA700: #d50000;
15 | @red: @red500;
16 |
17 | @pink50: #fce4ec;
18 | @pink100: #f8bbd0;
19 | @pink200: #f48fb1;
20 | @pink300: #f06292;
21 | @pink400: #ec407a;
22 | @pink500: #e91e63;
23 | @pink600: #d81b60;
24 | @pink700: #c2185b;
25 | @pink800: #ad1457;
26 | @pink900: #880e4f;
27 | @pinkA100: #ff80ab;
28 | @pinkA200: #ff4081;
29 | @pinkA400: #f50057;
30 | @pinkA700: #c51162;
31 | @pink: @pink500;
32 |
33 | @purple50: #f3e5f5;
34 | @purple100: #e1bee7;
35 | @purple200: #ce93d8;
36 | @purple300: #ba68c8;
37 | @purple400: #ab47bc;
38 | @purple500: #9c27b0;
39 | @purple600: #8e24aa;
40 | @purple700: #7b1fa2;
41 | @purple800: #6a1b9a;
42 | @purple900: #4a148c;
43 | @purpleA100: #ea80fc;
44 | @purpleA200: #e040fb;
45 | @purpleA400: #d500f9;
46 | @purpleA700: #aa00ff;
47 | @purple: @purple500;
48 |
49 | @deepPurple50: #ede7f6;
50 | @deepPurple100: #d1c4e9;
51 | @deepPurple200: #b39ddb;
52 | @deepPurple300: #9575cd;
53 | @deepPurple400: #7e57c2;
54 | @deepPurple500: #673ab7;
55 | @deepPurple600: #5e35b1;
56 | @deepPurple700: #512da8;
57 | @deepPurple800: #4527a0;
58 | @deepPurple900: #311b92;
59 | @deepPurpleA100: #b388ff;
60 | @deepPurpleA200: #7c4dff;
61 | @deepPurpleA400: #651fff;
62 | @deepPurpleA700: #6200ea;
63 | @deepPurple: @deepPurple500;
64 |
65 | @indigo50: #e8eaf6;
66 | @indigo100: #c5cae9;
67 | @indigo200: #9fa8da;
68 | @indigo300: #7986cb;
69 | @indigo400: #5c6bc0;
70 | @indigo500: #3f51b5;
71 | @indigo600: #3949ab;
72 | @indigo700: #303f9f;
73 | @indigo800: #283593;
74 | @indigo900: #1a237e;
75 | @indigoA100: #8c9eff;
76 | @indigoA200: #536dfe;
77 | @indigoA400: #3d5afe;
78 | @indigoA700: #304ffe;
79 | @indigo: @indigo500;
80 |
81 | @blue50: #e3f2fd;
82 | @blue100: #bbdefb;
83 | @blue200: #90caf9;
84 | @blue300: #64b5f6;
85 | @blue400: #42a5f5;
86 | @blue500: #2196f3;
87 | @blue600: #1e88e5;
88 | @blue700: #1976d2;
89 | @blue800: #1565c0;
90 | @blue900: #0d47a1;
91 | @blueA100: #82b1ff;
92 | @blueA200: #448aff;
93 | @blueA400: #2979ff;
94 | @blueA700: #2962ff;
95 | @blue: @blue500;
96 |
97 | @lightBlue50: #e1f5fe;
98 | @lightBlue100: #b3e5fc;
99 | @lightBlue200: #81d4fa;
100 | @lightBlue300: #4fc3f7;
101 | @lightBlue400: #29b6f6;
102 | @lightBlue500: #03a9f4;
103 | @lightBlue600: #039be5;
104 | @lightBlue700: #0288d1;
105 | @lightBlue800: #0277bd;
106 | @lightBlue900: #01579b;
107 | @lightBlueA100: #80d8ff;
108 | @lightBlueA200: #40c4ff;
109 | @lightBlueA400: #00b0ff;
110 | @lightBlueA700: #0091ea;
111 | @lightBlue: @lightBlue500;
112 |
113 | @cyan50: #e0f7fa;
114 | @cyan100: #b2ebf2;
115 | @cyan200: #80deea;
116 | @cyan300: #4dd0e1;
117 | @cyan400: #26c6da;
118 | @cyan500: #00bcd4;
119 | @cyan600: #00acc1;
120 | @cyan700: #0097a7;
121 | @cyan800: #00838f;
122 | @cyan900: #006064;
123 | @cyanA100: #84ffff;
124 | @cyanA200: #18ffff;
125 | @cyanA400: #00e5ff;
126 | @cyanA700: #00b8d4;
127 | @cyan: @cyan500;
128 |
129 | @teal50: #e0f2f1;
130 | @teal100: #b2dfdb;
131 | @teal200: #80cbc4;
132 | @teal300: #4db6ac;
133 | @teal400: #26a69a;
134 | @teal500: #009688;
135 | @teal600: #00897b;
136 | @teal700: #00796b;
137 | @teal800: #00695c;
138 | @teal900: #004d40;
139 | @tealA100: #a7ffeb;
140 | @tealA200: #64ffda;
141 | @tealA400: #1de9b6;
142 | @tealA700: #00bfa5;
143 | @teal: @teal500;
144 |
145 | @green50: #e8f5e9;
146 | @green100: #c8e6c9;
147 | @green200: #a5d6a7;
148 | @green300: #81c784;
149 | @green400: #66bb6a;
150 | @green500: #4caf50;
151 | @green600: #43a047;
152 | @green700: #388e3c;
153 | @green800: #2e7d32;
154 | @green900: #1b5e20;
155 | @greenA100: #b9f6ca;
156 | @greenA200: #69f0ae;
157 | @greenA400: #00e676;
158 | @greenA700: #00c853;
159 | @green: @green500;
160 |
161 | @lightGreen50: #f1f8e9;
162 | @lightGreen100: #dcedc8;
163 | @lightGreen200: #c5e1a5;
164 | @lightGreen300: #aed581;
165 | @lightGreen400: #9ccc65;
166 | @lightGreen500: #8bc34a;
167 | @lightGreen600: #7cb342;
168 | @lightGreen700: #689f38;
169 | @lightGreen800: #558b2f;
170 | @lightGreen900: #33691e;
171 | @lightGreenA100: #ccff90;
172 | @lightGreenA200: #b2ff59;
173 | @lightGreenA400: #76ff03;
174 | @lightGreenA700: #64dd17;
175 | @lightGreen: @lightGreen500;
176 |
177 | @lime50: #f9fbe7;
178 | @lime100: #f0f4c3;
179 | @lime200: #e6ee9c;
180 | @lime300: #dce775;
181 | @lime400: #d4e157;
182 | @lime500: #cddc39;
183 | @lime600: #c0ca33;
184 | @lime700: #afb42b;
185 | @lime800: #9e9d24;
186 | @lime900: #827717;
187 | @limeA100: #f4ff81;
188 | @limeA200: #eeff41;
189 | @limeA400: #c6ff00;
190 | @limeA700: #aeea00;
191 | @lime: @lime500;
192 |
193 | @yellow50: #fffde7;
194 | @yellow100: #fff9c4;
195 | @yellow200: #fff59d;
196 | @yellow300: #fff176;
197 | @yellow400: #ffee58;
198 | @yellow500: #ffeb3b;
199 | @yellow600: #fdd835;
200 | @yellow700: #fbc02d;
201 | @yellow800: #f9a825;
202 | @yellow900: #f57f17;
203 | @yellowA100: #ffff8d;
204 | @yellowA200: #ffff00;
205 | @yellowA400: #ffea00;
206 | @yellowA700: #ffd600;
207 | @yellow: @yellow500;
208 |
209 | @amber50: #fff8e1;
210 | @amber100: #ffecb3;
211 | @amber200: #ffe082;
212 | @amber300: #ffd54f;
213 | @amber400: #ffca28;
214 | @amber500: #ffc107;
215 | @amber600: #ffb300;
216 | @amber700: #ffa000;
217 | @amber800: #ff8f00;
218 | @amber900: #ff6f00;
219 | @amberA100: #ffe57f;
220 | @amberA200: #ffd740;
221 | @amberA400: #ffc400;
222 | @amberA700: #ffab00;
223 | @amber: @amber500;
224 |
225 | @orange50: #fff3e0;
226 | @orange100: #ffe0b2;
227 | @orange200: #ffcc80;
228 | @orange300: #ffb74d;
229 | @orange400: #ffa726;
230 | @orange500: #ff9800;
231 | @orange600: #fb8c00;
232 | @orange700: #f57c00;
233 | @orange800: #ef6c00;
234 | @orange900: #e65100;
235 | @orangeA100: #ffd180;
236 | @orangeA200: #ffab40;
237 | @orangeA400: #ff9100;
238 | @orangeA700: #ff6d00;
239 | @orange: @orange500;
240 |
241 | @deepOrange50: #fbe9e7;
242 | @deepOrange100: #ffccbc;
243 | @deepOrange200: #ffab91;
244 | @deepOrange300: #ff8a65;
245 | @deepOrange400: #ff7043;
246 | @deepOrange500: #ff5722;
247 | @deepOrange600: #f4511e;
248 | @deepOrange700: #e64a19;
249 | @deepOrange800: #d84315;
250 | @deepOrange900: #bf360c;
251 | @deepOrangeA100: #ff9e80;
252 | @deepOrangeA200: #ff6e40;
253 | @deepOrangeA400: #ff3d00;
254 | @deepOrangeA700: #dd2c00;
255 | @deepOrange: @deepOrange500;
256 |
257 | @brown50: #efebe9;
258 | @brown100: #d7ccc8;
259 | @brown200: #bcaaa4;
260 | @brown300: #a1887f;
261 | @brown400: #8d6e63;
262 | @brown500: #795548;
263 | @brown600: #6d4c41;
264 | @brown700: #5d4037;
265 | @brown800: #4e342e;
266 | @brown900: #3e2723;
267 | @brown: @brown500;
268 |
269 | @blueGrey50: #eceff1;
270 | @blueGrey100: #cfd8dc;
271 | @blueGrey200: #b0bec5;
272 | @blueGrey300: #90a4ae;
273 | @blueGrey400: #78909c;
274 | @blueGrey500: #607d8b;
275 | @blueGrey600: #546e7a;
276 | @blueGrey700: #455a64;
277 | @blueGrey800: #37474f;
278 | @blueGrey900: #263238;
279 | @blueGrey: @blueGrey500;
280 |
281 | @grey50: #fafafa;
282 | @grey100: #f5f5f5;
283 | @grey200: #eeeeee;
284 | @grey300: #e0e0e0;
285 | @grey400: #bdbdbd;
286 | @grey500: #9e9e9e;
287 | @grey600: #757575;
288 | @grey700: #616161;
289 | @grey800: #424242;
290 | @grey900: #212121;
291 | @grey: @grey500;
292 |
293 | @black: #000000;
294 | @white: #ffffff;
295 |
296 | @transparent: rgba(0, 0, 0, 0);
297 | @fullBlack: rgba(0, 0, 0, 1);
298 | @darkBlack: rgba(0, 0, 0, 0.87);
299 | @lightBlack: rgba(0, 0, 0, 0.54);
300 | @minBlack: rgba(0, 0, 0, 0.26);
301 | @faintBlack: rgba(0, 0, 0, 0.12);
302 | @fullWhite: rgba(255, 255, 255, 1);
303 | @darkWhite: rgba(255, 255, 255, 0.87);
304 | @lightWhite: rgba(255, 255, 255, 0.54);
305 |
--------------------------------------------------------------------------------
/src/styles/import.less:
--------------------------------------------------------------------------------
1 | @import "./vars.less";
2 | @import "./mixins.less";
3 |
--------------------------------------------------------------------------------
/src/styles/mixins.less:
--------------------------------------------------------------------------------
1 | .transition(@d) {
2 | -webkit-transition-duration: @d;
3 | transition-duration: @d;
4 | }
5 | .delay(@d) {
6 | -webkit-transition-delay: @d;
7 | transition-delay: @d;
8 | }
9 | .transform(@t) {
10 | -webkit-transform: @t;
11 | transform: @t;
12 | }
13 | .transform-origin(@to) {
14 | -webkit-transform-origin: @to;
15 | transform-origin: @to;
16 | }
17 | .translate3d(@x:0, @y:0, @z:0) {
18 | -webkit-transform: translate3d(@x,@y,@z);
19 | transform: translate3d(@x,@y,@z);
20 | }
21 | .animation (@a) {
22 | -webkit-animation: @a;
23 | animation: @a;
24 | }
25 | .scrollable() {
26 | overflow: auto;
27 | -webkit-overflow-scrolling: touch;
28 | }
29 | .flex-shrink(@fs) {
30 | -webkit-box-flex: @fs;
31 | -webkit-flex-shrink: @fs;
32 | -ms-flex: 0 @fs auto;
33 | flex-shrink: @fs;
34 | }
35 | .clearfix() {
36 | &:after,
37 | &:before {
38 | content: " ";
39 | display: table;
40 | }
41 | &:after {
42 | clear: both;
43 | }
44 | }
45 | .hairline(@position, @color) when (@position = top) {
46 | &:before {
47 | content: '';
48 | position: absolute;
49 | left: 0;
50 | top: 0;
51 | bottom: auto;
52 | right: auto;
53 | height: 1px;
54 | width: 100%;
55 | background-color: @color;
56 | display: block;
57 | z-index: 15;
58 | // .transform-origin(50% 0%);
59 | html.pixel-ratio-2 & {
60 | .transform(scaleY(0.5));
61 | }
62 | html.pixel-ratio-3 & {
63 | .transform(scaleY(0.33));
64 | }
65 | }
66 | }
67 | .hairline(@position, @color) when (@position = left) {
68 | &:before {
69 | content: '';
70 | position: absolute;
71 | left: 0;
72 | top: 0;
73 | bottom: auto;
74 | right: auto;
75 | width: 1px;
76 | height: 100%;
77 | background-color: @color;
78 | display: block;
79 | z-index: 15;
80 | // .transform-origin(0% 50%);
81 | html.pixel-ratio-2 & {
82 | .transform(scaleX(0.5));
83 | }
84 | html.pixel-ratio-3 & {
85 | .transform(scaleX(0.33));
86 | }
87 | }
88 |
89 | }
90 | .hairline(@position, @color) when (@position = bottom) {
91 | &:after {
92 | content: '';
93 | position: absolute;
94 | left: 0;
95 | bottom: 0;
96 | right: auto;
97 | top: auto;
98 | height: 1px;
99 | width: 100%;
100 | background-color: @color;
101 | display: block;
102 | z-index: 15;
103 | html.pixel-ratio-2 & {
104 | .transform(scaleY(0.5));
105 | }
106 | html.pixel-ratio-3 & {
107 | .transform(scaleY(0.33));
108 | }
109 | }
110 | }
111 | .hairline(@position, @color) when (@position = right) {
112 | &:after {
113 | content: '';
114 | position: absolute;
115 | right: 0;
116 | top: 0;
117 | left: auto;
118 | bottom: auto;
119 | width: 1px;
120 | height: 100%;
121 | background-color: @color;
122 | display: block;
123 | z-index: 15;
124 | // .transform-origin(100% 50%);
125 | html.pixel-ratio-2 & {
126 | .transform(scaleX(0.5));
127 | }
128 | html.pixel-ratio-3 & {
129 | .transform(scaleX(0.33));
130 | }
131 | }
132 | }
133 | // For right and bottom
134 | .hairline-remove(@position) when not (@position = left) and not (@position = top) {
135 | &:after {
136 | display: none;
137 | }
138 | }
139 | // For left and top
140 | .hairline-remove(@position) when not (@position = right) and not (@position = bottom) {
141 | &:before {
142 | display: none;
143 | }
144 | }
145 | // For right and bottom
146 | .hairline-color(@position, @color) when not (@position = left) and not (@position = top) {
147 | &:after {
148 | background-color: @color;
149 | }
150 | }
151 | // For left and top
152 | .hairline-color(@position, @color) when not (@position = right) and not (@position = bottom) {
153 | &:before {
154 | background-color: @color;
155 | }
156 | }
157 | // Encoded SVG Background
158 | .encoded-svg-background(@svg) {
159 | @url: `encodeURIComponent(@{svg})`;
160 | background-image: url("data:image/svg+xml;charset=utf-8,@{url}");
161 | }
162 | // Preserve3D
163 | .preserve3d() {
164 | -webkit-transform-style: preserve-3d;
165 | -moz-transform-style: preserve-3d;
166 | -ms-transform-style: preserve-3d;
167 | transform-style: preserve-3d;
168 | }
169 | // Shadow
170 | .depth(@level:1) {
171 | & when (@level = 1) {
172 | box-shadow: rgba(0, 0, 0, 0.117647) 0px 1px 6px, rgba(0, 0, 0, 0.117647) 0px 1px 4px;
173 | }
174 | & when (@level = 2) {
175 | box-shadow: rgba(0, 0, 0, 0.156863) 0px 3px 10px, rgba(0, 0, 0, 0.227451) 0px 3px 10px;
176 | }
177 | & when (@level = 3) {
178 | box-shadow: rgba(0, 0, 0, 0.188235) 0px 10px 30px, rgba(0, 0, 0, 0.227451) 0px 6px 10px;
179 | }
180 | & when (@level = 4) {
181 | box-shadow: rgba(0, 0, 0, 0.247059) 0px 14px 45px, rgba(0, 0, 0, 0.219608) 0px 10px 18px;
182 | }
183 | & when (@level = 5) {
184 | box-shadow: rgba(0, 0, 0, 0.298039) 0px 19px 60px, rgba(0, 0, 0, 0.219608) 0px 15px 20px;
185 | }
186 | }
187 | // Highlighted Links
188 | .active-highlight(@color:rgba(255, 255, 255, 0.15)){
189 | &:before {
190 | content: '';
191 | width: 100%;
192 | height: 100%;
193 | position: absolute;
194 | left: 0;
195 | top: 0;
196 | background-color: @color;
197 | background-repeat: no-repeat;
198 | background-position: center;
199 | background-size: 100% 100%;
200 | opacity: 0;
201 | pointer-events: none;
202 | .transition(600ms);
203 | }
204 | &.active-state:before,
205 | html:not(.watch-active-state) &:active:before {
206 | opacity: 1;
207 | .transition(150ms);
208 | }
209 | }
210 | .active-highlight-color(@color) {
211 | &:before {
212 | background-image: -webkit-radial-gradient(center, circle cover, @color 66%, rgba(red(@color),green(@color),blue(@color),0) 66%);
213 | background-image: radial-gradient(circle at center, @color 66%, rgba(red(@color),green(@color),blue(@color),0) 66%);
214 | }
215 | }
216 | // No Scrollbar
217 | .no-scrollbar() {
218 | &::-webkit-scrollbar {
219 | display: none !important;
220 | width: 0 !important;
221 | height: 0 !important;
222 | -webkit-appearance: none;
223 | opacity: 0 !important;
224 | }
225 | }
226 |
227 |
228 | .ellipsis() {
229 | white-space:nowrap;
230 | text-overflow:ellipsis;
231 | overflow:hidden;
232 | word-wrap: break-word;
233 | }
234 |
--------------------------------------------------------------------------------
/src/styles/normalize.css:
--------------------------------------------------------------------------------
1 | /*! normalize.css v4.1.1 | MIT License | github.com/necolas/normalize.css */
2 |
3 | /**
4 | * 1. Change the default font family in all browsers (opinionated).
5 | * 2. Prevent adjustments of font size after orientation changes in IE and iOS.
6 | */
7 |
8 | html {
9 | font-family: sans-serif; /* 1 */
10 | -ms-text-size-adjust: 100%; /* 2 */
11 | -webkit-text-size-adjust: 100%; /* 2 */
12 | }
13 |
14 | /**
15 | * Remove the margin in all browsers (opinionated).
16 | */
17 |
18 | body {
19 | margin: 0;
20 | }
21 |
22 | /* HTML5 display definitions
23 | ========================================================================== */
24 |
25 | /**
26 | * Add the correct display in IE 9-.
27 | * 1. Add the correct display in Edge, IE, and Firefox.
28 | * 2. Add the correct display in IE.
29 | */
30 |
31 | article,
32 | aside,
33 | details, /* 1 */
34 | figcaption,
35 | figure,
36 | footer,
37 | header,
38 | main, /* 2 */
39 | menu,
40 | nav,
41 | section,
42 | summary { /* 1 */
43 | display: block;
44 | }
45 |
46 | /**
47 | * Add the correct display in IE 9-.
48 | */
49 |
50 | audio,
51 | canvas,
52 | progress,
53 | video {
54 | display: inline-block;
55 | }
56 |
57 | /**
58 | * Add the correct display in iOS 4-7.
59 | */
60 |
61 | audio:not([controls]) {
62 | display: none;
63 | height: 0;
64 | }
65 |
66 | /**
67 | * Add the correct vertical alignment in Chrome, Firefox, and Opera.
68 | */
69 |
70 | progress {
71 | vertical-align: baseline;
72 | }
73 |
74 | /**
75 | * Add the correct display in IE 10-.
76 | * 1. Add the correct display in IE.
77 | */
78 |
79 | template, /* 1 */
80 | [hidden] {
81 | display: none;
82 | }
83 |
84 | /* Links
85 | ========================================================================== */
86 |
87 | /**
88 | * 1. Remove the gray background on active links in IE 10.
89 | * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
90 | */
91 |
92 | a {
93 | background-color: transparent; /* 1 */
94 | -webkit-text-decoration-skip: objects; /* 2 */
95 | }
96 |
97 | /**
98 | * Remove the outline on focused links when they are also active or hovered
99 | * in all browsers (opinionated).
100 | */
101 |
102 | a:active,
103 | a:hover {
104 | outline-width: 0;
105 | }
106 |
107 | /* Text-level semantics
108 | ========================================================================== */
109 |
110 | /**
111 | * 1. Remove the bottom border in Firefox 39-.
112 | * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
113 | */
114 |
115 | abbr[title] {
116 | border-bottom: none; /* 1 */
117 | text-decoration: underline; /* 2 */
118 | text-decoration: underline dotted; /* 2 */
119 | }
120 |
121 | /**
122 | * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
123 | */
124 |
125 | b,
126 | strong {
127 | font-weight: inherit;
128 | }
129 |
130 | /**
131 | * Add the correct font weight in Chrome, Edge, and Safari.
132 | */
133 |
134 | b,
135 | strong {
136 | font-weight: bolder;
137 | }
138 |
139 | /**
140 | * Add the correct font style in Android 4.3-.
141 | */
142 |
143 | dfn {
144 | font-style: italic;
145 | }
146 |
147 | /**
148 | * Correct the font size and margin on `h1` elements within `section` and
149 | * `article` contexts in Chrome, Firefox, and Safari.
150 | */
151 |
152 | h1 {
153 | font-size: 2em;
154 | margin: 0.67em 0;
155 | }
156 |
157 | /**
158 | * Add the correct background and color in IE 9-.
159 | */
160 |
161 | mark {
162 | background-color: #ff0;
163 | color: #000;
164 | }
165 |
166 | /**
167 | * Add the correct font size in all browsers.
168 | */
169 |
170 | small {
171 | font-size: 80%;
172 | }
173 |
174 | /**
175 | * Prevent `sub` and `sup` elements from affecting the line height in
176 | * all browsers.
177 | */
178 |
179 | sub,
180 | sup {
181 | font-size: 75%;
182 | line-height: 0;
183 | position: relative;
184 | vertical-align: baseline;
185 | }
186 |
187 | sub {
188 | bottom: -0.25em;
189 | }
190 |
191 | sup {
192 | top: -0.5em;
193 | }
194 |
195 | /* Embedded content
196 | ========================================================================== */
197 |
198 | /**
199 | * Remove the border on images inside links in IE 10-.
200 | */
201 |
202 | img {
203 | border-style: none;
204 | }
205 |
206 | /**
207 | * Hide the overflow in IE.
208 | */
209 |
210 | svg:not(:root) {
211 | overflow: hidden;
212 | }
213 |
214 | /* Grouping content
215 | ========================================================================== */
216 |
217 | /**
218 | * 1. Correct the inheritance and scaling of font size in all browsers.
219 | * 2. Correct the odd `em` font sizing in all browsers.
220 | */
221 |
222 | code,
223 | kbd,
224 | pre,
225 | samp {
226 | font-family: monospace, monospace; /* 1 */
227 | font-size: 1em; /* 2 */
228 | }
229 |
230 | /**
231 | * Add the correct margin in IE 8.
232 | */
233 |
234 | figure {
235 | margin: 1em 40px;
236 | }
237 |
238 | /**
239 | * 1. Add the correct box sizing in Firefox.
240 | * 2. Show the overflow in Edge and IE.
241 | */
242 |
243 | hr {
244 | box-sizing: content-box; /* 1 */
245 | height: 0; /* 1 */
246 | overflow: visible; /* 2 */
247 | }
248 |
249 | /* Forms
250 | ========================================================================== */
251 |
252 | /**
253 | * 1. Change font properties to `inherit` in all browsers (opinionated).
254 | * 2. Remove the margin in Firefox and Safari.
255 | */
256 |
257 | button,
258 | input,
259 | select,
260 | textarea {
261 | font: inherit; /* 1 */
262 | margin: 0; /* 2 */
263 | }
264 |
265 | /**
266 | * Restore the font weight unset by the previous rule.
267 | */
268 |
269 | optgroup {
270 | font-weight: bold;
271 | }
272 |
273 | /**
274 | * Show the overflow in IE.
275 | * 1. Show the overflow in Edge.
276 | */
277 |
278 | button,
279 | input { /* 1 */
280 | overflow: visible;
281 | }
282 |
283 | /**
284 | * Remove the inheritance of text transform in Edge, Firefox, and IE.
285 | * 1. Remove the inheritance of text transform in Firefox.
286 | */
287 |
288 | button,
289 | select { /* 1 */
290 | text-transform: none;
291 | }
292 |
293 | /**
294 | * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
295 | * controls in Android 4.
296 | * 2. Correct the inability to style clickable types in iOS and Safari.
297 | */
298 |
299 | button,
300 | html [type="button"], /* 1 */
301 | [type="reset"],
302 | [type="submit"] {
303 | -webkit-appearance: button; /* 2 */
304 | }
305 |
306 | /**
307 | * Remove the inner border and padding in Firefox.
308 | */
309 |
310 | button::-moz-focus-inner,
311 | [type="button"]::-moz-focus-inner,
312 | [type="reset"]::-moz-focus-inner,
313 | [type="submit"]::-moz-focus-inner {
314 | border-style: none;
315 | padding: 0;
316 | }
317 |
318 | /**
319 | * Restore the focus styles unset by the previous rule.
320 | */
321 |
322 | button:-moz-focusring,
323 | [type="button"]:-moz-focusring,
324 | [type="reset"]:-moz-focusring,
325 | [type="submit"]:-moz-focusring {
326 | outline: 1px dotted ButtonText;
327 | }
328 |
329 | /**
330 | * Change the border, margin, and padding in all browsers (opinionated).
331 | */
332 |
333 | fieldset {
334 | border: 1px solid #c0c0c0;
335 | margin: 0 2px;
336 | padding: 0.35em 0.625em 0.75em;
337 | }
338 |
339 | /**
340 | * 1. Correct the text wrapping in Edge and IE.
341 | * 2. Correct the color inheritance from `fieldset` elements in IE.
342 | * 3. Remove the padding so developers are not caught out when they zero out
343 | * `fieldset` elements in all browsers.
344 | */
345 |
346 | legend {
347 | box-sizing: border-box; /* 1 */
348 | color: inherit; /* 2 */
349 | display: table; /* 1 */
350 | max-width: 100%; /* 1 */
351 | padding: 0; /* 3 */
352 | white-space: normal; /* 1 */
353 | }
354 |
355 | /**
356 | * Remove the default vertical scrollbar in IE.
357 | */
358 |
359 | textarea {
360 | overflow: auto;
361 | }
362 |
363 | /**
364 | * 1. Add the correct box sizing in IE 10-.
365 | * 2. Remove the padding in IE 10-.
366 | */
367 |
368 | [type="checkbox"],
369 | [type="radio"] {
370 | box-sizing: border-box; /* 1 */
371 | padding: 0; /* 2 */
372 | }
373 |
374 | /**
375 | * Correct the cursor style of increment and decrement buttons in Chrome.
376 | */
377 |
378 | [type="number"]::-webkit-inner-spin-button,
379 | [type="number"]::-webkit-outer-spin-button {
380 | height: auto;
381 | }
382 |
383 | /**
384 | * 1. Correct the odd appearance in Chrome and Safari.
385 | * 2. Correct the outline style in Safari.
386 | */
387 |
388 | [type="search"] {
389 | -webkit-appearance: textfield; /* 1 */
390 | outline-offset: -2px; /* 2 */
391 | }
392 |
393 | /**
394 | * Remove the inner padding and cancel buttons in Chrome and Safari on OS X.
395 | */
396 |
397 | [type="search"]::-webkit-search-cancel-button,
398 | [type="search"]::-webkit-search-decoration {
399 | -webkit-appearance: none;
400 | }
401 |
402 | /**
403 | * Correct the text style of placeholders in Chrome, Edge, and Safari.
404 | */
405 |
406 | ::-webkit-input-placeholder {
407 | color: inherit;
408 | opacity: 0.54;
409 | }
410 |
411 | /**
412 | * 1. Correct the inability to style clickable types in iOS and Safari.
413 | * 2. Change font properties to `inherit` in Safari.
414 | */
415 |
416 | ::-webkit-file-upload-button {
417 | -webkit-appearance: button; /* 1 */
418 | font: inherit; /* 2 */
419 | }
420 |
--------------------------------------------------------------------------------
/src/styles/themes/carbon.less:
--------------------------------------------------------------------------------
1 | @import "../vars.less";
2 |
3 | @primaryColor: #474a4f;
4 | @darkerPrimaryColor: #7e848c;
5 | @lighterPrimaryColor: #bbbfc4;
6 | @accentColor: #ff5252;
7 |
8 | @textColor: #474a4f;
9 | @secondaryTextColor: #7e848c;
10 | @borderColor: #edeff2;
11 | @disabledColor: #d3d6db;
12 |
13 | @import "../../../less/theme-vars.less";
14 | // components vars
15 | @badgePrimaryColor: @darkerPrimaryColor;
16 | @checkboxCheckedColor: @accentColor;
17 | @checkboxColor: @secondaryTextColor;
18 | @datePickerSelectColor: @accentColor;
19 | @flatButtonPrimaryTextColor: @accentColor;
20 | @circleColor: @accentColor;
21 | @linearProgressFillColor: @accentColor;
22 | @radioColor: @darkerPrimaryColor;
23 | @radioCheckedColor: @accentColor;
24 | @raisedButtonPrimaryColor: @darkerPrimaryColor;
25 | @refreshControlColor: @accentColor;
26 | @sliderSelectionColor: @accentColor;
27 | @snackbarColor: @darkBlack;
28 | @stepperIconColor: @accentColor;
29 | @switchThumbOnColor: @accentColor;
30 | @switchTrackOnColor: fade(@accentColor, 50%);
31 | @textFieldFocusTextColor: @accentColor;
32 | @textFieldFocusLineColor: @accentColor;
33 | @timePickerSelectColor: @accentColor;
34 | @toastColor: @darkBlack;
35 | @import "../../../less/theme.less";
36 |
--------------------------------------------------------------------------------
/src/styles/themes/dark.less:
--------------------------------------------------------------------------------
1 | @import "../vars.less";
2 |
3 | @primaryColor: @lightBlue700;
4 | @darkerPrimaryColor: @lightBlue700;
5 | @lighterPrimaryColor: @grey600;
6 | @accentColor: @pinkA200;
7 | @darkerAccentColor: @pinkA400;
8 | @lighterAccentColor: @pinkA100;
9 |
10 | @textColor: @fullWhite;
11 | @secondaryTextColor: fade(@fullWhite, 70%);
12 | @alternateTextColor: #303030;
13 | @borderColor: fade(@fullWhite, 30%);
14 | @disabledColor: fade(@fullWhite, 30%);
15 |
16 | // background
17 | @backgroundColor: #303030;
18 | @statusBarBackgroundColor: @fullBlack;
19 | @appbarBackgroundColor: @grey900;
20 | @dialogBackgroundColor: #424242; // dialogs or cards
21 |
22 | // icon
23 | @activeIconColor: fade(@fullWhite, 100%);
24 | @inActiveIconColor: fade(@fullWhite, 50%);
25 |
26 | @import "../../../less/theme-vars.less";
27 | // components vars
28 | @avatarBackgroundColor: lighten(@alternateTextColor, 26%);
29 | @datePickerHeaderColor: fade(@fullWhite, 12%);
30 | @timePickerHeaderColor: fade(@fullWhite, 12%);
31 | @timePickerClockCircleColor: fade(@fullWhite, 12%);
32 | @avatarBackgroundColor: lighten(@alternateTextColor, 26%);
33 | @chipColor: lighten(@alternateTextColor, 12%);
34 | @floatButtonDisabledColor: lighten(@alternateTextColor, 12%);
35 |
36 | @tableRowHoverBackgroundColor: fade(@textColor, 10%);
37 | @tableRowSelectedBackgroundColor: fade(@textColor, 5%);
38 | @datePickerTextColor: @textColor;
39 | @timePickerColor: @textColor;
40 | @import "../../../less/theme.less";
41 |
--------------------------------------------------------------------------------
/src/styles/themes/default.less:
--------------------------------------------------------------------------------
1 | @import "../vars.less";
2 | @import "../../../less/theme-vars.less";
3 | @import "../../../less/theme.less";
4 |
--------------------------------------------------------------------------------
/src/styles/themes/teal.less:
--------------------------------------------------------------------------------
1 | @import "../vars.less";
2 |
3 | @primaryColor: @teal;
4 | @darkerPrimaryColor: @teal700;
5 |
6 | @import "../../../less/theme-vars.less";
7 | @import "../../../less/theme.less";
8 |
--------------------------------------------------------------------------------
/src/styles/vars.less:
--------------------------------------------------------------------------------
1 | @import "./colors.less";
2 | @fontFamily: Roboto, Lato, sans-serif;
3 |
4 | // primary and accent
5 | @primaryColor: @lightBlue; // 主色
6 | @darkerPrimaryColor: @lightBlue700;
7 | @lighterPrimaryColor: @grey400;
8 | @accentColor: @pinkA200;
9 | @darkerAccentColor: @grey100;
10 | @lighterAccentColor: @grey500;
11 |
12 | // textColor or borderColor
13 | @textColor: @darkBlack;
14 | @secondaryTextColor: fade(@fullBlack, 54%);
15 | @alternateTextColor: @white;
16 | @borderColor: fade(@fullBlack, 12%);
17 | @disabledColor: fade(@fullBlack, 38%);
18 |
19 | // background
20 | @backgroundColor: @white;
21 | @statusBarBackgroundColor: @grey300;
22 | @appbarBackgroundColor: @grey100;
23 | @dialogBackgroundColor: @white; // dialogs or cards
24 |
25 | // icon color
26 | @activeIconColor: fade(@fullBlack, 54%);
27 | @inActiveIconColor: fade(@fullBlack, 38%);
28 |
29 | // spaceing
30 | @iconSize: 24px;
31 | @desktopGutter: 24px;
32 | @desktopGutterMore: 32px;
33 | @desktopGutterLess: 16px;
34 | @desktopGutterMini: 8px;
35 | @desktopKeylineIncrement: 64px;
36 | @desktopDropDownMenuItemHeight: 32px;
37 | @desktopDropDownMenuFontSize: 15px;
38 | @desktopDrawerMenuItemHeight: 48px;
39 | @desktopSubheaderHeight: 48px;
40 | @desktopToolbarHeight: 56px;
41 |
42 | // animate
43 | @easeOutFunction: cubic-bezier(0.23, 1, 0.32, 1);
44 | @easeInOutFunction: cubic-bezier(0.445, 0.05, 0.55, 0.95);
45 |
--------------------------------------------------------------------------------
/src/styles/zIndex.less:
--------------------------------------------------------------------------------
1 | @menu: 1000;
2 | @appBar: 1100;
3 | @drawerOverlay: 1200;
4 | @drawer: 1300;
5 | @dialogOverlay: 1400;
6 | @dialog: 1500;
7 | @layer: 2000;
8 | @popover: 2100;
9 | @snackbar: 2900;
10 | @tooltip: 3000;
11 |
--------------------------------------------------------------------------------
/src/views/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | M
7 |
8 |
9 | QQ Music
10 |
11 |
12 | Embrace Vue , enjoy life
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/src/views/player.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
![]()
5 |
6 |
7 |
{{song.name}}
8 |
{{singer.name}}
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pluto1114/vue-music-qq/d95f93cfe0c4fbb7c42540dfffead952f8c1fa57/static/.gitkeep
--------------------------------------------------------------------------------
/static/hot_all.js:
--------------------------------------------------------------------------------
1 |
2 | var hot_all={
3 | retcode: "1",
4 | songlist: [{
5 | id: "1597410",
6 | type: 3,
7 | url: "http://stream1.qqmusic.qq.com:0/1597410.wma",
8 | songName: "江南style",
9 | singerId: "13143",
10 | singerName: "Psy",
11 | albumId: "128191",
12 | albumName: "PSY 6甲 Part.1",
13 | albumLink: "/musicbox/shop/v3/album/91/album_128191.htm",
14 | playtime: "219"
15 | },
16 | {
17 | id: "1539873",
18 | type: 3,
19 | url: "http://stream6.qqmusic.qq.com:0/1539873.wma",
20 | songName: "没有什么不同",
21 | singerId: "34703",
22 | singerName: "曲婉婷",
23 | albumId: "107526",
24 | albumName: "我的歌声里",
25 | albumLink: "/musicbox/shop/v3/album/26/album_107526.htm",
26 | playtime: "288"
27 | },
28 | {
29 | id: "1913719",
30 | type: 3,
31 | url: "http://stream3.qqmusic.qq.com:0/1913719.wma",
32 | songName: "想你的夜",
33 | singerId: "12770",
34 | singerName: "关喆",
35 | albumId: "139643",
36 | albumName: "身边的故事",
37 | albumLink: "/musicbox/shop/v3/album/43/album_139643.htm",
38 | playtime: "268"
39 | },
40 | {
41 | id: "1803555",
42 | type: 3,
43 | url: "http://stream10.qqmusic.qq.com:0/1803555.wma",
44 | songName: "怒放的生命",
45 | singerId: "4604",
46 | singerName: "汪峰",
47 | albumId: "140820",
48 | albumName: "北京青年 电视原声带",
49 | albumLink: "/musicbox/shop/v3/album/20/album_140820.htm",
50 | playtime: "275"
51 | },
52 | {
53 | id: "1773989",
54 | type: 3,
55 | url: "http://stream3.qqmusic.qq.com:0/1773989.wma",
56 | songName: "如果分开我也爱你",
57 | singerId: "12770",
58 | singerName: "关喆",
59 | albumId: "139643",
60 | albumName: "身边的故事",
61 | albumLink: "/musicbox/shop/v3/album/43/album_139643.htm",
62 | playtime: "289"
63 | },
64 | {
65 | id: "1641090",
66 | type: 3,
67 | url: "http://stream9.qqmusic.qq.com:0/1641090.wma",
68 | songName: "你并不懂我",
69 | singerId: "13578",
70 | singerName: "BY2",
71 | albumId: "123849",
72 | albumName: "2020爱你爱你",
73 | albumLink: "/musicbox/shop/v3/album/49/album_123849.htm",
74 | playtime: "235"
75 | },
76 | {
77 | id: "1531817",
78 | type: 3,
79 | url: "http://stream9.qqmusic.qq.com:0/1531817.wma",
80 | songName: "幻听",
81 | singerId: "7221",
82 | singerName: "许嵩",
83 | albumId: "119459",
84 | albumName: "梦游计",
85 | albumLink: "/musicbox/shop/v3/album/59/album_119459.htm",
86 | playtime: "273"
87 | },
88 | {
89 | id: "1439470",
90 | type: 3,
91 | url: "http://stream8.qqmusic.qq.com:0/1439470.wma",
92 | songName: "一吻天荒",
93 | singerId: "4357",
94 | singerName: "胡歌",
95 | albumId: "115748",
96 | albumName: "轩辕剑之天之痕",
97 | albumLink: "/musicbox/shop/v3/album/48/album_115748.htm",
98 | playtime: "250"
99 | },
100 | {
101 | id: "1913708",
102 | type: 3,
103 | url: "http://stream2.qqmusic.qq.com:0/1913708.wma",
104 | songName: "淋雨一直走",
105 | singerId: "224",
106 | singerName: "张韶涵",
107 | albumId: "130382",
108 | albumName: "有形的翅膀",
109 | albumLink: "/musicbox/shop/v3/album/82/album_130382.htm",
110 | playtime: "205"
111 | },
112 | {
113 | id: "1067125",
114 | type: 3,
115 | url: "http://stream2.qqmusic.qq.com:0/1067125.wma",
116 | songName: "父亲",
117 | singerId: "11761",
118 | singerName: "筷子兄弟",
119 | albumId: "90932",
120 | albumName: "父亲",
121 | albumLink: "/musicbox/shop/v3/album/32/album_90932.htm",
122 | playtime: "301"
123 | },
124 | {
125 | id: "1078214",
126 | type: 3,
127 | url: "http://stream5.qqmusic.qq.com:0/1078214.wma",
128 | songName: "后会无期",
129 | singerId: "22704",
130 | singerName: "徐良",
131 | albumId: "91325",
132 | albumName: "不良少年",
133 | albumLink: "/musicbox/shop/v3/album/25/album_91325.htm",
134 | playtime: "211"
135 | },
136 | {
137 | id: "1908164",
138 | type: 3,
139 | url: "http://stream3.qqmusic.qq.com:0/1908164.wma",
140 | songName: "爱输给了谁",
141 | singerId: "15809",
142 | singerName: "黄勇",
143 | albumId: "143913",
144 | albumName: "2012年09月新歌速递",
145 | albumLink: "/musicbox/shop/v3/album/13/album_143913.htm",
146 | playtime: "209"
147 | },
148 | {
149 | id: "804997",
150 | type: 3,
151 | url: "http://stream4.qqmusic.qq.com:0/804997.wma",
152 | songName: "因为爱情",
153 | singerId: "143",
154 | singerName: "陈奕迅 王菲",
155 | albumId: "68074",
156 | albumName: "Stranger Under My Skin",
157 | albumLink: "/musicbox/shop/v3/album/74/album_68074.htm",
158 | playtime: "217"
159 | },
160 | {
161 | id: "140677",
162 | type: 3,
163 | url: "http://stream3.qqmusic.qq.com:0/140677.wma",
164 | songName: "爱要坦荡荡",
165 | singerId: "5117",
166 | singerName: "萧萧",
167 | albumId: "12416",
168 | albumName: "Beautiful Angel",
169 | albumLink: "/musicbox/shop/v3/album/16/album_12416.htm",
170 | playtime: "238"
171 | },
172 | {
173 | id: "1756991",
174 | type: 3,
175 | url: "http://stream2.qqmusic.qq.com:0/1756991.wma",
176 | songName: "爱,有你才完整",
177 | singerId: "11453",
178 | singerName: "魏晨",
179 | albumId: "138767",
180 | albumName: "童话二分之一 电视原声带",
181 | albumLink: "/musicbox/shop/v3/album/67/album_138767.htm",
182 | playtime: "234"
183 | },
184 | {
185 | id: "1229385",
186 | type: 3,
187 | url: "http://stream7.qqmusic.qq.com:0/1229385.wma",
188 | songName: "风度",
189 | singerId: "3954",
190 | singerName: "汪苏泷",
191 | albumId: "121274",
192 | albumName: "万有引力",
193 | albumLink: "/musicbox/shop/v3/album/74/album_121274.htm",
194 | playtime: "220"
195 | },
196 | {
197 | id: "1366653",
198 | type: 3,
199 | url: "http://stream8.qqmusic.qq.com:0/1366653.wma",
200 | songName: "最亲爱的你",
201 | singerId: "4351",
202 | singerName: "范玮琪",
203 | albumId: "110648",
204 | albumName: "爱,在一起Together",
205 | albumLink: "/musicbox/shop/v3/album/48/album_110648.htm",
206 | playtime: "282"
207 | },
208 | {
209 | id: "1887792",
210 | type: 3,
211 | url: "http://stream8.qqmusic.qq.com:0/1887792.wma",
212 | songName: "流恋",
213 | singerId: "4907",
214 | singerName: "吴奇隆 严艺丹",
215 | albumId: "146668",
216 | albumName: "新白发魔女传 电视原声带 Part.1",
217 | albumLink: "/musicbox/shop/v3/album/68/album_146668.htm",
218 | playtime: "245"
219 | },
220 | {
221 | id: "1833391",
222 | type: 3,
223 | url: "http://stream2.qqmusic.qq.com:0/1833391.wma",
224 | songName: "末日不孤单",
225 | singerId: "61981",
226 | singerName: "李代沫 陈浩轩",
227 | albumId: "135242",
228 | albumName: "2012年08月新歌速递",
229 | albumLink: "/musicbox/shop/v3/album/42/album_135242.htm",
230 | playtime: "272"
231 | },
232 | {
233 | id: "1319052",
234 | type: 3,
235 | url: "http://stream6.qqmusic.qq.com:0/1319052.wma",
236 | songName: "我的歌声里",
237 | singerId: "34703",
238 | singerName: "曲婉婷",
239 | albumId: "107526",
240 | albumName: "我的歌声里",
241 | albumLink: "/musicbox/shop/v3/album/26/album_107526.htm",
242 | playtime: "208"
243 | },
244 | {
245 | id: "1878910",
246 | type: 3,
247 | url: "http://stream2.qqmusic.qq.com:0/1878910.wma",
248 | songName: "最近好吗",
249 | singerId: "224",
250 | singerName: "张韶涵",
251 | albumId: "130382",
252 | albumName: "有形的翅膀",
253 | albumLink: "/musicbox/shop/v3/album/82/album_130382.htm",
254 | playtime: "249"
255 | },
256 | {
257 | id: "916834",
258 | type: 3,
259 | url: "http://stream5.qqmusic.qq.com:0/916834.wma",
260 | songName: "那些年",
261 | singerId: "24833",
262 | singerName: "胡夏",
263 | albumId: "77485",
264 | albumName: "那些年,我们一起追的女孩",
265 | albumLink: "/musicbox/shop/v3/album/85/album_77485.htm",
266 | playtime: "371"
267 | },
268 | {
269 | id: "1781758",
270 | type: 3,
271 | url: "http://stream7.qqmusic.qq.com:0/1781758.wma",
272 | songName: "任由爱",
273 | singerId: "13578",
274 | singerName: "BY2",
275 | albumId: "140197",
276 | albumName: "爱情是从告白开始的 电视原声带",
277 | albumLink: "/musicbox/shop/v3/album/97/album_140197.htm",
278 | playtime: "210"
279 | },
280 | {
281 | id: "1474843",
282 | type: 3,
283 | url: "http://stream9.qqmusic.qq.com:0/1474843.wma",
284 | songName: "胡萝卜须",
285 | singerId: "7221",
286 | singerName: "许嵩",
287 | albumId: "119459",
288 | albumName: "梦游计",
289 | albumLink: "/musicbox/shop/v3/album/59/album_119459.htm",
290 | playtime: "231"
291 | },
292 | {
293 | id: "1554114",
294 | type: 3,
295 | url: "http://stream9.qqmusic.qq.com:0/1554114.wma",
296 | songName: "拥抱你的微笑",
297 | singerId: "11626",
298 | singerName: "郭静",
299 | albumId: "125039",
300 | albumName: "原来爱就是甜蜜 电视原声带",
301 | albumLink: "/musicbox/shop/v3/album/39/album_125039.htm",
302 | playtime: "240"
303 | },
304 | {
305 | id: "974808",
306 | type: 3,
307 | url: "http://stream9.qqmusic.qq.com:0/974808.wma",
308 | songName: "依然爱你",
309 | singerId: "265",
310 | singerName: "王力宏",
311 | albumId: "81359",
312 | albumName: "火力全开 新歌+精选",
313 | albumLink: "/musicbox/shop/v3/album/59/album_81359.htm",
314 | playtime: "246"
315 | },
316 | {
317 | id: "1791017",
318 | type: 3,
319 | url: "http://stream10.qqmusic.qq.com:0/1791017.wma",
320 | songName: "存在",
321 | singerId: "4604",
322 | singerName: "汪峰",
323 | albumId: "140820",
324 | albumName: "北京青年 电视原声带",
325 | albumLink: "/musicbox/shop/v3/album/20/album_140820.htm",
326 | playtime: "284"
327 | },
328 | {
329 | id: "1500512",
330 | type: 3,
331 | url: "http://stream8.qqmusic.qq.com:0/1500512.wma",
332 | songName: "这样爱了",
333 | singerId: "19868",
334 | singerName: "张婧",
335 | albumId: "115748",
336 | albumName: "轩辕剑之天之痕",
337 | albumLink: "/musicbox/shop/v3/album/48/album_115748.htm",
338 | playtime: "263"
339 | },
340 | {
341 | id: "1891844",
342 | type: 3,
343 | url: "http://stream9.qqmusic.qq.com:0/1891844.wma",
344 | songName: "愿得一人心",
345 | singerId: "23080",
346 | singerName: "李行亮",
347 | albumId: "141889",
348 | albumName: "愿得一人心",
349 | albumLink: "/musicbox/shop/v3/album/89/album_141889.htm",
350 | playtime: "277"
351 | },
352 | {
353 | id: "1831828",
354 | type: 3,
355 | url: "http://stream7.qqmusic.qq.com:0/1831828.wma",
356 | songName: "爱的回归线",
357 | singerId: "6119",
358 | singerName: "陈韵若 陈每文",
359 | albumId: "97617",
360 | albumName: "爱情公寓3 电视原声带",
361 | albumLink: "/musicbox/shop/v3/album/17/album_97617.htm",
362 | playtime: "257"
363 | },
364 | {
365 | id: "577172",
366 | type: 3,
367 | url: "http://stream2.qqmusic.qq.com:0/577172.wma",
368 | songName: "爱情转移",
369 | singerId: "143",
370 | singerName: "陈奕迅",
371 | albumId: "48918",
372 | albumName: "1997-2007 跨世纪国语精选 CD2",
373 | albumLink: "/musicbox/shop/v3/album/18/album_48918.htm",
374 | playtime: "262"
375 | },
376 | {
377 | id: "1459416",
378 | type: 3,
379 | url: "http://stream6.qqmusic.qq.com:0/1459416.wma",
380 | songName: "无颜女",
381 | singerId: "22704",
382 | singerName: "徐良 小凌",
383 | albumId: "121966",
384 | albumName: "无颜女",
385 | albumLink: "/musicbox/shop/v3/album/66/album_121966.htm",
386 | playtime: "214"
387 | },
388 | {
389 | id: "1923586",
390 | type: 3,
391 | url: "http://stream8.qqmusic.qq.com:0/1923586.wma",
392 | songName: "可能你还爱我",
393 | singerId: "11957",
394 | singerName: "炎亚纶",
395 | albumId: "150218",
396 | albumName: "纪念日",
397 | albumLink: "/musicbox/shop/v3/album/18/album_150218.htm",
398 | playtime: "278"
399 | },
400 | {
401 | id: "726895",
402 | type: 3,
403 | url: "http://stream9.qqmusic.qq.com:0/726895.wma",
404 | songName: "最炫民族风",
405 | singerId: "5829",
406 | singerName: "凤凰传奇",
407 | albumId: "61517",
408 | albumName: "我从草原来 新歌+精选",
409 | albumLink: "/musicbox/shop/v3/album/17/album_61517.htm",
410 | playtime: "284"
411 | },
412 | {
413 | id: "935920",
414 | type: 3,
415 | url: "http://stream7.qqmusic.qq.com:0/935920.wma",
416 | songName: "策马奔腾",
417 | singerId: "5829",
418 | singerName: "凤凰传奇",
419 | albumId: "77377",
420 | albumName: "大声唱",
421 | albumLink: "/musicbox/shop/v3/album/77/album_77377.htm",
422 | playtime: "282"
423 | },
424 | {
425 | id: "447257",
426 | type: 3,
427 | url: "http://stream4.qqmusic.qq.com:0/447257.wma",
428 | songName: "AlwaysOnline",
429 | singerId: "4286",
430 | singerName: "林俊杰",
431 | albumId: "36160",
432 | albumName: "JJ陆",
433 | albumLink: "/musicbox/shop/v3/album/60/album_36160.htm",
434 | playtime: "222"
435 | },
436 | {
437 | id: "430057",
438 | type: 3,
439 | url: "http://stream10.qqmusic.qq.com:0/430057.wma",
440 | songName: "类似爱情",
441 | singerId: "165",
442 | singerName: "萧亚轩",
443 | albumId: "34887",
444 | albumName: "三面夏娃",
445 | albumLink: "/musicbox/shop/v3/album/87/album_34887.htm",
446 | playtime: "282"
447 | },
448 | {
449 | id: "1919590",
450 | type: 3,
451 | url: "http://stream9.qqmusic.qq.com:0/1919590.wma",
452 | songName: "还好有你在",
453 | singerId: "14262",
454 | singerName: "至上励合",
455 | albumId: "149889",
456 | albumName: "还好有你在",
457 | albumLink: "/musicbox/shop/v3/album/89/album_149889.htm",
458 | playtime: "293"
459 | },
460 | {
461 | id: "1113312",
462 | type: 3,
463 | url: "http://stream6.qqmusic.qq.com:0/1113312.wma",
464 | songName: "滴答",
465 | singerId: "6307",
466 | singerName: "侃侃",
467 | albumId: "94666",
468 | albumName: "《北京爱情故事》音乐原声",
469 | albumLink: "/musicbox/shop/v3/album/66/album_94666.htm",
470 | playtime: "232"
471 | },
472 | {
473 | id: "1600197",
474 | type: 3,
475 | url: "http://stream8.qqmusic.qq.com:0/1600197.wma",
476 | songName: "我知道你都知道",
477 | singerId: "5062",
478 | singerName: "薛之谦",
479 | albumId: "122328",
480 | albumName: "几个薛之谦",
481 | albumLink: "/musicbox/shop/v3/album/28/album_122328.htm",
482 | playtime: "274"
483 | },
484 | {
485 | id: "1761210",
486 | type: 3,
487 | url: "http://stream7.qqmusic.qq.com:0/1761210.wma",
488 | songName: "快乐 不再快乐",
489 | singerId: "31719",
490 | singerName: "付梦妮",
491 | albumId: "138767",
492 | albumName: "童话二分之一 电视原声带",
493 | albumLink: "/musicbox/shop/v3/album/67/album_138767.htm",
494 | playtime: "252"
495 | },
496 | {
497 | id: "974039",
498 | type: 3,
499 | url: "http://stream1.qqmusic.qq.com:0/974039.wma",
500 | songName: "爱着你却伤了她",
501 | singerId: "19722",
502 | singerName: "冷漠",
503 | albumId: "90215",
504 | albumName: "爱过以后",
505 | albumLink: "/musicbox/shop/v3/album/15/album_90215.htm",
506 | playtime: "260"
507 | },
508 | {
509 | id: "1494222",
510 | type: 3,
511 | url: "http://stream6.qqmusic.qq.com:0/1494222.wma",
512 | songName: "万有引力",
513 | singerId: "3954",
514 | singerName: "汪苏泷",
515 | albumId: "121274",
516 | albumName: "万有引力",
517 | albumLink: "/musicbox/shop/v3/album/74/album_121274.htm",
518 | playtime: "246"
519 | },
520 | {
521 | id: "1842091",
522 | type: 3,
523 | url: "http://stream5.qqmusic.qq.com:0/1842091.wma",
524 | songName: "再不疯狂我们就老了",
525 | singerId: "4615",
526 | singerName: "李宇春",
527 | albumId: "100385",
528 | albumName: "再不疯狂我们就老了",
529 | albumLink: "/musicbox/shop/v3/album/85/album_100385.htm",
530 | playtime: "246"
531 | },
532 | {
533 | id: "440817",
534 | type: 3,
535 | url: "http://stream3.qqmusic.qq.com:0/440817.wma",
536 | songName: "我们都一样",
537 | singerId: "6499",
538 | singerName: "张杰",
539 | albumId: "35875",
540 | albumName: "明天过后",
541 | albumLink: "/musicbox/shop/v3/album/75/album_35875.htm",
542 | playtime: "303"
543 | },
544 | {
545 | id: "793420",
546 | type: 3,
547 | url: "http://stream5.qqmusic.qq.com:0/793420.wma",
548 | songName: "Rolling in the Deep",
549 | singerId: "12578",
550 | singerName: "Adele",
551 | albumId: "67005",
552 | albumName: "21 (Target Deluxe Edition)",
553 | albumLink: "/musicbox/shop/v3/album/5/album_67005.htm",
554 | playtime: "229"
555 | },
556 | {
557 | id: "1913422",
558 | type: 3,
559 | url: "http://stream3.qqmusic.qq.com:0/1913422.wma",
560 | songName: "御龙品青梅",
561 | singerId: "4674",
562 | singerName: "刘惜君",
563 | albumId: "121963",
564 | albumName: "御龙在天场景音乐",
565 | albumLink: "/musicbox/shop/v3/album/63/album_121963.htm",
566 | playtime: "207"
567 | },
568 | {
569 | id: "1197338",
570 | type: 3,
571 | url: "http://stream7.qqmusic.qq.com:0/1197338.wma",
572 | songName: "逆战",
573 | singerId: "6499",
574 | singerName: "张杰",
575 | albumId: "101177",
576 | albumName: "逆战",
577 | albumLink: "/musicbox/shop/v3/album/77/album_101177.htm",
578 | playtime: "229"
579 | },
580 | {
581 | id: "874843",
582 | type: 3,
583 | url: "http://stream5.qqmusic.qq.com:0/874843.wma",
584 | songName: "不要在我寂寞的时候说爱我(国)",
585 | singerId: "4715",
586 | singerName: "郑源",
587 | albumId: "33812",
588 | albumName: "源情歌",
589 | albumLink: "/musicbox/shop/v3/album/12/album_33812.htm",
590 | playtime: "244"
591 | },
592 | {
593 | id: "1673329",
594 | type: 3,
595 | url: "http://stream7.qqmusic.qq.com:0/1673329.wma",
596 | songName: "单身美好",
597 | singerId: "11626",
598 | singerName: "郭静",
599 | albumId: "133127",
600 | albumName: "花是爱 电视原声带",
601 | albumLink: "/musicbox/shop/v3/album/27/album_133127.htm",
602 | playtime: "249"
603 | },
604 | {
605 | id: "1887796",
606 | type: 3,
607 | url: "http://stream8.qqmusic.qq.com:0/1887796.wma",
608 | songName: "留香",
609 | singerId: "4907",
610 | singerName: "吴奇隆",
611 | albumId: "146668",
612 | albumName: "新白发魔女传 电视原声带 Part.1",
613 | albumLink: "/musicbox/shop/v3/album/68/album_146668.htm",
614 | playtime: "196"
615 | },
616 | {
617 | id: "1037897",
618 | type: 3,
619 | url: "http://stream7.qqmusic.qq.com:0/1037897.wma",
620 | songName: "我想我不够好",
621 | singerId: "28634",
622 | singerName: "单色凌",
623 | albumId: "87797",
624 | albumName: "11月网络红歌2",
625 | albumLink: "/musicbox/shop/v3/album/97/album_87797.htm",
626 | playtime: "172"
627 | },
628 | {
629 | id: "1878998",
630 | type: 3,
631 | url: "http://stream3.qqmusic.qq.com:0/1878998.wma",
632 | songName: "伤心童话(电影版)",
633 | singerId: "24833",
634 | singerName: "胡夏",
635 | albumId: "143913",
636 | albumName: "2012年09月新歌速递",
637 | albumLink: "/musicbox/shop/v3/album/13/album_143913.htm",
638 | playtime: "278"
639 | },
640 | {
641 | id: "916320",
642 | type: 3,
643 | url: "http://stream1.qqmusic.qq.com:0/916320.wma",
644 | songName: "全世界宣布爱你",
645 | singerId: "22874",
646 | singerName: "孙子涵",
647 | albumId: "77451",
648 | albumName: "一年一度的夏天",
649 | albumLink: "/musicbox/shop/v3/album/51/album_77451.htm",
650 | playtime: "235"
651 | },
652 | {
653 | id: "432421",
654 | type: 3,
655 | url: "http://stream3.qqmusic.qq.com:0/432421.wma",
656 | songName: "如果沒有你",
657 | singerId: "54",
658 | singerName: "莫文蔚",
659 | albumId: "35165",
660 | albumName: "就i Karen 莫文蔚精选",
661 | albumLink: "/musicbox/shop/v3/album/65/album_35165.htm",
662 | playtime: "289"
663 | },
664 | {
665 | id: "1136672",
666 | type: 3,
667 | url: "http://stream4.qqmusic.qq.com:0/1136672.wma",
668 | songName: "经过",
669 | singerId: "11446",
670 | singerName: "陈楚生 何洁",
671 | albumId: "96774",
672 | albumName: "夫妻那些事",
673 | albumLink: "/musicbox/shop/v3/album/74/album_96774.htm",
674 | playtime: "244"
675 | },
676 | {
677 | id: "1232479",
678 | type: 3,
679 | url: "http://stream5.qqmusic.qq.com:0/1232479.wma",
680 | songName: "一个人不可能",
681 | singerId: "11979",
682 | singerName: "丁当",
683 | albumId: "101565",
684 | albumName: "好难得",
685 | albumLink: "/musicbox/shop/v3/album/65/album_101565.htm",
686 | playtime: "290"
687 | },
688 | {
689 | id: "936753",
690 | type: 3,
691 | url: "http://stream2.qqmusic.qq.com:0/936753.wma",
692 | songName: "说好了不见面",
693 | singerId: "16292",
694 | singerName: "小贱",
695 | albumId: "76932",
696 | albumName: "2011年8月新歌速递2",
697 | albumLink: "/musicbox/shop/v3/album/32/album_76932.htm",
698 | playtime: "208"
699 | },
700 | {
701 | id: "674077",
702 | type: 3,
703 | url: "http://stream7.qqmusic.qq.com:0/674077.wma",
704 | songName: "手放开",
705 | singerId: "38",
706 | singerName: "李圣杰",
707 | albumId: "56866",
708 | albumName: "孤鸾疗伤版",
709 | albumLink: "/musicbox/shop/v3/album/66/album_56866.htm",
710 | playtime: "265"
711 | },
712 | {
713 | id: "1539092",
714 | type: 3,
715 | url: "http://stream3.qqmusic.qq.com:0/1539092.wma",
716 | songName: "好男人都死哪儿去了",
717 | singerId: "37459",
718 | singerName: "崔子格",
719 | albumId: "123853",
720 | albumName: "好男人都死哪儿去了",
721 | albumLink: "/musicbox/shop/v3/album/53/album_123853.htm",
722 | playtime: "240"
723 | },
724 | {
725 | id: "434447",
726 | type: 3,
727 | url: "http://stream6.qqmusic.qq.com:0/434447.wma",
728 | songName: "擦肩而过",
729 | singerId: "4715",
730 | singerName: "郑源",
731 | albumId: "35352",
732 | albumName: "擦肩而过",
733 | albumLink: "/musicbox/shop/v3/album/52/album_35352.htm",
734 | playtime: "234"
735 | },
736 | {
737 | id: "1014867",
738 | type: 3,
739 | url: "http://stream4.qqmusic.qq.com:0/1014867.wma",
740 | songName: "朋友的酒",
741 | singerId: "6862",
742 | singerName: "李晓杰",
743 | albumId: "84524",
744 | albumName: "2011年10月新歌速递",
745 | albumLink: "/musicbox/shop/v3/album/24/album_84524.htm",
746 | playtime: "261"
747 | },
748 | {
749 | id: "1385291",
750 | type: 3,
751 | url: "http://stream4.qqmusic.qq.com:0/1385291.wma",
752 | songName: "凌乱的华丽",
753 | singerId: "28634",
754 | singerName: "单色凌",
755 | albumId: "112454",
756 | albumName: "凌乱的华丽 EP",
757 | albumLink: "/musicbox/shop/v3/album/54/album_112454.htm",
758 | playtime: "186"
759 | },
760 | {
761 | id: "1403189",
762 | type: 3,
763 | url: "http://stream6.qqmusic.qq.com:0/1403189.wma",
764 | songName: "一生无悔",
765 | singerId: "19229",
766 | singerName: "高安 杭娇",
767 | albumId: "114086",
768 | albumName: "一唱而红",
769 | albumLink: "/musicbox/shop/v3/album/86/album_114086.htm",
770 | playtime: "242"
771 | },
772 | {
773 | id: "1547646",
774 | type: 3,
775 | url: "http://stream10.qqmusic.qq.com:0/1547646.wma",
776 | songName: "胡闹",
777 | singerId: "178",
778 | singerName: "吴克羣",
779 | albumId: "124530",
780 | albumName: "寂寞来了怎么办",
781 | albumLink: "/musicbox/shop/v3/album/30/album_124530.htm",
782 | playtime: "329"
783 | },
784 | {
785 | id: "777178",
786 | type: 3,
787 | url: "http://stream5.qqmusic.qq.com:0/777178.wma",
788 | songName: "你是我的眼",
789 | singerId: "11606",
790 | singerName: "林宥嘉",
791 | albumId: "65505",
792 | albumName: "昨天今天明天",
793 | albumLink: "/musicbox/shop/v3/album/5/album_65505.htm",
794 | playtime: "283"
795 | },
796 | {
797 | id: "1193426",
798 | type: 3,
799 | url: "http://stream3.qqmusic.qq.com:0/1193426.wma",
800 | songName: "有我在",
801 | singerId: "4651",
802 | singerName: "罗志祥",
803 | albumId: "100593",
804 | albumName: "有我在",
805 | albumLink: "/musicbox/shop/v3/album/93/album_100593.htm",
806 | playtime: "264"
807 | },
808 | {
809 | id: "691943",
810 | type: 3,
811 | url: "http://stream1.qqmusic.qq.com:0/691943.wma",
812 | songName: "HIGH歌",
813 | singerId: "11476",
814 | singerName: "黄龄",
815 | albumId: "58502",
816 | albumName: "特别",
817 | albumLink: "/musicbox/shop/v3/album/2/album_58502.htm",
818 | playtime: "283"
819 | },
820 | {
821 | id: "462620",
822 | type: 3,
823 | url: "http://stream9.qqmusic.qq.com:0/462620.wma",
824 | songName: "难以启齿的柔弱",
825 | singerId: "12111",
826 | singerName: "金志文",
827 | albumId: "37632",
828 | albumName: "爱比不爱更寂寞",
829 | albumLink: "/musicbox/shop/v3/album/32/album_37632.htm",
830 | playtime: "250"
831 | },
832 | {
833 | id: "1067128",
834 | type: 3,
835 | url: "http://stream2.qqmusic.qq.com:0/1067128.wma",
836 | songName: "老男孩",
837 | singerId: "11761",
838 | singerName: "筷子兄弟",
839 | albumId: "90932",
840 | albumName: "父亲",
841 | albumLink: "/musicbox/shop/v3/album/32/album_90932.htm",
842 | playtime: "300"
843 | },
844 | {
845 | id: "434074",
846 | type: 3,
847 | url: "http://stream1.qqmusic.qq.com:0/434074.wma",
848 | songName: "最初的梦想",
849 | singerId: "4351",
850 | singerName: "范玮琪",
851 | albumId: "35325",
852 | albumName: "Faces Of FanFan 新歌+精选32首全纪录",
853 | albumLink: "/musicbox/shop/v3/album/25/album_35325.htm",
854 | playtime: "298"
855 | },
856 | {
857 | id: "1844597",
858 | type: 3,
859 | url: "http://stream6.qqmusic.qq.com:0/1844597.wma",
860 | songName: "诗人漫步",
861 | singerId: "227",
862 | singerName: "蔡依林",
863 | albumId: "139346",
864 | albumName: "MUSE",
865 | albumLink: "/musicbox/shop/v3/album/46/album_139346.htm",
866 | playtime: "308"
867 | },
868 | {
869 | id: "185675",
870 | type: 3,
871 | url: "http://stream2.qqmusic.qq.com:0/185675.wma",
872 | songName: "我怀念的",
873 | singerId: "109",
874 | singerName: "孙燕姿",
875 | albumId: "15902",
876 | albumName: "逆光",
877 | albumLink: "/musicbox/shop/v3/album/2/album_15902.htm",
878 | playtime: "287"
879 | },
880 | {
881 | id: "2441405",
882 | type: 3,
883 | url: "http://stream9.qqmusic.qq.com:0/2441405.wma",
884 | songName: "不再让你孤单",
885 | singerId: "208",
886 | singerName: "水木年华",
887 | albumId: "150859",
888 | albumName: "2012年10月新歌速递",
889 | albumLink: "/musicbox/shop/v3/album/59/album_150859.htm",
890 | playtime: "343"
891 | },
892 | {
893 | id: "416764",
894 | type: 3,
895 | url: "http://stream4.qqmusic.qq.com:0/416764.wma",
896 | songName: "洋葱",
897 | singerId: "11608",
898 | singerName: "杨宗纬",
899 | albumId: "33703",
900 | albumName: "鸽子",
901 | albumLink: "/musicbox/shop/v3/album/3/album_33703.htm",
902 | playtime: "278"
903 | },
904 | {
905 | id: "97870",
906 | type: 3,
907 | url: "http://stream7.qqmusic.qq.com:0/97870.wma",
908 | songName: "一直很安静",
909 | singerId: "3346",
910 | singerName: "阿桑",
911 | albumId: "8229",
912 | albumName: "寂寞在唱歌",
913 | albumLink: "/musicbox/shop/v3/album/29/album_8229.htm",
914 | playtime: "251"
915 | },
916 | {
917 | id: "469831",
918 | type: 3,
919 | url: "http://stream2.qqmusic.qq.com:0/469831.wma",
920 | songName: "关不上的窗",
921 | singerId: "4365",
922 | singerName: "周传雄",
923 | albumId: "38202",
924 | albumName: "恋人创世纪",
925 | albumLink: "/musicbox/shop/v3/album/2/album_38202.htm",
926 | playtime: "293"
927 | },
928 | {
929 | id: "1092641",
930 | type: 3,
931 | url: "http://stream4.qqmusic.qq.com:0/1092641.wma",
932 | songName: "我想大声告诉你",
933 | singerId: "15798",
934 | singerName: "樊凡",
935 | albumId: "92824",
936 | albumName: "我想大声告诉你",
937 | albumLink: "/musicbox/shop/v3/album/24/album_92824.htm",
938 | playtime: "275"
939 | },
940 | {
941 | id: "797241",
942 | type: 3,
943 | url: "http://stream9.qqmusic.qq.com:0/797241.wma",
944 | songName: "暖暖",
945 | singerId: "44",
946 | singerName: "梁静茹",
947 | albumId: "67399",
948 | albumName: "现在开始我爱你(Disc2)",
949 | albumLink: "/musicbox/shop/v3/album/99/album_67399.htm",
950 | playtime: "243"
951 | },
952 | {
953 | id: "1414751",
954 | type: 3,
955 | url: "http://stream4.qqmusic.qq.com:0/1414751.wma",
956 | songName: "慢慢",
957 | singerId: "174",
958 | singerName: "张学友",
959 | albumId: "20164",
960 | albumName: "Black & White",
961 | albumLink: "/musicbox/shop/v3/album/64/album_20164.htm",
962 | playtime: "282"
963 | },
964 | {
965 | id: "1739275",
966 | type: 3,
967 | url: "http://stream1.qqmusic.qq.com:0/1739275.wma",
968 | songName: "哥有老婆",
969 | singerId: "64495",
970 | singerName: "纪晓斌",
971 | albumId: "137331",
972 | albumName: "哥有老婆",
973 | albumLink: "/musicbox/shop/v3/album/31/album_137331.htm",
974 | playtime: "239"
975 | },
976 | {
977 | id: "1050795",
978 | type: 3,
979 | url: "http://stream7.qqmusic.qq.com:0/1050795.wma",
980 | songName: "多喜欢你",
981 | singerId: "16292",
982 | singerName: "小贱",
983 | albumId: "89627",
984 | albumName: "多喜欢你",
985 | albumLink: "/musicbox/shop/v3/album/27/album_89627.htm",
986 | playtime: "237"
987 | },
988 | {
989 | id: "1363973",
990 | type: 3,
991 | url: "http://stream4.qqmusic.qq.com:0/1363973.wma",
992 | songName: "Someone Like You",
993 | singerId: "12578",
994 | singerName: "Adele",
995 | albumId: "110534",
996 | albumName: "21(Japan Bonus Track Version)",
997 | albumLink: "/musicbox/shop/v3/album/34/album_110534.htm",
998 | playtime: "287"
999 | },
1000 | {
1001 | id: "231008",
1002 | type: 3,
1003 | url: "http://stream9.qqmusic.qq.com:0/231008.wma",
1004 | songName: "只想一生跟你走",
1005 | singerId: "174",
1006 | singerName: "张学友",
1007 | albumId: "20178",
1008 | albumName: "一生跟你走 (年度代表作品辑)",
1009 | albumLink: "/musicbox/shop/v3/album/78/album_20178.htm",
1010 | playtime: "313"
1011 | },
1012 | {
1013 | id: "410316",
1014 | type: 3,
1015 | url: "http://stream8.qqmusic.qq.com:0/410316.wma",
1016 | songName: "青花瓷",
1017 | singerId: "4558",
1018 | singerName: "周杰伦",
1019 | albumId: "33021",
1020 | albumName: "我很忙",
1021 | albumLink: "/musicbox/shop/v3/album/21/album_33021.htm",
1022 | playtime: "239"
1023 | },
1024 | {
1025 | id: "1200324",
1026 | type: 3,
1027 | url: "http://stream7.qqmusic.qq.com:0/1200324.wma",
1028 | songName: "藕断丝连",
1029 | singerId: "7298",
1030 | singerName: "陈瑞",
1031 | albumId: "101397",
1032 | albumName: "把你藏心里",
1033 | albumLink: "/musicbox/shop/v3/album/97/album_101397.htm",
1034 | playtime: "291"
1035 | },
1036 | {
1037 | id: "1191160",
1038 | type: 3,
1039 | url: "http://stream9.qqmusic.qq.com:0/1191160.wma",
1040 | songName: "兄弟抱一下",
1041 | singerId: "221",
1042 | singerName: "庞龙",
1043 | albumId: "100659",
1044 | albumName: "兄弟抱一下",
1045 | albumLink: "/musicbox/shop/v3/album/59/album_100659.htm",
1046 | playtime: "265"
1047 | },
1048 | {
1049 | id: "678753",
1050 | type: 3,
1051 | url: "http://stream8.qqmusic.qq.com:0/678753.wma",
1052 | songName: "十一年",
1053 | singerId: "3558",
1054 | singerName: "邱永传",
1055 | albumId: "57259",
1056 | albumName: "2010年5月新歌速递",
1057 | albumLink: "/musicbox/shop/v3/album/59/album_57259.htm",
1058 | playtime: "254"
1059 | },
1060 | {
1061 | id: "797227",
1062 | type: 3,
1063 | url: "http://stream9.qqmusic.qq.com:0/797227.wma",
1064 | songName: "可惜不是你",
1065 | singerId: "44",
1066 | singerName: "梁静茹",
1067 | albumId: "69903",
1068 | albumName: "现在开始我爱你(Disc1)",
1069 | albumLink: "/musicbox/shop/v3/album/3/album_69903.htm",
1070 | playtime: "285"
1071 | },
1072 | {
1073 | id: "1943608",
1074 | type: 3,
1075 | url: "http://stream10.qqmusic.qq.com:0/1943608.wma",
1076 | songName: "你懂得",
1077 | singerId: "12744",
1078 | singerName: "小沈阳 沈春阳",
1079 | albumId: "151990",
1080 | albumName: "后厨 电视原声带",
1081 | albumLink: "/musicbox/shop/v3/album/90/album_151990.htm",
1082 | playtime: "274"
1083 | },
1084 | {
1085 | id: "1518325",
1086 | type: 3,
1087 | url: "http://stream1.qqmusic.qq.com:0/1518325.wma",
1088 | songName: "Whistle",
1089 | singerId: "12740",
1090 | singerName: "Flo Rida",
1091 | albumId: "121661",
1092 | albumName: "Wild Ones",
1093 | albumLink: "/musicbox/shop/v3/album/61/album_121661.htm",
1094 | playtime: "225"
1095 | },
1096 | {
1097 | id: "672519",
1098 | type: 3,
1099 | url: "http://stream4.qqmusic.qq.com:0/672519.wma",
1100 | songName: "眼泪的错觉",
1101 | singerId: "44275",
1102 | singerName: "王露凝",
1103 | albumId: "8930",
1104 | albumName: "2010年四月热搜歌",
1105 | albumLink: "/musicbox/shop/v3/album/30/album_8930.htm",
1106 | playtime: "223"
1107 | },
1108 | {
1109 | id: "435848",
1110 | type: 3,
1111 | url: "http://stream10.qqmusic.qq.com:0/435848.wma",
1112 | songName: "放生",
1113 | singerId: "220",
1114 | singerName: "范逸臣",
1115 | albumId: "35459",
1116 | albumName: "无乐不作 (新歌+精选)",
1117 | albumLink: "/musicbox/shop/v3/album/59/album_35459.htm",
1118 | playtime: "272"
1119 | },
1120 | {
1121 | id: "938054",
1122 | type: 3,
1123 | url: "http://stream4.qqmusic.qq.com:0/938054.wma",
1124 | songName: "如果爱忘了",
1125 | singerId: "7033",
1126 | singerName: "戚薇",
1127 | albumId: "79174",
1128 | albumName: "如果爱忘了",
1129 | albumLink: "/musicbox/shop/v3/album/74/album_79174.htm",
1130 | playtime: "239"
1131 | },
1132 | {
1133 | id: "947618",
1134 | type: 3,
1135 | url: "http://stream9.qqmusic.qq.com:0/947618.wma",
1136 | songName: "你在看孤独的风景",
1137 | singerId: "4545",
1138 | singerName: "本兮",
1139 | albumId: "80239",
1140 | albumName: "你在看孤独的风景",
1141 | albumLink: "/musicbox/shop/v3/album/39/album_80239.htm",
1142 | playtime: "250"
1143 | },
1144 | {
1145 | id: "1857290",
1146 | type: 3,
1147 | url: "http://stream5.qqmusic.qq.com:0/1857290.wma",
1148 | songName: "天天想你",
1149 | singerId: "10",
1150 | singerName: "陈绮贞",
1151 | albumId: "145135",
1152 | albumName: "夏季练习曲世界巡回演唱会录音",
1153 | albumLink: "/musicbox/shop/v3/album/35/album_145135.htm",
1154 | playtime: "256"
1155 | },
1156 | {
1157 | id: "1769730",
1158 | type: 3,
1159 | url: "http://stream6.qqmusic.qq.com:0/1769730.wma",
1160 | songName: "大艺术家",
1161 | singerId: "227",
1162 | singerName: "蔡依林",
1163 | albumId: "139346",
1164 | albumName: "MUSE",
1165 | albumLink: "/musicbox/shop/v3/album/46/album_139346.htm",
1166 | playtime: "197"
1167 | },
1168 | {
1169 | id: "1114377",
1170 | type: 3,
1171 | url: "http://stream5.qqmusic.qq.com:0/1114377.wma",
1172 | songName: "因为爱情",
1173 | singerId: "264",
1174 | singerName: "王菲 陈奕迅",
1175 | albumId: "94805",
1176 | albumName: "2012龙年春晚",
1177 | albumLink: "/musicbox/shop/v3/album/5/album_94805.htm",
1178 | playtime: "215"
1179 | },
1180 | {
1181 | id: "1943208",
1182 | type: 3,
1183 | url: "http://stream2.qqmusic.qq.com:0/1943208.wma",
1184 | songName: "只爱到一半",
1185 | singerId: "11453",
1186 | singerName: "魏晨",
1187 | albumId: "149192",
1188 | albumName: "V SPACE",
1189 | albumLink: "/musicbox/shop/v3/album/92/album_149192.htm",
1190 | playtime: "257"
1191 | },
1192 | {
1193 | id: "1889873",
1194 | type: 3,
1195 | url: "http://stream8.qqmusic.qq.com:0/1889873.wma",
1196 | songName: "缺口",
1197 | singerId: "6204",
1198 | singerName: "林凡",
1199 | albumId: "147448",
1200 | albumName: "我家有喜 电视原声带",
1201 | albumLink: "/musicbox/shop/v3/album/48/album_147448.htm",
1202 | playtime: "242"
1203 | }]
1204 | };
--------------------------------------------------------------------------------
/static/vue-animated-list.js:
--------------------------------------------------------------------------------
1 | (function (global, factory) {
2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3 | typeof define === 'function' && define.amd ? define(factory) :
4 | (global.VueAnimatedList = factory());
5 | }(this, function () { 'use strict';
6 | function install (Vue) {
7 | var _ = Vue.util
8 | var transitionEndEvent = _.transitionEndEvent
9 | var addClass = _.addClass
10 | var removeClass = _.removeClass
11 | var on = _.on
12 | var off = _.off
13 | var transitionProp = _.transitionProp
14 |
15 | // patch v-for
16 | var vFor = Vue.directive('for')
17 | var diff = vFor.diff
18 | vFor.diff = function () {
19 | var needMoveTransition = prepareMoveTransition(this.frags)
20 | diff.apply(this, arguments)
21 | if (needMoveTransition) {
22 | applyMoveTransition(this.frags)
23 | }
24 | }
25 |
26 | /**
27 | * Check if move transitions are needed, and if so,
28 | * record the bounding client rects for each item.
29 | *
30 | * @param {Array|undefined} frags
31 | * @return {Boolean|undefined}
32 | */
33 |
34 | function prepareMoveTransition (frags) {
35 | var transition =
36 | transitionEndEvent && // css transition supported?
37 | frags && frags.length && // has frags to be moved?
38 | frags[0].node.__v_trans // has transitions?
39 | if (transition) {
40 | var node = frags[0].node
41 | var moveClass = transition.id + '-move'
42 | var moving = node._pendingMoveCb
43 | var hasTransition = false
44 | if (!moving) {
45 | // sniff whether element has a transition duration for transform
46 | // with the move class applied
47 | addClass(node, moveClass)
48 | var type = transition.getCssTransitionType(moveClass)
49 | if (type === 'transition') {
50 | var computedStyles = window.getComputedStyle(node)
51 | var transitionedProps = computedStyles[transitionProp + 'Property']
52 | if (/\btransform(,|$)/.test(transitionedProps)) {
53 | hasTransition = true
54 | }
55 | }
56 | removeClass(node, moveClass)
57 | }
58 | if (moving || hasTransition) {
59 | frags.forEach(function (frag) {
60 | frag._oldPos = frag.node.getBoundingClientRect()
61 | })
62 | return true
63 | }
64 | }
65 | }
66 |
67 | /**
68 | * Apply move transitions.
69 | * Calculate new target positions after the move, then apply the
70 | * FLIP technique to trigger CSS transforms.
71 | *
72 | * @param {Array} frags
73 | */
74 |
75 | function applyMoveTransition (frags) {
76 | frags.forEach(function (frag) {
77 | frag._newPos = frag.node.getBoundingClientRect()
78 | })
79 | frags.forEach(function (frag) {
80 | var node = frag.node
81 | var oldPos = frag._oldPos
82 | if (!oldPos) return
83 | if (!frag.moved) {
84 | // transition busting to ensure correct bounding rect:
85 | // if an element has an ongoing transition and not "reinserted",
86 | // the bounding rect will not be calculated at its target position,
87 | // but rather an in-transition position.
88 | var p = node.parentNode
89 | var next = node.nextSibling
90 | p.removeChild(node)
91 | p.insertBefore(node, next)
92 | }
93 | var dx = oldPos.left - frag._newPos.left
94 | var dy = oldPos.top - frag._newPos.top
95 | if (dx !== 0 || dy !== 0) {
96 | frag.moved = true
97 | node.style.transform =
98 | node.style.WebkitTransform =
99 | 'translate(' + dx + 'px, ' + dy + 'px)'
100 | node.style.transitionDuration = '0s'
101 | } else {
102 | frag.moved = false
103 | }
104 | })
105 | Vue.nextTick(function () {
106 | var f = document.documentElement.offsetHeight
107 | frags.forEach(function (frag) {
108 | var node = frag.node
109 | var moveClass = node.__v_trans.id + '-move'
110 | if (frag.moved) {
111 | addClass(node, moveClass)
112 | node.style.transform = node.style.WebkitTransform = ''
113 | node.style.transitionDuration = ''
114 | if (node._pendingMoveCb) {
115 | off(node, transitionEndEvent, node._pendingMoveCb)
116 | }
117 | node._pendingMoveCb = function cb () {
118 | off(node, transitionEndEvent, cb)
119 | node._pendingMoveCb = null
120 | removeClass(node, moveClass)
121 | }
122 | on(node, transitionEndEvent, node._pendingMoveCb)
123 | }
124 | })
125 | })
126 | }
127 | }
128 |
129 | if (typeof Vue !== 'undefined') {
130 | Vue.use(install)
131 | }
132 | return install
133 | }));
134 |
--------------------------------------------------------------------------------