diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2018-05-25 17:12:07 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2018-05-31 15:50:50 +0000 |
commit | c4a21708ed186640f4db381dc800febdbc85941e (patch) | |
tree | 72c5414f12b15d6b5e932666a6f4bb72f0ba2bfa /util/gradientgen/gradientgen.js | |
parent | c538a333db4b7526fb4d9a82c06296d2492bf000 (diff) |
Provide presets for QGradient
Similar to Qt::GlobalColor, the presets allow the user to create
brushes based on predefined gradients, quickly getting pretty pixels
on screen.
The presets are based on the linear gradients from WebGradients, a
free collection of gradients, hosted at https://webgradients.com/.
The few radial and blended gradient presets have been excluded.
Change-Id: I1ce8f2210a6045c9edb8829ab3eddcc313549127
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'util/gradientgen/gradientgen.js')
-rwxr-xr-x | util/gradientgen/gradientgen.js | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/util/gradientgen/gradientgen.js b/util/gradientgen/gradientgen.js new file mode 100755 index 0000000000..ff256d16d6 --- /dev/null +++ b/util/gradientgen/gradientgen.js @@ -0,0 +1,123 @@ +#! /usr/bin/env node + +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the utils of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +const _ = require('lodash'); +const fs = require('fs'); + +const postcss = require('postcss'); +const minifyGradients = require('postcss-minify-gradients'); +const valueParser = require('postcss-value-parser'); +const parseColor = require('parse-color'); +const math = require('mathjs'); + +const argc = process.argv.length; +if (argc < 3) { + console.log("usage: gradientgen [mode] <filename>"); + process.exit(1); +} + +const filename = process.argv[argc - 1]; +const mode = argc > 3 ? process.argv[argc - 2] : ''; + +fs.readFile(filename, (err, css) => { + postcss([minifyGradients]).process(css) + .then(result => { + let enums = []; + let gradients = []; + + result.root.walkRules(rule => { + gradients.push(null); // Placeholder + + const name = _.startCase(rule.selector).replace(/\s/g, ''); + if (enums.indexOf(name) >= 0) + return; // Duplicate entry + + // We can only support single gradient declarations + if (rule.nodes.length > 1) + return; + + valueParser(rule.nodes[0].value).walk(node => { + if (node.type !== 'function') + return; + + if (node.value !== 'linear-gradient') + return; + + const args = node.nodes.reduce((args, arg) => { + if (arg.type === 'div') + args.push([]); + else if (arg.type !== 'space') + args[args.length - 1].push(arg.value); + return args; + }, [[]]); + + let angle = valueParser.unit(args[0][0]); + if (angle.unit !== 'deg') + return; + + angle = parseInt(angle.number); + if (angle < 0) + angle += 360; + + // Angle is in degrees, but we need radians + const radians = angle * math.pi / 180; + + const gradientLine = (math.abs(math.sin(radians)) + math.abs(math.cos(radians))); + const cathetus = fn => math.round(fn(radians - math.pi / 2) * gradientLine / 2, 10); + + const x = cathetus(math.cos); + const y = cathetus(math.sin); + + const start = { x: 0.5 - x, y: 0.5 - y }; + const end = { x: 0.5 + x, y: 0.5 + y }; + + let stops = [] + args.slice(1).forEach((arg, index) => { + let [color, stop = !index ? '0%' : '100%'] = arg; + stop = parseInt(stop) / 100; + color = parseColor(color).hex; + color = parseInt(color.slice(1), 16) + stops.push({ color, stop }) + }); + + gradients[gradients.length - 1] = { start, end, stops }; + }); + + enums.push(name); + + if (mode == 'enums') + console.log(`${name} = ${gradients.length},`) + }); + + // Done walking declarations + if (mode != 'enums') + console.log(JSON.stringify(gradients, undefined, 4)); + }); +}); |