<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 13687字,需瀏覽 28分鐘

           ·

          2023-01-09 14:01

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

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

          你將收獲

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

          正文

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

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

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

          • Dooring無(wú)代碼搭建平臺(tái)技術(shù)演進(jìn)之路

          之所以要介紹低代碼的 schema 設(shè)計(jì), 是因?yàn)榈痛a組件的設(shè)計(jì)與開(kāi)發(fā)需要依賴(lài) schema 的定義, 為了滿(mǎn)足低代碼組件能被用戶(hù)實(shí)時(shí)編輯, 其基本的組成類(lèi)似如下:

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

          // 組件代碼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è)計(jì)模式之后, 我們接下來(lái)就來(lái)實(shí)現(xiàn)一下低代碼印章組件的實(shí)現(xiàn).

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

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

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

          接下來(lái)我們就來(lái)實(shí)現(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 方法來(lái)創(chuàng)建一個(gè)圓形邊框.

          2. 繪制五角星

          創(chuàng)建一個(gè)五角星形狀. 該五角星的中心坐標(biāo)為(x0, y0),中心到頂點(diǎn)的距離為 radius, rotate=0 時(shí)一個(gè)頂點(diǎn)在對(duì)稱(chēng)軸上

              function create5star(context: any,sx: number,sy: number,radius: number,color: string,rotato: number){
                  context.save();  
                  context.fillStyle=color;  
                  //移動(dòng)坐標(biāo)原點(diǎn)
                  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++){
                    //畫(huà)五角星的五條邊 
                   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. 繪制印章名稱(chēng)

          context.font = `${fontSize}px Helvetica`;
          //設(shè)置文本的垂直對(duì)齊方式
          context.textBaseline = 'middle';
          //設(shè)置文本的水平對(duì)對(duì)齊方式
          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(); 
                  // 平移到此位置,此時(shí)字和x軸垂直 
                  context.translate(900);
                  // 旋轉(zhuǎn)90度,讓字平行于x軸
                  context.rotate(Math.PI/2);
                  // 此點(diǎn)為字的中心點(diǎn) 
                  context.fillText(c, 020);  
                  context.restore();             
              }

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

          對(duì)于低代碼的 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零代碼搭建平臺(tái)',
              componySize18,
              text'H5-Dooring',
              fontSize14,
              color'rgba(240,0,0,1)',
              lineWidth6,
              opacity100
            },
          };

          export default List;

          快速將任意組件集成到低代碼平臺(tái)

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

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

          總結(jié)

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

          H5-dooring低代碼

          H5-dooring低代碼

          V6.Dooring可視化大屏搭建平臺(tái)

          V6.Dooring可視化大屏搭建平臺(tái)


          瀏覽 62
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  中文字幕在线观看不卡 | 无码人妻一区二区三区免费n鬼沢 | 日本中文不卡视频 | 亚洲欧美中文日韩在线观看 | 亚洲多毛 |