адрес демо-версии react-slider-vertify:react-slider-vertify
Примечание: ⚠️Эта статья является первой подписанной статьей сообщества Nuggets, и её перепечатка без разрешения запрещена.
делился раньшенизкий кодивизуализация, которая включает в себя много интересных моментов знаний и дизайнерских идей.Сегодня я продолжу делиться с вами очень интересным и практичным фронтовым боевым проектом - на основе нуляreact + canvasРеализуйте прокрутку капчи и опубликуйте ее наnpm
для использования другими. Конечно, если вы предпочитаетеvue
Не беспокойтесь о методе разработкиvue
компоненты и публиковать вnpm
Вы также можете обратиться к моей предыдущей статье:Научу разрабатывать библиотеку компонентов на основе vue с нуля до единицы.
Из этого практического проекта мы можем извлечь следующие знания:
- Базовые идеи и навыки разработки интерфейсных компонентов
- Базовые знания и использование холста
- Базовые знания и использование хуков реакции
- Основной принцип построения скользящего проверочного кода
- Как упаковать компонент расширяемого скользящего кода подтверждения
- Как использовать dumi для создания документации по компонентам
- Как опубликовать свой первый пакет npm
Если вас интересует какой-либо из вышеперечисленных пунктов знаний, я считаю, что эта статья вдохновит вас.
Демонстрация эффекта
Базовое использование и техническая реализация компонентов скользящей проверки
На приведенном выше рисунке показана демонстрация эффекта реализованного компонента скользящей проверки.Конечно, есть много элементов конфигурации на выбор, чтобы поддерживать большеНастройкаместо действия. Далее я сначала расскажу, как установить и использовать этот подключаемый модуль кода подтверждения, чтобы у вас был интуитивно понятный опыт, а затем я подробно представлю идеи реализации скользящего кода подтверждения.Если у вас есть определенная техническая база, вы также можете сразу перейти к части технической реализации.
основное использование
так какreact-slider-vertify
Я выпустил этот компонент дляnpm
поэтому вы можете установить и использовать его следующим образом:
- Установить
# 或者 yarn add @alex_xu/react-slider-vertify
npm i @alex_xu/react-slider-vertify -S
- использовать
import React from 'react';
import { Vertify } from '@alex_xu/react-slider-vertify';
export default () => {
return <Vertify
width={320}
height={160}
onSuccess={() => alert('success')}
onFail={() => alert('fail')}
onRefresh={() => alert('refresh')}
/>
};
Выполнив два вышеуказанных шага, мы можем легко использовать этот компонент скользящего кода подтверждения, это очень просто?
Конечно, я также предоставил множество настраиваемых свойств, чтобы дать вам лучший контроль над компонентами. Ссылка выглядит следующим образом:
Техническая реализация
Прежде чем заняться этим проектом, я также изучил некоторые знания о скользящем коде подтверждения и существующих технических решениях и многому научился. Далее я познакомлю вас с тем, как использовать мои идеи дизайна компонентов.react
Чтобы реализовать и инкапсулировать компонент скользящего кода подтверждения, если у вас есть лучшие идеи и предложения, вы также можете в любое время оставить отзыв в области комментариев.
1. Идеи и навыки компонентного дизайна
У каждого свой способ и стиль проектирования компонентов, но конечная цель состоит в том, чтобы быть болеемилостьмилостьМетрики проектирования компонентов:
-
удобочитаемость(Формат кода унифицирован, аннотация полная, структура кода четкая, используется парадигма программирования)
-
Доступность(Код полностью функционален, хорошо совместим в разных сценариях, покрытие бизнес-логики)
-
возможность повторного использования(Код может быть повторно использован другими бизнес-модулями)
-
ремонтопригодность(Код прост в обслуживании и расширении, с некоторой обратной/нисходящей совместимостью)
-
высокая производительность
Выше приведены соображения для моих собственных компонентов дизайна, вы можете обратиться к ним.
Кроме того, нам необходимо уточнить требования перед проектированием компонентов.В качестве примера возьмем компонент скользящего кода проверки, нам нужно знать сценарии его использования (Служба человеко-машинной проверки для бизнес-сценариев с высоким риском, таких как регистрация входа, события, форумы и SMS.) и требования (Логика взаимодействия, как проверить, какие свойства нужно выставить).
Вышеизложенное является общим требованием к разработке компонентов, с которым я разобрался.Перед разработкой конкретных компонентов, если мы столкнемся со сложной бизнес-логикой, мы также можем перечислить каждый шаг реализации, а затем реализовать их один за другим, что поможет организовать наши идеи. более эффективное развитие.
2. Основной принцип реализации скользящего проверочного кода
После ознакомления с идеями проектирования компонентов и анализа требований давайте взглянем на принцип реализации кода скользящей проверки.
Мы все знаем, что основная цель разработки проверочных кодов — предотвратить незаконное и насильственное вторжение машин в наши приложения.Определите, кто управляет приложением(люди or машина), поэтому обычное решениеслучайная идентификация.
На приведенном выше рисунке мы видим, что проверка проходит успешно только в том случае, если пользователь вручную перетаскивает ползунок в соответствующую пустую область, а положение пустой области является случайным (проверка случайности временно реализована во внешнем интерфейсе, и более безопасный способ - передать бэкэнд, чтобы вернуть местоположение и изображение).
Основываясь на приведенном выше анализе, мы можем нарисовать базовую принципиальную схему разработки скользящего кода проверки:
Далее мы упакуем вместе этот масштабируемый компонент кода скользящей проверки.
3. Инкапсулируйте расширяемый компонент скользящего кода проверки
Согласно моему обычному стилю разработки компонентов, я сначала напишу базовый фреймворк компонентов на основе требований:
import React, { useRef, useState, useEffect, ReactNode } from 'react';
interface IVertifyProp {
/**
* @description canvas宽度
* @default 320
*/
width:number,
/**
* @description canvas高度
* @default 160
*/
height:number,
/**
* @description 滑块边长
* @default 42
*/
l:number,
/**
* @description 滑块半径
* @default 9
*/
r:number,
/**
* @description 是否可见
* @default true
*/
visible:boolean,
/**
* @description 滑块文本
* @default 向右滑动填充拼图
*/
text:string | ReactNode,
/**
* @description 刷新按钮icon, 为icon的url地址
* @default -
*/
refreshIcon:string,
/**
* @description 用于获取随机图片的url地址
* @default https://picsum.photos/${id}/${width}/${height}, 具体参考https://picsum.photos/, 只需要实现类似接口即可
*/
imgUrl:string,
/**
* @description 验证成功回调
* @default ():void => {}
*/
onSuccess:VoidFunction,
/**
* @description 验证失败回调
* @default ():void => {}
*/
onFail:VoidFunction,
/**
* @description 刷新时回调
* @default ():void => {}
*/
onRefresh:VoidFunction
}
export default ({
width = 320,
height = 160,
l = 42,
r = 9,
imgUrl,
text,
refreshIcon = 'http://yourimgsite/icon.png',
visible = true,
onSuccess,
onFail,
onRefresh
}: IVertifyProp) => {
return <div className="vertifyWrap">
<div className="canvasArea">
<canvas width={width} height={height}></canvas>
<canvas className="block" width={width} height={height}></canvas>
</div>
<div className={sliderClass}>
<div className="sliderMask">
<div className="slider">
<div className="sliderIcon">→</div>
</div>
</div>
<div className="sliderText">{ textTip }</div>
</div>
<div className="refreshIcon" onClick={handleRefresh}></div>
<div className="loadingContainer">
<div className="loadingIcon"></div>
<span>加载中...</span>
</div>
</div>
}
Выше приведена базовая структура фрейма наших компонентов. Из кода видно, что свойства компонента понятны с первого взгляда, что является преимуществом предварительной организации требований, что позволяет нам более четко мыслить при написании компонентов. написание основныхcss
Интерфейс, который мы видим после стилизации, выглядит так:
Далее нам нужно реализовать следующие основные функции:
- эффект пустоты
canvas
реализация изображения - ажурный узор
canvas
выполнить - Движение ползунка и реализация логики проверки
Приведенное выше описание может быть абстрактным, поэтому позвольте мне нарисовать картинку для иллюстрации:
Поскольку реализация компонента полностью принимаетreact hooks
, если все правыhooks
Если вы не знакомы с ним, вы также можете обратиться к моей предыдущей статье:
1. Для достижения эффекта пустотыcanvas
рисунок
В началеcodingПрежде чем нам нужноcanvas
Существует базовое понимание, рекомендуется, чтобы незнакомые друзья могли обратиться к эффективнымcanvasУчебные документы:Canvas of MDN.
Как видно из рисунка выше, первая проблема, которую нужно решить, это как использоватьcanvasЧтобы нарисовать неправильные формы, здесь я просто рисую набросок:
нам просто нужно использоватьcanvasкоторый предоставилпуть APIНарисуйте путь, показанный выше, и залейте путь любым полупрозрачным цветом. Рекомендуется, чтобы, если вы не знакомы с ним, вы могли сначала понять следующееapi :
- beginPath() запускает отрисовку пути
- moveTo() перемещает штрих в указанную точку
- arc() рисует дугу
- lineTo() рисовать линию
- ход() ход
- заполнить () заполнить
- clip() обтравочный контур
Метод реализации выглядит следующим образом:
const drawPath = (ctx:any, x:number, y:number, operation: 'fill' | 'clip') => {
ctx.beginPath()
ctx.moveTo(x, y)
ctx.arc(x + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI)
ctx.lineTo(x + l, y)
ctx.arc(x + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI)
ctx.lineTo(x + l, y + l)
ctx.lineTo(x, y + l)
// anticlockwise为一个布尔值。为true时,是逆时针方向,否则顺时针方向
ctx.arc(x + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true)
ctx.lineTo(x, y)
ctx.lineWidth = 2
ctx.fillStyle = 'rgba(255, 255, 255, 0.8)'
ctx.strokeStyle = 'rgba(255, 255, 255, 0.8)'
ctx.stroke()
ctx.globalCompositeOperation = 'destination-over'
// 判断是填充还是裁切, 裁切主要用于生成图案滑块
operation === 'fill'? ctx.fill() : ctx.clip()
}
Эта реализация также относится к нативной версии Yield.js
Реализация, пункт, который необходимо добавить здесь, заключается в том, чтоcanvas
изglobalCompositeOperation
свойство, основной целью которого является установка способа рисования исходного (нового) изображения на целевом (существующем) изображении.
-
исходное изображение = рисунок, который мы собираемся разместить на холсте
-
целевое изображение = рисунок, который мы разместили на холсте
На w3c есть пример изображения:
Причина, по которой это свойство задано здесь, заключается в том, что на выдолбленную форму не влияет фоновая базовая карта, и она накладывается поверх фоновой базовой карты. следующее:
Далее нам просто нужно нарисовать изображение на холсте:
const canvasCtx = canvasRef.current.getContext('2d')
// 绘制镂空形状
drawPath(canvasCtx, 50, 50, 'fill')
// 画入图片
canvasCtx.drawImage(img, 0, 0, width, height)
Конечно, что касается того, как генерировать случайные картинки и случайные позиции, способ реализации тоже очень прост.Math.random
Вот и все.
2. Осознайте полый паттернcanvas
Полая форма реализована выше, тогда полый узор аналогичен, нам нужно только использоватьclip()
Метод Обрежьте изображение в маску формы и поместите полый узор в левой части холста. код показывает, как показано ниже:
const blockCtx = blockRef.current.getContext('2d')
drawPath(blockCtx, 50, 50, 'clip')
blockCtx.drawImage(img, 0, 0, width, height)
// 提取图案滑块并放到最左边
const y1 = 50 - r * 2 - 1
const ImageData = blockCtx.getImageData(xRef.current - 3, y1, L, L)
// 调整滑块画布宽度
blockRef.current.width = L
blockCtx.putImageData(ImageData, 0, y1)
Мы использовали код вышеgetImageData
иputImageData
, дваapiиспользуется в основном для полученияcanvas
Пиксельные данные сцены холста и запись пиксельных данных в сцену. Эффект после внедрения следующий:
3. Реализуйте логику движения ползунка и проверки
Решение для реализации движения ползунка также относительно простое, нам нужно только использовать мышь.event
События могут быть:
- onMouseDown
- onMouseMove
- onMouseUp
Выше приведена простая схематическая диаграмма, конкретный код реализации выглядит следующим образом:
const handleDragMove = (e) => {
if (!isMouseDownRef.current) return false
e.preventDefault()
// 为了支持移动端, 可以使用e.touches[0]
const eventX = e.clientX || e.touches[0].clientX
const eventY = e.clientY || e.touches[0].clientY
const moveX = eventX - originXRef.current
const moveY = eventY - originYRef.current
if (moveX < 0 || moveX + 36 >= width) return false
setSliderLeft(moveX)
const blockLeft = (width - l - 2r) / (width - l) * moveX
blockRef.current.style.left = blockLeft + 'px'
}
Конечно, нам также нужно отслеживать события после остановки перетаскивания, чтобы определить, прошла ли проверка успешно, и похоронить обратные вызовы успеха и неудачи. код показывает, как показано ниже:
const handleDragEnd = (e) => {
if (!isMouseDownRef.current) return false
isMouseDownRef.current = false
const eventX = e.clientX || e.changedTouches[0].clientX
if (eventX === originXRef.current) return false
setSliderClass('sliderContainer')
const { flag, result } = verify()
if (flag) {
if (result) {
setSliderClass('sliderContainer sliderContainer_success')
// 成功后的自定义回调函数
typeof onSuccess === 'function' && onSuccess()
} else {
// 验证失败, 刷新重置
setSliderClass('sliderContainer sliderContainer_fail')
setTextTip('请再试一次')
reset()
}
} else {
setSliderClass('sliderContainer sliderContainer_fail')
// 失败后的自定义回调函数
typeof onFail === 'function' && onFail()
setTimeout(reset.bind(this), 1000)
}
}
Эффект после внедрения следующий:
Конечно, есть еще некоторые детали, которые нужно оптимизировать, вотgithub
На нем есть полный код, вы можете обратиться к нему и изучить его.Если вы хотите внести свой вклад в этот компонент, вы также можете упомянуть его в любое время.issue
.
4. Как использовать dumi для создания документации по компонентам
Чтобы компоненты лучше понимались и использовались другими, мы можем создавать документацию по компонентам. Как фронтенд, который любит открытый исходный кодcoder, написание документации по компонентам также является хорошей привычкой разработчиков. Далее мы такжеreact-slider-vertifyНапишите компонентный документ, здесь я используюdumi
Конечно, для создания составных документов можно использовать и другие решения (например, сборник рассказов). Давайте посмотрим на эффект после строительства:
dumi
Собрать документацию по компоненту очень просто.Далее я расскажу вам, как ее установить и использовать.
- Установить
$ npx @umijs/create-dumi-lib # 初始化一个文档模式的组件库开发脚手架
# or
$ yarn create @umijs/dumi-lib
$ npx @umijs/create-dumi-lib --site # 初始化一个站点模式的组件库开发脚手架
# or
$ yarn create @umijs/dumi-lib --site
- работать локально
npm run dev
# or
yarn dev
- писать документацию
dumi
Условно определяет место и способ написания документа.На его официальном сайте также есть специальные вводные для еды.Вот краткое введение к предыдущему.dumi
Схема структуры каталогов встроенных компонентов:
мы можемdocs
Инструкции по написанию первой страницы и страницы руководства документации библиотеки компонентов ниже используются в папке одного компонента.index.md
Написать документацию по использованию самого компонента, конечно, весь процесс очень простой, вот пример документации:
этим способомdumi
Это может помочь нам автоматически отображать компонент с помощью документа. Если вы хотите узнать больше о содержании документации по компонентам, вы также можете посетитьdumi
Исследование на официальном сайте.
5. Опубликуйте свой первый пакет компонентов npm
Последняя проблема — публикация компонентов. Многие друзья спрашивали меня, как опубликовать мои компоненты вnpm
Пусть им воспользуется больше людей, в Интернете есть много информации, чтобы изучить этот фрагмент знаний, а затем используйте скользящий проверочный код сегодня.@alex_xu/react-slider-vertifyНапример, позвольте мне дать вам краткое введение.
- Имеется
npm
Учетная запись и вход
Если у вас нетnpm
счет, доступный по адресуофициальный сайт нпмПодпишитесь на один, затем используйте наш знакомыйIDEВход в терминал один раз:
npm login
После запроса на ввод имени пользователя и пароля мы можем опубликовать пакет компонента через командную строку:
npm publish --access public
Причина, по которой за командой следуетpublic
Этот параметр позволяет избежать проблем с разрешениями, из-за которых не удается успешно опубликовать пакет компонента. Чтобы избежать проблем, мы также можем настроить команду освобождения наpackage.json
, который автоматически публикуется после упаковки компонента:
{
"scripts": {
"start": "dumi dev",
"release": "npm run build && npm publish --access public",
}
}
Это позволяет нам легко публиковать наши компоненты вnpm
Он доступен для использования другими! Я также открыл исходный код многих библиотек компонентов ранее. Если у вас есть какие-либо вопросы о деталях упаковки компонентов и процессе создания, вы также можете обратиться к моим предыдущим решениям проекта с открытым исходным кодом. Опубликовать вnpm
После эффекта:
Наконец
Если вы заинтересованы в визуальном конструировании или low-code/zero-code, вы также можете обратиться к моим предыдущим статьям или обменяться мыслями и опытом в области комментариев.Добро пожаловать, чтобы вместе изучить настоящую фронтенд-технологию.
github: react-slider-vertify
Стартер:Технологическое сообщество Nuggets
Столбец:гитхаб проект с открытым исходным кодом
Официальный аккаунт: Интересный интерфейс разговора
больше рекомендаций
- Как спроектировать хранилище компонентов для платформы визуального построения?
- Проектирование механизма визуализации большого экрана с нуля
- Используйте электрон для создания настольного визуального редактора Dooring с нуля
- (Low Code) Платформа визуализации Анализ дизайна источника данных
- Создайте редактор страниц для ПК PC-Dooring с нуля
- Как быстро разработать страницы H5 со строительными блоками?