react使用拖拽,縮放組件,采用react-rnd解決 -完整版

屏幕錄制2025-03-10 10.16.06

以下代碼僅提供左側可視化區域
右側數據根據你們的存儲數據來
大家直接看Rnd標簽設置的屬性即可!!!!!

/*** 用戶拖拽水印的最終位置信息*/
export interface ProductWatermarkValue {watermark?: ProductWatermarkManagerValue;position: {x: number; // 水印在圖片上的水平位置y: number; // 水印在圖片上的垂直位置};size: {width: number; // 水印的寬度(相對于商品圖片的寬度)height: number; // 水印的高度(相對于商品圖片的高度)};
}
/*** 用戶上傳的水印詳細信息,比如路徑,寬高*/
export interface ProductWatermarkManagerValue {id: string;name: string;fileUrl: string;width: number;height: number;type: ProductWatermarkManagerValueType;
}
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Rnd } from 'react-rnd';
import { Dispatch } from 'redux';
import { actions } from '@comall-backend-builder/core';
import { Entity } from '@comall-backend-builder/core/lib/parser';
import './index.less';const prefix = 'product-main-image-watermark-preview';
interface Props {dispatch: Dispatch;entity: Entity;componentId: any;preview: any;
}
interface State {/*** 正在操作中*/isDragging: boolean;
}
export class productMainImageWatermarkRulePreview extends Component<Props, State> {constructor(props: Props) {super(props);this.state = {isDragging: false,};}getWatermarkRule = () => {const { preview } = this.props;return preview?.baseInfo?.watermarkRule;};getPreviewProduct = () => {const { preview } = this.props;const goods = preview?.baseInfo?.goods || [];const isPreviewGoods = goods.find((item: any) => {return item.isPreview;});return isPreviewGoods;};onChangeWatermarkRule = (ruleWatermark: any) => {const { dispatch, componentId } = this.props;dispatch(actions.formChangeAction(componentId, 'baseInfo.watermarkRule', ruleWatermark));};handleDragStart = (e: any) => {e.preventDefault();e.stopPropagation();this.setState({isDragging: true,});};handleDragStop = (e: any, d: any) => {e.preventDefault();e.stopPropagation();this.setState({isDragging: false,});const watermarkRule = this.getWatermarkRule();watermarkRule.position = {x: d.x > 0 ? d.x * 2 : 0,y: d.y > 0 ? d.y * 2 : 0,};this.onChangeWatermarkRule({ ...watermarkRule });};handleResizeStart = (e: any) => {e.preventDefault();e.stopPropagation();this.setState({isDragging: true,});};handleResizeStop = (e: any, direction: any, ref: any, delta: any, position: any) => {e.preventDefault();e.stopPropagation();this.setState({isDragging: false,});const watermarkRule = this.getWatermarkRule();const sizeWidth = ref.style.width.replace('px', '');const sizeHeight = ref.style.height.replace('px', '');//因為左側模擬器是375px,后端存儲的是750px的,所以Rnd數據需要乘以2watermarkRule.size = {width: `${sizeWidth * 2}px`,height: `${sizeHeight * 2}px`,};watermarkRule.position = {x: position.x > 0 ? position.x * 2 : 0,y: position.y > 0 ? position.y * 2 : 0,};this.onChangeWatermarkRule({ ...watermarkRule });};render() {const watermarkRule = this.getWatermarkRule();if (!watermarkRule) {return null;}const { position, size, watermark } = watermarkRule;const previewGoods = this.getPreviewProduct();const pic = previewGoods?.productPic || '';const { isDragging } = this.state;const style = {backgroundImage: pic ? `url(${pic})` : undefined,};const sizeWidth = size && size.width ? size.width.replace('px', '') : 0;const sizeHeight = size && size.height ? size.height.replace('px', '') : 0;//因為后端存儲的是750px的,左側模擬器是375px,所以頁面渲染數據需要除2const rndSize = {width: `${sizeWidth / 2}px`,height: `${sizeHeight / 2}px`,};const rndPosition = {x: position.x / 2,y: position.y / 2,};console.log('存儲大小size,position', size, position);console.log('展示大小rndSize,rndPosition', rndSize, rndPosition);const isDraggingStyle = {opacity: isDragging ? 0.8 : 1,border: isDragging ? '2px solid #1890ff' : undefined,};return (<div className={prefix}><div className={`${prefix}__bg`} style={style}><RndmaxHeight={375}maxWidth={375}size={rndSize}position={rndPosition}bounds="parent"onDragStart={this.handleDragStart}onDragStop={this.handleDragStop}onResizeStart={this.handleResizeStart}onResizeStop={this.handleResizeStop}resizeParentMore={true} // 如果需要阻止父容器跟隨大小變化,可以設置為falseenableResizing={{top: true,right: true,bottom: true,left: true,topRight: true,bottomRight: true,bottomLeft: true,topLeft: true,}}resizeHandles={['se', 'sw', 'ne', 'nw']}style={isDraggingStyle}onClick={(e: any) => e.stopPropagation()}lockAspectRatio={true}><imgsrc={watermark?.fileUrl}alt=""style={{ width: '100%', height: '100%' }}/></Rnd></div></div>);}
}const mapStateToProps = (_state: any, props: any) => {let preview = null;let componentId = null;const entityId = props.entity.id;for (var compId in _state.components) {const comp = _state.components[compId];if ((comp.type === 'CreateForm' || comp.type === 'EditForm') &&comp.entityId === entityId) {preview = comp.fields;componentId = compId;}}return { preview: preview, componentId: componentId };
};export const ProductMainImageWatermarkRulePreview = connect(mapStateToProps)(productMainImageWatermarkRulePreview
);
.product-main-image-watermark-preview{&__bg{margin-right: 10px;overflow: hidden;width: 375px ;min-width: 375px;height: 375px;position: relative;border: 1px solid #ccc;background-position: center;background-repeat: no-repeat;background-size: cover;}
}

開發過程中遇到的問題
1.在使用過程中,火狐瀏覽器出現一拖拽,就打開了瀏覽器新標簽頁
解決方案:在方法調用處理中新增以下兩個代碼

e.preventDefault();
e.stopPropagation();

2.在使用過程中,用戶需要自己上傳的水印在左側渲染中,拉伸時,是等比例放大或縮小的,而不是用戶自己控制拉伸大小
解決方案:Rnd標簽設置屬性

  lockAspectRatio={true}

希望以上代碼對大家有幫助??

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/73033.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/73033.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/73033.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring Cloud之遠程調用OpenFeign參數傳遞

目錄 OpenFeign參數傳遞 傳遞單個參數 傳遞多個參數 傳遞對象 傳遞JSON OpenFeign參數傳遞 傳遞單個參數 服務提供方product-service RequestMapping("/product") RestController public class ProductController {Autowiredprivate ProductService productSe…

每日一練之移除鏈表元素

題目&#xff1a; 畫圖解析&#xff1a; 方法&#xff1a;雙指針 解答代碼&#xff08;注&#xff1a;解答代碼帶解析&#xff09;&#xff1a; //題目給的結構體 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* }…

從零開始的python學習(五)P75+P76+P77+P78+P79+P80

本文章記錄觀看B站python教程學習筆記和實踐感悟&#xff0c;視頻鏈接&#xff1a;【花了2萬多買的Python教程全套&#xff0c;現在分享給大家&#xff0c;入門到精通(Python全棧開發教程)】 https://www.bilibili.com/video/BV1wD4y1o7AS/?p6&share_sourcecopy_web&v…

基于SpringBoot實現旅游酒店平臺功能八

一、前言介紹&#xff1a; 1.1 項目摘要 隨著社會的快速發展和人民生活水平的不斷提高&#xff0c;旅游已經成為人們休閑娛樂的重要方式之一。人們越來越注重生活的品質和精神文化的追求&#xff0c;旅游需求呈現出爆發式增長。這種增長不僅體現在旅游人數的增加上&#xff0…

FastAPI 分頁模塊實現詳解

1. 簡介 本文詳細介紹了一個基于 FastAPI 框架的通用分頁處理模塊的實現。該模塊提供了標準的分頁參數處理、數據切片和響應格式化功能&#xff0c;可以輕松地集成到任何 FastAPI 項目中。 2. 代碼實現 2.1 導入必要的模塊 首先&#xff0c;我們需要導入所需的模塊&#xf…

Java 學習記錄:基礎到進階之路(一)

今天&#xff0c;讓我們深入到 Java 項目構建、基礎語法及核心編程概念的領域&#xff0c;一探究竟。 軟件安裝及環境配置請查看之前更新的博客有著詳細的介紹&#xff1a; IDEA軟件安裝&環境配置&中文插件-CSDN博客 目錄 1.Java 項目構建基礎 1.項目中的 SRC 目錄…

Yashan DB 對象管理

一、什么是數據庫對象 數據庫對象是數據庫里面用來存儲和指向數據的各種概念和結構的總稱。數據庫支持的對象包括&#xff1a; ? 表&#xff1a;表是一個邏輯概念&#xff0c;是數據庫組織管理數據的基本單位。 ? 索引&#xff1a;索引是建立在表上的邏輯對象&#xff0c;索…

deepseek 3FS編譯

3FS在ubuntu22.04下的編譯&#xff08;記錄下編譯過程&#xff0c;方便后續使用&#xff09; 環境信息 OS ubuntu 22.04內核版本 6.8.0-52-genericlibfuse 3.16.1rust 1.75.0FoundationDB 7.1.66meson 1.0.0ninja 1.10.1 libfuse編譯 以下建議均在root下執行 pip3 install…

python-uiautomator2 安裝教程

目錄 一、簡介 二、支持平臺及語言 三、工作原理 四、安裝 一、簡介 uiautomator2是一個python庫&#xff0c;用于Android的UI自動化測試&#xff0c;其底層基于Google uiautomator&#xff0c;Google提供的uiautomator庫可以獲取屏幕上任意一個APP的任意一個控件屬性&…

無頭瀏覽器與請求簽名技術-Cloudflare防護

在實際數據采集實踐中&#xff0c;許多目標網站&#xff08;例如 Amazon&#xff09;都會采用 Cloudflare 等防護措施&#xff0c;防止機器人和非正常流量。本文將分享一個故障場景下的排查與改進方案&#xff0c;講述如何利用無頭瀏覽器、請求簽名技術以及爬蟲代理 IP來實現數…

Spring Cloud之注冊中心之Nacos健康監測和環境隔離

目錄 Nacos健康檢查 兩種健康檢查機制 Nacos服務類型實例 Nacos環境隔離 創建namespace 配置namespace Nacos健康檢查 兩種健康檢查機制 Nacos作為注冊中?, 需要感知服務的健康狀態, 才能為服務調??提供良好的服務. Nacos 中提供了兩種健康檢查機制&#xff1a; 客?…

Vue3實戰學習(Element-Plus常用組件的使用(輸入框、下拉框、單選框多選框、el-image圖片))(上)(5)

目錄 一、Vue3工程環境配置、項目基礎腳手架搭建、Vue3基礎語法、Vue3集成Element-Plus的詳細教程。(博客鏈接如下) 二、Element-Plus常用組件使用。 &#xff08;1&#xff09;el-input。(input輸入框) <1>正常狀態的el-input。 <2>el-input的disable狀態。 <3…

微服務——網關、網關登錄校驗、OpenFeign傳遞共享信息、Nacos共享配置以及熱更新、動態路由

之前學習了Nacos&#xff0c;用于發現并注冊、管理項目里所有的微服務&#xff0c;而OpenFeign簡化微服務之間的通信&#xff0c;而為了使得前端可以使用微服務項目里的每一個微服務的接口&#xff0c;就應該將所有微服務的接口管理起來方便前端調用&#xff0c;所以有了網關。…

2025年3月11日(有限元牛頓迭代法:通俗講解與示例)

牛頓迭代法的正確流程解釋 是的&#xff0c;你的理解基本正確&#xff01;但需要更準確地描述內外力的關系和迭代邏輯。以下是更清晰的步驟說明&#xff1a; 核心流程&#xff08;修正版&#xff09; 假設已知 外力 ( F_{\text{ext}} )&#xff08;如2000 N&#xff09;&…

爬蟲的精準識別:基于 User-Agent 的正則實現

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家&#xff0c;歷代文學網&#xff08;PC端可以訪問&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移動端可微信小程序搜索“歷代文學”&#xff09;總架構師&#xff0c;15年工作經驗&#xff0c;精通Java編…

【AI大模型】LLM訓練deepseek如何識別視頻

要讓像DeepSeek這樣的大語言模型&#xff08;LLM&#xff09;具備視頻識別能力&#xff0c;需要結合多模態學習技術&#xff0c;將視覺信息與文本語義進行融合。以下是實現這一目標的關鍵步驟和技術要點&#xff1a; --- 一、視頻識別的核心挑戰 1. 多模態數據&#xff1a;視頻…

【物聯網-以太網-W5500】

物聯網-以太網-W5500 ■ W5500-簡介■■■■ ■ W5500-簡介 ■ ■ ■ ■

centos linux安裝mysql8 重置密碼 遠程連接

1. 下載并安裝 MySQL Yum 倉庫 從 MySQL 官方網站下載并安裝 Yum 倉庫配置文件。 # 下載MySQL 8.0的Yum倉庫包 wget https://dev.mysql.com/get/mysql80-community-release-el7-5.noarch.rpm # 安裝Yum倉庫包 sudo rpm -ivh mysql80-community-release-el7-5.noarch.rpm2. 啟…

C++【類和對象】(超詳細!!!)

C【類和對象】 1.運算符重載2.賦值運算符重載3.日期類的實現 1.運算符重載 (1).C規定類類型運算符使用時&#xff0c;必須轉換成調用運算符重載。 (2).運算符重載是具有特殊名字的函數&#xff0c;名字等于operator加需要使用的運算符&#xff0c;具有返回類型和參數列表及函數…

【面試】Java 多線程

多線程 1、什么是線程和進程2、創建線程有幾種方式3、線程有幾種狀態4、什么是上下文切換5、什么是守護線程&#xff0c;和普通線程有什么區別6、什么是線程池&#xff0c;如何實現的7、Executor和Executors的區別8、線程池處理任務的流程9、線程數設定成多少更合適10、執行exe…