|
|
@@ -13,9 +13,241 @@ interface SunsetProps {
|
|
|
export default function SunsetCanvas({ sunset = "16:20", sunrise = "07:41", width = 600, height = 300 }: SunsetProps) {
|
|
|
useEffect(() => {
|
|
|
// drawSunsetCanvas()
|
|
|
- initCanvas()
|
|
|
+ initCanvas3()
|
|
|
+ // animationCanvas()
|
|
|
}, [sunset, sunrise])
|
|
|
|
|
|
+ function animationCanvas() {
|
|
|
+ const query = Taro.createSelectorQuery();
|
|
|
+ query.select(`#sunsetCanvas`).fields({ node: true, size: true });
|
|
|
+ query.exec((res) => {
|
|
|
+ const canvas = res[0].node;
|
|
|
+ const ctx = canvas.getContext('2d');
|
|
|
+
|
|
|
+ const width = res[0].width;
|
|
|
+ const height = res[0].height;
|
|
|
+
|
|
|
+ const dpr = Taro.getSystemInfoSync().pixelRatio;
|
|
|
+ canvas.width = width * dpr;
|
|
|
+ canvas.height = height * dpr;
|
|
|
+ ctx.scale(dpr, dpr);
|
|
|
+
|
|
|
+ const amplitude = (2 / 3) * 50; // 振幅为 (2/3) * 50
|
|
|
+ const frequency = 1; // 频率
|
|
|
+ const offsetY = height / 2; // Y 轴偏移
|
|
|
+ const startX = -Math.PI; // x 起始值
|
|
|
+ const endX = Math.PI; // x 结束值
|
|
|
+ let phase = 0; // 相位
|
|
|
+
|
|
|
+ const draw = () => {
|
|
|
+ // 清空画布
|
|
|
+ ctx.clearRect(0, 0, width, height);
|
|
|
+
|
|
|
+ // 设置背景颜色
|
|
|
+ ctx.fillStyle = '#F0F0F0';
|
|
|
+ ctx.fillRect(0, 0, width, height);
|
|
|
+
|
|
|
+ // 绘制坐标轴
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.moveTo(0, offsetY); // X 轴
|
|
|
+ ctx.lineTo(width, offsetY);
|
|
|
+ ctx.moveTo(width / 2, 0); // Y 轴
|
|
|
+ ctx.lineTo(width / 2, height);
|
|
|
+ ctx.strokeStyle = '#000';
|
|
|
+ ctx.lineWidth = 1;
|
|
|
+ ctx.stroke();
|
|
|
+ // 填充 x < 0 && y < 0 的区域为红色
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.moveTo(((startX - startX) / (endX - startX)) * width, offsetY); // 起点:x=-π, y=offsetY
|
|
|
+
|
|
|
+ for (let x = startX; x <= 0; x += 0.01) {
|
|
|
+ const pixelX = ((x - startX) / (endX - startX)) * width; // 将 x 映射到 Canvas 宽度
|
|
|
+ const y = amplitude * Math.sin(frequency * x + phase) + offsetY; // 计算 y 值
|
|
|
+ if (y < offsetY) {
|
|
|
+ ctx.lineTo(pixelX, y);
|
|
|
+ } else {
|
|
|
+ ctx.lineTo(pixelX, offsetY);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 闭合路径
|
|
|
+ ctx.lineTo(((0 - startX) / (endX - startX)) * width, offsetY); // 终点:x=0, y=offsetY
|
|
|
+ ctx.closePath();
|
|
|
+ // 填充红色
|
|
|
+ ctx.fillStyle = 'rgba(255, 0, 0, 0.3)'; // 半透明红色
|
|
|
+ ctx.fill();
|
|
|
+
|
|
|
+ // 绘制正弦曲线
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.moveTo(((startX - startX) / (endX - startX)) * width, offsetY);
|
|
|
+
|
|
|
+ for (let x = startX; x <= endX; x += 0.01) {
|
|
|
+ const pixelX = ((x - startX) / (endX - startX)) * width;
|
|
|
+ const y = amplitude * Math.sin(frequency * x + phase) + offsetY;
|
|
|
+ ctx.lineTo(pixelX, y);
|
|
|
+ }
|
|
|
+
|
|
|
+ ctx.strokeStyle = '#FF4500';
|
|
|
+ ctx.lineWidth = 2;
|
|
|
+ ctx.stroke();
|
|
|
+
|
|
|
+ // 更新相位
|
|
|
+ phase += 0.05;
|
|
|
+
|
|
|
+ // 请求下一帧
|
|
|
+ requestAnimationFrame(draw);
|
|
|
+ };
|
|
|
+
|
|
|
+ draw();
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ function initCanvas3() {
|
|
|
+ const query = Taro.createSelectorQuery();
|
|
|
+ query.select(`#sunsetCanvas`).fields({ node: true, size: true });
|
|
|
+ query.exec((res) => {
|
|
|
+ const canvas = res[0].node;
|
|
|
+ const ctx = canvas.getContext('2d');
|
|
|
+
|
|
|
+ const width = res[0].width; // Canvas 宽度
|
|
|
+ const height = res[0].height; // Canvas 高度
|
|
|
+
|
|
|
+ // 设置 Canvas 分辨率
|
|
|
+ const dpr = Taro.getSystemInfoSync().pixelRatio;
|
|
|
+ canvas.width = width * dpr;
|
|
|
+ canvas.height = height * dpr;
|
|
|
+ ctx.scale(dpr, dpr);
|
|
|
+
|
|
|
+ // 清空画布
|
|
|
+ ctx.clearRect(0, 0, width, height);
|
|
|
+
|
|
|
+ // 设置背景颜色
|
|
|
+ ctx.fillStyle = '#F0F0F0';
|
|
|
+ ctx.fillRect(0, 0, width, height);
|
|
|
+
|
|
|
+ // 绘制坐标轴
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.moveTo(0, height / 2); // X 轴
|
|
|
+ ctx.lineTo(width, height / 2);
|
|
|
+ ctx.moveTo(width / 2, 0); // Y 轴
|
|
|
+ ctx.lineTo(width / 2, height);
|
|
|
+ ctx.strokeStyle = '#000';
|
|
|
+ ctx.lineWidth = 1;
|
|
|
+ ctx.stroke();
|
|
|
+
|
|
|
+ // 绘制正弦曲线 (4/5) * sin(x),x 范围为 -π 到 π
|
|
|
+ const amplitude = (4 / 5) * 50; // 振幅为 (2/3) * 50
|
|
|
+ const frequency = 1; // 频率
|
|
|
+ const offsetY = height / 2; // Y 轴偏移
|
|
|
+ const startX = -Math.PI; // x 起始值
|
|
|
+ const endX = Math.PI; // x 结束值
|
|
|
+
|
|
|
+ // 填充 x >= 0 && x <= (4/5) * π && y >= 0 的区域为绿色
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.moveTo(((0 - startX) / (endX - startX)) * width, offsetY); // 起点:x=0, y=offsetY
|
|
|
+
|
|
|
+ const leftPath = 1/2
|
|
|
+ for (let x = 0; x <= leftPath * Math.PI; x += 0.01) {
|
|
|
+ const pixelX = ((x - startX) / (endX - startX)) * width; // 将 x 映射到 Canvas 宽度
|
|
|
+ const y = amplitude * Math.sin(frequency * x) + offsetY; // 计算 y 值
|
|
|
+ if (y >= offsetY) {
|
|
|
+ ctx.lineTo(pixelX, y);
|
|
|
+ } else {
|
|
|
+ ctx.lineTo(pixelX, offsetY);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 闭合路径
|
|
|
+ ctx.lineTo(((leftPath * Math.PI - startX) / (endX - startX)) * width, offsetY); // 终点:x=(2/3)*π, y=offsetY
|
|
|
+ ctx.closePath();
|
|
|
+
|
|
|
+ // 填充绿色
|
|
|
+ ctx.fillStyle = 'rgb(70,70,70)'; // 半透明绿色
|
|
|
+ ctx.fill();
|
|
|
+
|
|
|
+ // 绘制正弦曲线
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.moveTo(((startX - startX) / (endX - startX)) * width, offsetY);
|
|
|
+ for (let x = startX; x <= endX; x += 0.01) {
|
|
|
+ const pixelX = ((x - startX) / (endX - startX)) * width;
|
|
|
+ const y = amplitude * Math.sin(frequency * x) + offsetY;
|
|
|
+ ctx.lineTo(pixelX, y);
|
|
|
+ }
|
|
|
+
|
|
|
+ ctx.strokeStyle = 'rgb(170,170,170)';
|
|
|
+ ctx.lineWidth = 1;
|
|
|
+ ctx.stroke();
|
|
|
+ ctx.restore();
|
|
|
+
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.arc(((leftPath * Math.PI - startX) / (endX - startX)) * width, amplitude * Math.sin(frequency * leftPath * Math.PI) + offsetY, 2, 0, 2 * Math.PI);
|
|
|
+ ctx.lineWidth = 2;
|
|
|
+ ctx.strokeStyle ='red'
|
|
|
+ ctx.fillStyle = 'red'
|
|
|
+ ctx.fill()
|
|
|
+ ctx.stroke();
|
|
|
+ ctx.restore();
|
|
|
+
|
|
|
+
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ function initCanvas2() {
|
|
|
+ const query = Taro.createSelectorQuery();
|
|
|
+ query.select(`#sunsetCanvas`).fields({ node: true, size: true });
|
|
|
+ query.exec((res) => {
|
|
|
+ const canvas = res[0].node;
|
|
|
+ const ctx = canvas.getContext('2d');
|
|
|
+
|
|
|
+ const width = res[0].width; // Canvas 宽度
|
|
|
+ const height = res[0].height; // Canvas 高度
|
|
|
+
|
|
|
+ // 设置 Canvas 分辨率
|
|
|
+ const dpr = Taro.getSystemInfoSync().pixelRatio;
|
|
|
+ canvas.width = width * dpr;
|
|
|
+ canvas.height = height * dpr;
|
|
|
+ ctx.scale(dpr, dpr);
|
|
|
+
|
|
|
+ // 清空画布
|
|
|
+ ctx.clearRect(0, 0, width, height);
|
|
|
+
|
|
|
+ // 设置背景颜色
|
|
|
+ ctx.fillStyle = '#F0F0F0';
|
|
|
+ ctx.fillRect(0, 0, width, height);
|
|
|
+ // 绘制坐标轴
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.moveTo(0, height / 2); // X 轴
|
|
|
+ ctx.lineTo(width, height / 2);
|
|
|
+ ctx.moveTo(width / 2, 0); // Y 轴
|
|
|
+ ctx.lineTo(width / 2, height);
|
|
|
+ ctx.strokeStyle = '#000';
|
|
|
+ ctx.lineWidth = 1;
|
|
|
+ ctx.stroke();
|
|
|
+
|
|
|
+ // 绘制正弦曲线 (2/3) * sin(x),x 范围为 -2π 到 0
|
|
|
+ //从波峰到波峰 amplitude为正,波谷到波谷 amplitude为负
|
|
|
+ const amplitude = -(2 / 3) * 50; // 振幅为 (2/3) * 50
|
|
|
+ const frequency = 1; // 频率
|
|
|
+ const offsetY = height / 2; // Y 轴偏移
|
|
|
+
|
|
|
+ const startX = -1 / 2 * Math.PI; // x 起始值
|
|
|
+ const endX = 3 / 2 * Math.PI; // x 结束值
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ ctx.beginPath();
|
|
|
+
|
|
|
+ for (let x = startX; x <= endX; x += 0.01) {
|
|
|
+ const pixelX = ((x - startX) / (endX - startX)) * width; // 将 x 映射到 Canvas 宽度
|
|
|
+ const y = amplitude * Math.sin(frequency * x) + offsetY;
|
|
|
+ ctx.lineTo(pixelX, y);
|
|
|
+ }
|
|
|
+ ctx.strokeStyle = '#FF4500';
|
|
|
+ ctx.lineWidth = 2;
|
|
|
+ ctx.stroke();
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
function initCanvas() {
|
|
|
const query = Taro.createSelectorQuery();
|
|
|
query.select(`#sunsetCanvas`).fields({ node: true, size: true });
|