echarts渐变色与css渐变色互转(两个坐标点转角度)

前言

用于 echarts 的小伙伴都知道,他使用的渐变色写法和 css 的写法不一样。css 中直接使用角度定义渐变的方向,而 echarts 使用的是两个坐标点来进行标识方向(线性渐变)。

本文主要针对线性渐变的转换

那怎么在 css 中使用 echarts 的渐变色呢🤔? 也就是需要相互转换,下文将对此进行实现。

最终实现目标如下图演示:
左边是 echarts 柱状图,右边是 div
坐标转换.gif

两种渐变色格式

css 线性渐变使用方法 linear-gradient

<div
     style={{
        backgroundImage: `linear-gradient(90deg, red, blue)`
    }}
></div>

echarts 线性渐变使用方法


// echarts 颜色
const color = {
    type: "linear",  
    x: 0,
    y: 0.5,
    x2: 1,
    y2: 0.5, 
    colorStops: [
        {
                offset: 0,
                color: "red", // 0% 处的颜色
        },
        {
                offset: 1,
                color: "blue", // 100% 处的颜色
        },
    ]
};
        
const options = { 
     // ...
    series: [
        {
            // ...
            itemStyle: {
                 color,
            },
        },
    ],
};

代码目标

从上面可以看出来,其实就是 echarts 用了坐标的形式,而 css 使用的角度。所以针对坐标和角度进行转换即可

实现代码

具体实现见下面代码即可,懒得写了~

import React, { useEffect, useState, useRef } from "react";
// import Test from './views/Test';

/**
 * 线性渐变,前四个参数分别是 x0, y0, x2, y2
 * x y 语义
 *
 * x=0.5 y=0,     x2=0.5, y2=1   从上到下
 * x=1   y=0.5,   x2=0.5,   y2=0   从下到上
 * x=0   y=0.5,   x2=1,   y2=0.5 从左到右
 * x=1   y=0.5,   x2=0,   y2=0.5 从右到左
 * 
 * css 中 0deg 是从上到下,顺时针方向是从左到右渐变(90deg => 左到右)
 *
 * */ 

