成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

設(shè)計(jì)一個(gè)基于svg的涂鴉組件(一)

cartoon / 3249人閱讀

摘要:基于寫了一個(gè)涂鴉組件,說項(xiàng)目之前先附上幾張效果圖項(xiàng)目地址由于篇幅問題,本文先總體介紹一下項(xiàng)目的大概情況,重點(diǎn)介紹一下組件間的通信方式。一項(xiàng)目說明該項(xiàng)目是基于構(gòu)建的多頁應(yīng)用,使用開發(fā),以組件的方式組織代碼。

基于svg寫了一個(gè)涂鴉組件,說項(xiàng)目之前先附上幾張效果圖:

項(xiàng)目地址:SVGraffiti

由于篇幅問題,本文先總體介紹一下項(xiàng)目的大概情況,重點(diǎn)介紹一下組件間的通信方式。

一、項(xiàng)目說明

該項(xiàng)目是基于[email protected]構(gòu)建的多頁應(yīng)用,使用ES6開發(fā),以組件的方式組織代碼。
git clone項(xiàng)目后(文末附上該項(xiàng)目github倉庫地址),npm i安裝相關(guān)依賴,npm run dev運(yùn)行項(xiàng)目,默認(rèn)會(huì)打開應(yīng)用的首頁,也就是上面的效果預(yù)覽對(duì)應(yīng)的界面。開發(fā)過程會(huì)多帶帶地為一些功能編寫一些測(cè)試代碼,所以該項(xiàng)目提供了不同的頁面對(duì)應(yīng)于不同的功能,比如:

color picker組件測(cè)試頁:

組件消息通信框架測(cè)試頁:

svg底層繪制api測(cè)試頁:

二、組件間通信

1、組件間為了實(shí)現(xiàn)最大程度的封裝與解耦,不直接進(jìn)行互相通信,而是通過“消息訂閱/發(fā)布管理中心”(以下簡稱“消息中心”)進(jìn)行間接通信。組件通過聲明自己為不同的角色從而擁有對(duì)應(yīng)的通信能力:

組件聲明為訂閱者(Subscriber)并通過@Topics注解的形式從“消息中心”訂閱自己感興趣的主題消息,對(duì)應(yīng)的消息會(huì)通過notify接口告知組件;

組件聲明為發(fā)布者(Publisher),可以通過Publisher角色注入的publish方法發(fā)布主題消息;

組件聲明為發(fā)布/訂閱者(SubScatterer),同時(shí)擁有訂閱者和發(fā)布者的通信能力。

這里以項(xiàng)目中的中間區(qū)域的畫板組件為例,因?yàn)楫嫲褰M件只是接收Toolbar組件發(fā)來的切換繪制能力、清空繪制內(nèi)容以及Settings組件發(fā)來的設(shè)置繪制參數(shù)信息,所以該組件只是一個(gè)消息訂閱者角色,編碼設(shè)計(jì)如下:

首先導(dǎo)入對(duì)應(yīng)的角色類:

import Subscriber from "../../supports/pubsub/base/subscriber";
import Topics from "../../supports/pubsub/base/topics";

編寫對(duì)應(yīng)的組件:

// 通過@Topics的形式訂閱感興趣的消息類型
@Topics(["function", "resident_function", "set_preference"])
export default class Sketchpad extends Subscriber {
    // 構(gòu)造器
    constructor(sketchpad) {
        super();
        this.sketchpad = sketchpad;
        // ...
    }
    
    /**
     * 該接口由【PubSub消息管理中心】負(fù)責(zé)調(diào)用,畫板組件在此接口處理接收到的消息類型
     * 1、處理Toolbar組件發(fā)送的 “切換畫板繪制狀態(tài)” ,對(duì)應(yīng)的消息類型為:“function”
     * 2、處理Toolbar組件發(fā)送的 “清空繪制內(nèi)容” ,對(duì)應(yīng)的消息類型為:“resident_function”
     * 3、處理Settings組件發(fā)送的 “設(shè)置畫板繪制參數(shù)” ,對(duì)應(yīng)的消息類型為:“set_preference”
     * @param {String} topic 消息主題標(biāo)識(shí)
     * @param {Object} entity 消息實(shí)體對(duì)象
     */
    notify(topic, entity) {
       // 在此處理接收到的消息
    }
}

注:@Topics是靜態(tài)的,若有些主題是需要運(yùn)行時(shí)訂閱也可以調(diào)用Subscriber角色提供的subscribe方法動(dòng)態(tài)訂閱消息。

2、PubSub(消息訂閱/發(fā)布管理中心)的實(shí)現(xiàn)
既然是底層通用能力就一定要實(shí)現(xiàn)的不帶任何具體的業(yè)務(wù),無論是在命名規(guī)范還是編碼實(shí)現(xiàn)上都要保證它是一個(gè)通用模塊

PubSub的實(shí)現(xiàn):

/**
 * 主題訂閱發(fā)布中心
 */
export default class PubSub {

    // 緩存主題和主題的訂閱者列表
    static topics = {};

    /**
     * 發(fā)布主題消息
     * @param {String} topic 主題
     * @param {*} entity 消息體 
     */
    static publish(topic, entity) {
        if (!PubSub.topics[topic]) return;

        // 獲取該主題的訂閱者列表
        const subscribers = PubSub.topics[topic];

        // 向所有該主題的訂閱者發(fā)送主題消息
        for (let subscriber of subscribers) {
            subscriber.notify && subscriber.notify(topic, entity);
        }
    }

