1. 從零實現(xiàn)Dooring低代碼印章組件

        共 13687字,需瀏覽 28分鐘

         ·

        2023-01-09 14:01

        上一篇文章和大家分享了低代碼平臺組件間通信方案的幾種實現(xiàn):

        今天繼續(xù)和大家分享一下比較有意思的可視化印章組件的實現(xiàn).

        你將收獲

        • 低代碼組件的基本設(shè)計模式
        • 印章組件的設(shè)計原理(canvas相關(guān))
        • 如何快速將任意組件集成到低代碼平臺

        正文

        低代碼組件的基本設(shè)計模式

        我們都知道任何低代碼或者零代碼搭建產(chǎn)品都非常注重底層搭建協(xié)議(schema), 這些產(chǎn)品通常會設(shè)計一套向上兼容且可擴展的 DSL 結(jié)構(gòu), 來實現(xiàn)頁面元件的標(biāo)準(zhǔn)化配置, 并支持元件的向上擴展:

        在設(shè)計 H5-Dooring 可視化搭建平臺前, 我也參考了很多標(biāo)準(zhǔn)化軟件數(shù)據(jù)協(xié)議, 給我啟發(fā)最大的就是 ODATA 規(guī)范, 具體設(shè)計細節(jié)可以參考我之前的文章:

        • Dooring無代碼搭建平臺技術(shù)演進之路

        之所以要介紹低代碼的 schema 設(shè)計, 是因為低代碼組件的設(shè)計與開發(fā)需要依賴 schema 的定義, 為了滿足低代碼組件能被用戶實時編輯, 其基本的組成類似如下:

        我們只需要在寫普通組件的基礎(chǔ)上加一個 schema 文件即可, 這里以Dooring組件來舉一個例子:

        // 組件代碼tsx
        import styles from './index.less';
        import React, { memo, useState } from 'react';
        import { IHeaderConfig } from './schema';

        const Header = memo((props: IHeaderConfig) => {
          const { cpName, bgColor, logo, height } = props;

          return (
            <header className={styles.header} style={{ backgroundColor: bgColorheight: height + 'px' }}>
              <div className={styles.logo}>
                H5-dooring
              </div>
            </header>

          );
        });

        export default Header;


        // 組件樣式
        .header {
            box-sizing: content-box;
            padding: 3px 12px;
            background-color: #000;
            .logo {
              max-width: 160px;
              overflow: hidden;
              img {
                height100%;
                object-fit: contain;
              }
            }
          }

        // 組件schema
        const Header = {
              editData: [
                ...baseConfig,
                {
                  key'bgColor',
                  name: 背景色,
                  type'Color',
                },
                {
                  key'height',
                  name: 高,
                  type'Number',
                },
                {
                  key'logo',
                  name'logo',
                  type'Upload',
                  isCropfalse,
                  cropRate1000 / 618,
                }
              ],
              config: {
                ...baseDefault,
                bgColor'rgba(245,245,245,1)',
                logo: [
                  {
                    uid'001',
                    name'image.png',
                    status'done',
                    url'http://cdn.dooring.cn/dr/logo.ff7fc6bb.png',
                  },
                ],
                height50,
              },
            };
            
        export default Header;

        在初步了解了低代碼組件的設(shè)計模式之后, 我們接下來就來實現(xiàn)一下低代碼印章組件的實現(xiàn).

        印章組件的設(shè)計原理

        我們由上圖可以看出, 一個印章組件包含如下幾個部分:

        對于印章的繪制, 我們可以采用 canvas 或者 svg 來實現(xiàn), 這里我采用 canvas 來實現(xiàn), 首先我們需要定義組件可以對外暴露的屬性, 以便在低代碼平臺中可以讓用戶來自定義, 這里我直接列出基本的配置:

        接下來我們就來實現(xiàn)一下吧!

        1. 繪制印章邊框

        let canvas = dom; 
        let context = canvas.getContext('2d'as any;

        // 初始化
        canvas.width= w0;
        canvas.height = w0;

        // 繪制印章邊框   
        let width=canvas.width/2;
        let height=canvas.height/2;
        context.lineWidth= lineWidth;
        context.strokeStyle= color;
        context.beginPath();
        context.arc(width, height, width - lineWidth, 0Math.PI*2);
        context.stroke();

        由上面代碼可知我們用 canvasarc 方法來創(chuàng)建一個圓形邊框.

        2. 繪制五角星

        創(chuàng)建一個五角星形狀. 該五角星的中心坐標(biāo)為(x0, y0),中心到頂點的距離為 radius, rotate=0 時一個頂點在對稱軸上

            function create5star(context: any,sx: number,sy: number,radius: number,color: string,rotato: number){
                context.save();  
                context.fillStyle=color;  
                //移動坐標(biāo)原點
                context.translate(sx,sy);  
                //旋轉(zhuǎn) 
                context.rotate(Math.PI+rotato); 
                //創(chuàng)建路徑 
                context.beginPath(); 
                let x = Math.sin(0);  
                let y= Math.cos(0);  
                let dig = Math.PI/5 *4;  
                for(let i = 0;i< 5;i++){
                  //畫五角星的五條邊 
                 let x = Math.sin(i*dig);  
                 let y = Math.cos(i*dig);  
                 context.lineTo(x*radius,y*radius);  
                }   
                context.closePath();  
                context.stroke();  
                context.fill();  
                context.restore();  
            }

        3. 繪制印章名稱

        context.font = `${fontSize}px Helvetica`;
        //設(shè)置文本的垂直對齊方式
        context.textBaseline = 'middle';
        //設(shè)置文本的水平對對齊方式
        context.textAlign = 'center'
        context.lineWidth=1;
        context.fillStyle = color;
        context.fillText(name,width,height+60);

        4. 繪制環(huán)形印章單位

        // 平移到此位置
        context.translate(width,height);
            context.font = `${componySize}px Helvetica`
            let count = company.length;// 字?jǐn)?shù)   
            let angle = 4*Math.PI/(3*(count - 1));// 字間角度   
            let chars = company.split("");   
            let c;
            for (let i = 0; i < count; i++){
                // 需要繪制的字符
                c = chars[i];   
                if(i==0)
                    context.rotate(5*Math.PI/6);
                else
                  context.rotate(angle);
                context.save(); 
                // 平移到此位置,此時字和x軸垂直 
                context.translate(900);
                // 旋轉(zhuǎn)90度,讓字平行于x軸
                context.rotate(Math.PI/2);
                // 此點為字的中心點 
                context.fillText(c, 020);  
                context.restore();             
            }

        在基本的印章實現(xiàn)之后, 我們來接收屬性配置:

        對于低代碼的 schema 配置, 這里以 H5-Dooring 的組件為例, 給大家分享一下:

        import {
          IColorConfigType,
          IDataListConfigType,
          INumberConfigType,
          ISelectConfigType,
          TColorDefaultType,
          ISwitchConfigType,
          ITextConfigType,
          TNumberDefaultType,
          TTextDefaultType,
        from '@/core/FormComponents/types';
        import { ICommonBaseType, baseConfig, baseDefault } from '../../common';
        import intl from '@/utils/intl';

        const t = intl();
        export type TTextSelectKeyType = 'left' | 'right' | 'center';
        export type TTextPosSelectKeyType = 'bottom' | 'top';
        export type TTextFormatSelectKeyType = 'CODE128' | 'pharmacode'
        export type TListEditData = Array<
          IColorConfigType | 
          IDataListConfigType | 
          INumberConfigType | 
          ISelectConfigType<TTextSelectKeyType> | 
          ISelectConfigType<TTextPosSelectKeyType> |
          ISelectConfigType<TTextFormatSelectKeyType> |
          ISwitchConfigType | 
          ITextConfigType 
        >;
        export interface IListConfig extends ICommonBaseType {
          width: TNumberDefaultType;
          compony: TTextDefaultType;
          componySize: TNumberDefaultType;
          text: TTextDefaultType;
          fontSize: TNumberDefaultType;
          color: TColorDefaultType;
          lineWidth: TNumberDefaultType;
          opacity: TNumberDefaultType;
        }

        export interface IListSchema {
          editData: TListEditData;
          config: IListConfig;
        }

        const List: IListSchema = {
          editData: [
            ...baseConfig,
            {
              key'width',
              name: t('dr.attr.sealSize'),
              type'Number',
            },
            {
              key'compony',
              name: t('dr.attr.componyName'),
              type'Text',
            },
            {
              key'componySize',
              name: t('dr.attr.componySize'),
              type'Number',
            },
            {
              key'text',
              name: t('dr.attr.sealUnit'),
              type'Text',
            },
            {
              key'fontSize',
              name: t('dr.attr.fontSize'),
              type'Number',
            },
            {
              key'color',
              name: t('dr.attr.color'),
              type'Color',
            },
            {
              key'lineWidth',
              name: t('dr.attr.lineWidth'),
              type'Number',
            },
            {
              key'opacity',
              name: t('dr.attr.opacity'),
              type'Number',
            },
          ],
          config: {
            ...baseDefault,
            cpName'Seal',
            width180,
            compony'Dooring零代碼搭建平臺',
            componySize18,
            text'H5-Dooring',
            fontSize14,
            color'rgba(240,0,0,1)',
            lineWidth6,
            opacity100
          },
        };

        export default List;

        快速將任意組件集成到低代碼平臺

        在上面的分析實現(xiàn)中我們可以發(fā)現(xiàn), 只需要把普通組件按照屬性對外暴露出來, 并按照 Dooringschema 定義模式來描述出來, 普通組件就可以立馬變成低代碼組件, 并自動生成組件配置面板:

        具體的 schema 描述我在文檔中做了詳細的介紹, 大家感興趣可以參考一下:

        總結(jié)

        后續(xù)我會繼續(xù)和大家分享一下 H5-Dooring 低代碼的更多實踐和思考, 如果大家對可視化低代碼感興趣也可以參考我的低代碼可視化專欄, 如果大家對圖形學(xué)感興趣, 也可以參考我的專欄100+前端幾何學(xué)應(yīng)用案例.

        H5-dooring低代碼

        H5-dooring低代碼

        V6.Dooring可視化大屏搭建平臺

        V6.Dooring可視化大屏搭建平臺


        瀏覽 62
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 国产 在线观看免费视频 | 午夜无码福利 | 亚洲春色在线视频 | 99中文视频 | 男女在线观看免费视频 |