美文网首页
线性渐变设计方案

线性渐变设计方案

作者: 豪爵吸金ing | 来源:发表于2021-06-20 22:19 被阅读0次

    线性渐变

    image

    线性渐变数据格式

    expendProperties

    
    /**
     * @description 渐变
     */
    interface LinePoint {
      // 颜色
      color: Number;
      // 位置
      position: Number;
    }
    /**
     * @description 直线渐变位置
     */
    interface LinePosition {
      x: number;
      y: number;
    }
    
    interface ColorItem {
      // 渐变
      line?: LinePoint[];
      // 直线渐变位置信息
      position?: LinePosition[];
    
    

    BasicState

      // 当前编辑模式, linear,image ...
      viewmode: String;
      // 当前编辑选中点信息
      viewindex: number;
    
    

    数据格式说明

    position 存放渐变的开始结束位置:2个点信息,相对位置

    line存放渲染颜色信息以及位置(0-1)

    基础属性

    interface BasicState {
      // 当前选择模式 钢笔模式涉及字段为6
      mode: String;
      // 视图模式 新增编辑模式
      viewMode: Number;
      viewModeFillId: String;
      // canvas高度
      height: Number;
      // canvas宽度
      width: Number;
      // 背景颜色
      pagebkcolor: -1;
      pagebkvisible: boolean;
      // 图层缩放比例
      scale: Number;
      // 光标类型 钢笔模式涉及字段为2
      cursorType: Number;
      // 光标角度
      cursorAngle: Number;
      // 图层选择ids
      selectIds: Array<String>;
      // 图层hoverId
      hoverId: String;
      // 编辑模式 新增 kSET_Select=0,kSET_Pen=1,kSET_Control=2,kSET_FillMode=3,
      editMode: number;
      // 水平滚轮定位左 @todo 待给出
      xSacleLeft: Number;
      // 水平滚轮定位右 @todo 待给出
      xSacleRight: Number;
      // 垂直滚轮定位左 @todo 待给出
      ySacleUp: Number;
      // 垂直滚轮定位下 @todo 待给出
      ySacleDown: Number;
      // 是否显示多人光标 字段前端维护
      showCoordination: Boolean;
      // 是否显示网格
      gridVisible: Boolean;
      // 是否显示标尺
      rulerVisible: Boolean;
      // 是否网格对齐
      gridAlign: Boolean;
      // 是否打开colorpicker
      colorPicker: Boolean;
    }
    
    

    数据计算公式

    坐标变换

    image

    Position 存放相对图层坐标

    计算如下:

    比如:图层世界坐标:p(x,y) 宽度为:w, 高度:h

    Position: 开始点为: start(x1,y1), end(x2,y2)

    世界位置到相对位置变换矩阵为:matrix

    1/w, 0, -x/w

    0, 1/h, -y/h

    0, 0, 1

    例如:

    (x,y,1) * matrix = (0,0,1)

    (x+w,y+h,1)* matrix = (1,1,1)

    (x+w/2,y+h/2,1)*matrix = (0.5,0.5,1)

    相对位置到世界位置变换矩阵为:matrix1

    w, 0, x

    0, h, y

    0, 0, 1

    例如:

    (0,0,1) * matrix1 = (x,y,1)

    (1,1,1)* matrix1 = (x+w,y+h,1)

    (0.5,0.5,1)*matrix1 = ((x+w/2,y+h/2,1)

    css样式计算

    角度计算:

    第一步: 把position相对坐标乘以matrix1变换为世界坐标

    得到p1,p2点

    第二步计算角度

      let x = p2.x - p1.x;
      let y = p2.y - p1.y;
      let res = (Math.atan2(y, x) * 180) / Math.PI + 90;
      if (res < 0) {
        res += 360;
      }
    
    

    第三步计算图层4个角到渐变色直线的交点

    计算公式为:

    // 计算点到直线的垂线交点
    function linecross(line: any, point: any) {
      let p1 = line[0];
      let p2 = line[1];
      // 90度
      if (p1.x == p2.x) {
        return {
          x: p1.x,
          y: point.y
        };
      } else {
        //斜率
        let k1 = (p2.y - p1.y) / (p2.x - p1.x);
        let k2 = -1 / k1;
        let x = (p1.y - point.y - (k1 * p1.x - k2 * point.x)) / (k2 - k1);
        let y = k1 * (x - p1.x) + p1.y;
        return { x, y };
      }
    }
    
    

    第四步计算各个点距离0点的距离

    function distance(p1: any, p2: any) {
      let k = (p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y);
      k = Math.sqrt(k);
      if (p1.x < p2.x) {
        k = -k;
      }
      if (p1.x == p2.x && p1.y < p2.y) {
        k = -k;
      }
      return k;
    }
    
    

    最后一步计算比例

    // 计算比例 p1 0 p2 100 p3 要计算的点
    function caluPer(p1: any, p2: any, p3: any) {
      let d1 = distance(p2, p1);
      let d2 = distance(p3, p1);
      return d2 / d1;
    }
    
    

    补充

    javscript矩阵乘法:

    function matrixMul(a, b) {
      const c = new Array(a.length);
      for (let i = 0; i < a.length; i++) {
        c[i] = new Array(b[0].length);
        for (let j = 0; j < b[0].length; j++) {
          c[i][j] = 0;
          for (let k = 0; k < b.length; k++) {
            c[i][j] += a[i][k] * b[k][j];
          }
        }
      }
      return c;
    }
    
    

    线性变换旋转90(p1. 开始点,p2 结束点)

    // 获取中点
    let dx = (p1.x + p2.x) / 2;
    let dy = (p1.y + p2.y) / 2;    
    let mx = [
          [1, 0, -dx],
          [0, 1, -dy],
          [0, 0, 1]
        ];
    p1 = matrixMul(mx, p1);
    p2 = matrixMul(mx, p2);
    mx = [
          [0, 1, 0],
          [-1, 0, 0],
          [0, 0, 1]
        ];
    p1 = matrixMul(mx, p1);
    p2 = matrixMul(mx, p2);
    
    // p1,p2 为旋转后的位置
    
    

    相关文章

      网友评论

          本文标题:线性渐变设计方案

          本文链接:https://www.haomeiwen.com/subject/ohjkkltx.html