    /**
     * 一次登記一個(gè)主題
     * @param {String} topic 
     */
    static registerTopic(topic) {
        const topics = PubSub["topics"];
        !topics[topic] && (topics[topic] = []);
    }

    /**
     * 同時(shí)登記多個(gè)主題
     * @param {Array} topics 
     */
    static registerTopics(topics = []) {
        topics.forEach(topic => {
            this.registerTopic(topic);
        });
    }

    /**
     * 添加主題訂閱者
     * @param {String} topic 主題
     * @param {Object} subscriber 實(shí)現(xiàn)了notify接口的訂閱者
     */
    static addSubscriber(topic, subscriber) {
        const topics = PubSub["topics"];
        !topics[topic] && (topics[topic] = []);

        // 將該主題的訂閱者登記到對(duì)應(yīng)的主題
        topics[topic].push(subscriber);
    }
    
    /**
     * 刪除對(duì)應(yīng)的訂閱者
     * @param subscriber 
     */
    static removeSubscriber(subscriber) {
        const subs = [];
        // 遍歷所有主題下的訂閱者列表,將對(duì)應(yīng)訂閱者刪除
        const topics = PubSub.topics;
        Object.keys(topics).forEach(topicName => {
            const topic = topics[topicName];
            for (let i = 0; i < topic.length; ++i) {
                if (topic[i] === subscriber) {
                    subs.push(topics[topic].splice(i, 1));
                    break;
                }
            }
        });
        return subs;
    }
}

Subscriber的實(shí)現(xiàn):

import PubSub from "../pubsub";

const addSubscribe = (topics = [], context) => {
    topics.forEach(topic => {
        PubSub.addSubscriber(topic, context);
    });
}

/**
 * 主題訂閱者
 */
export default class Subscriber {
    constructor() {
        addSubscribe(this.__proto__.constructor.topics, this);
    }

    subscribe(topic) {
        PubSub.addSubscriber(topic, this);
    }
}

為了方便訂閱主題,再提供一個(gè)@Topics注解:

import PubSub from "../pubsub";

/**
 * 訂閱者主題裝飾器
 * @param {Array} topics
 */
export default function Topics(topics) {
    return target => {
        target.topics = topics;
        PubSub.registerTopics(topics);
    }
}

Publisher的實(shí)現(xiàn):

import PubSub from "../pubsub";

/**
 * 主題消息發(fā)布者
 */
export default class Publisher {
    publish(topic, entity) {
        PubSub.publish(topic, entity);
    }
}

SubScatterer的實(shí)現(xiàn):

import PubSub from "../pubsub";
import Subscriber from "./subscriber";

/**
 * 主題訂閱者 and 主題消息發(fā)布者
 */
export default class SubScatterer extends Subscriber {
    publish(topic, entity) {
        PubSub.publish(topic, entity);
    }
}

本篇介紹了項(xiàng)目的大概情況,重點(diǎn)分析了如何以發(fā)布/訂閱的形式實(shí)現(xiàn)組件間的通信,接下來還會(huì)抽時(shí)間寫幾個(gè)篇分別介紹“svg底層繪制能力的封裝”、“畫板不同繪制狀態(tài)的實(shí)現(xiàn)與管理”、“如何開發(fā)一個(gè)通用的ColorPicker”等等與本項(xiàng)目相關(guān)的文章,寫得不好求親噴。

項(xiàng)目github地址:SVGraffiti

感興趣的同學(xué)們歡迎star一起交流。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/94972.html

相關(guān)文章

  • vue組件:canvas實(shí)現(xiàn)圖片涂鴉功能

    摘要:方案背景需求需要對(duì)圖片進(jìn)行標(biāo)注,導(dǎo)出圖片。對(duì)應(yīng)方案用實(shí)現(xiàn)涂鴉圓形矩形的繪制,最終生成圖片編碼用于上傳大量圖片批量上傳很耗時(shí)間,為了提高用戶體驗(yàn),改為只實(shí)現(xiàn)圓形矩形繪制,最終保存成坐標(biāo),下次顯示時(shí)根據(jù)坐標(biāo)再繪制。 方案背景 需求 需要對(duì)圖片進(jìn)行標(biāo)注,導(dǎo)出圖片。 需要標(biāo)注N多圖片最后同時(shí)保存。 需要根據(jù)多邊形區(qū)域數(shù)據(jù)(區(qū)域、顏色、名稱)標(biāo)注。 對(duì)應(yīng)方案 用canvas實(shí)現(xiàn)涂鴉、圓形、...

    roland_reed 評(píng)論0 收藏0
  • STM32CubeMX學(xué)習(xí)教程之硬件I2C讀取光照度

    摘要:使用庫讀寫環(huán)境光照度傳感器本文將教大家如何快速使用庫讀取光照度數(shù)據(jù)。五實(shí)驗(yàn)樣機(jī)測(cè)試展示通過之前配置好的面板,通過涂鴉智能進(jìn)行配網(wǎng)實(shí)時(shí)采集光照度傳感器的數(shù)據(jù)。 使用STM32 HAL庫讀寫環(huán)境光照度傳感器(BH1750) 本文將教大家如何快速使用STM32HAL庫讀取光照度數(shù)據(jù)。 實(shí)現(xiàn)功能:通...

    tinylcy 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<