function App() {
	const pointArr = useRef();
	const myChart = useRef();
	const [deg, setDeg] = useState();

	// echarts 颜色
	const color = {
		type: "linear", 
		// 左到右  90 deg
		x: 0,
		y: 0.5,
		x2: 1,
		y2: 0.5,

		colorStops: [
			{
				offset: 0,
				color: "red", // 0% 处的颜色
			},
			{
				offset: 1,
				color: "blue", // 100% 处的颜色
			},
		],
		global: false, // 缺省为 false
	};

	useEffect(() => {
		const format = ({ x: x1, y: y1, x2, y2 }) => {
			var getYAngle = function (cx, cy, x2, y2) {
				var x = Math.abs(cx - x2);
				var y = Math.abs(cy - y2);
				var tan = x / y;
				var radina = Math.atan(tan); //用反三角函数求弧度
				var angle = Math.floor(180 / (Math.PI / radina)) || 0; //将弧度转换成角度
				console.log("angle", angle);
				/**
				 * 根据目标点判断象限(注意是笛卡尔坐标)
				 * 一: +,+
				 * 二: -,+
				 * 三: -,+
				 * 一: +,-
				 */

				//  * 二、三象限要加 180°
				if (x2 < 0 && y2 >= 0) {
					angle = 180 + angle;
				}
				if (x2 < 0 && y2 < 0) {
					angle = 180 + angle;
				}

				// 一、二象限 === 0 就是 180°
				if (angle === 0) {
					if ((x2 >= 0 && y2 > 0) || (x2 <= 0 && y2 > 0)) {
						angle = 180 + angle;
					}
				}

				return angle;
			};

			/**
			 * 1、将 二维 坐标看成一个正方形([0, 0],[1, 0],[1, 1],[0, 1]), 坐落于一象限
			 * 2、根据二维坐标转一个新的坐标(相对于正方形中心点的,所以线段会贯穿正方形),
			 *    把相对于笛卡尔坐标系中心点的坐标,转为相对于正方形中心点的坐标
			 *    eg: x 0.5 => 0,
			 *        y 0   => -0.5
			 *
			 *        其实就是  x - 0.5,  y - 0.5
			 */
			const deg = getYAngle(color.x - 0.5, color.y - 0.5, color.x2 - 0.5, color.y2 - 0.5); 
		};
		const deg = format(color);

		// 计算成 css 渐变
		setDeg(deg);

		const options = {
			grid: {
				left: -100,
				top: 0,
				right: 0,
				bottom: 0,
				width: "180%",
			},
			xAxis: { show: false, data: ["数据"], boundaryGap: false },
			yAxis: { show: false },
			series: [
				{
					data: [100],
					type: "bar",
					itemStyle: {
						color,
					},
				},
			],
		};
		myChart.current = echarts.init(document.getElementById("main"));
		myChart.current.setOption(options);
	}, []);

	// 是否按下
	const isDwon = useRef();
	const onMouseDown = () => {
		isDwon.current = true; 
	};
	const onMouseUp = () => {
		isDwon.current = false; 
	};
	const onMouseMove = (event) => {
		if (!isDwon.current) return;
		const rece = pointArr.current.getBoundingClientRect();
		// 中心点
		const center = {
			x: rece.left + (rece.right - rece.left) / 2,
			y: rece.top + (rece.bottom - rece.top) / 2,
		};
		const rad = Math.atan2(center.y - event.pageY, center.x - event.pageX);
		let deg = rad / (Math.PI / 180) - 90; 
		if (deg < 0) {
			deg += 360;
		}
		setDeg(deg); 

		// 角度转坐标 
		const format2 = (deg) => { 

			// 假定旋转半径 0.5 
			const start = { x: 0, y: -0.5 };
			const end = {};
			end.x2 = start.x * Math.cos((deg * Math.PI) / 180) - start.y * Math.sin((deg * Math.PI) / 180);
			end.y2 = start.x * Math.sin((deg * Math.PI) / 180) + start.y * Math.cos((deg * Math.PI) / 180);
			 
      // 算出对应其他象限中对应的点
      end.x = 0 - end.x2;
      end.y = 0 - end.y2;

      // console.log(deg, end);
      return end; 
		};
		const { x, y, x2, y2 } = format2(deg);

		myChart.current.setOption({
			series: [
				{
					data: [100],
					type: "bar",
					itemStyle: {
						color: {
							...color,
							x: x + 0.5,
							y: y + 0.5,
							x2: x2 + 0.5,
							y2: y2 + 0.5,
						},
					},
				},
			],
		}); 
	};

	return (
		<>
			<div id="main" style={{ width: 300, height: 300, display: "inline-block", border: "3px solid green" }}></div>
			<div
				style={{
					backgroundImage: `linear-gradient(${deg}deg, red, blue)`,
					width: 300,
					height: 300,
					display: "inline-block",
					border: "3px solid green",
					marginLeft: 12,
				}}
			></div>

			<div onMouseDown={onMouseDown} onMouseUp={onMouseUp} onMouseMove={onMouseMove} style={{ width: 300, height: 300, position: "relative", border: "3px solid green" }}>
				<div
					ref={pointArr}
					style={{
						position: "absolute",
						fontSize: 50,
						textAlign: "center",
						display: "flex",
						justifyContent: "center",
						alignContent: "center",
						left: "0px",
						right: "0px",
						top: "0px",
						bottom: "0px",
						margin: "auto",
						height: 60,
						width: 60,
						transform: `rotate(${deg - 90}deg)`,
					}}
				>
					<span>→</span>
				</div>
			</div> 
		</>
	);
}

export default App;


  • 13
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
CSS中,带有角度的变色表示为linear-gradient()函数,而在QSS中,变色通过QGradient对象来表示。因此,我们需要将CSS中的变色换成QSS中的QGradient对象。 以下是一个示例代码,可以将CSS中的变色字符串换成QGradient对象: ```python from PyQt5.QtGui import QColor, QGradient, QLinearGradient def css_gradient_to_qss(css_gradient): # 解析CSS字符串,获取变方向和颜色列表 parts = css_gradient.split(',') direction = parts[0].replace('linear-gradient(', '').strip() colors = [c.strip() for c in parts[1:]] # 将变方向换成QGradient的方向枚举 if 'deg' in direction: angle = int(direction.replace('deg', '').strip()) if angle > 90 and angle <= 180: direction = QGradient.LeftTop elif angle > 180 and angle <= 270: direction = QGradient.LeftBottom elif angle > 270 and angle <= 360: direction = QGradient.RightBottom else: direction = QGradient.RightTop else: direction = QGradient.DirectionFromString(direction) # 创建QGradient对象,添加颜色和位置信息 gradient = QLinearGradient() gradient.setStart(0, 0) gradient.setFinalStop(1, 1) for i, c in enumerate(colors): color = QColor(c) position = i / (len(colors) - 1) gradient.setColorAt(position, color) # 设置变方向 gradient.setCoordinateMode(QGradient.ObjectBoundingMode) gradient.setStart(0, 0) gradient.setFinalStop(1, 1) gradient.setAngle(direction) return gradient ``` 使用示例: ```python css_gradient = 'linear-gradient(45deg, red, blue)' qss_gradient = css_gradient_to_qss(css_gradient) ``` 这样就可以将CSS变色字符串换成QSS的QGradient对象了。需要注意的是,该函数只支持线性变,如果需要支持径向变或其他类型的变,需要进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小明IO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值