bugfix> javascript > 投稿

現在、ショッピングサイト内の写真に表示される編集可能な領域を作成しようとしています。

目的は、Reactを使用して、移動およびサイズ調整が可能なボックス付きの画像を作成することです。

私はこれについてyoutubeからjavascriptチュートリアルに従っていますが、これは期待どおりに機能していません。

以下は私が使用しているコードです:

import React, { useState } from "react";
import axios from "axios";
import Delete from "../Buttons/Delete";
import Picture from "../Picture/Picture";
function EditableImageUploader(props){
    const [  loading, setLoading ] = useState(false);
    const editableArea = document.querySelector(".editableArea");
    const pictureEdit = document.querySelector(".pictureEdit");
    const uploadImage = async e => {
        const files = e.target.files
        const data = new FormData()
        data.append('file', files[0])
        data.append('upload_preset', 'charlotte-co')
        setLoading(true)
        axios.post('https://api.cloudinary.com/v1_1/charlotte-co/image/upload', data)
            .then(res => {
                setLoading(false);
                props.setImages([...props.images, res.data]);
            })
            .catch(err =>console.log(err));
    }
    function moveDiv(e){
        window.addEventListener("mousemove", mouseMove);
        window.addEventListener("mouseup", mouseRelease);
        let prevX = e.clientX;
        let prevY = e.clientY;
        function mouseMove(e){     
            let newX = prevX - e.clientX;
            let newY = prevY - e.clientY;
            console.log(prevY)
            console.log(`Y = ${e.clientY}`)
            console.log(prevX)
            console.log(`X = ${e.clientX}`)
            const rect = editableArea.getBoundingClientRect()
            editableArea.style.left = (rect.left - newX) + "px";
            editableArea.style.top = (rect.top - newY) + "px";
        }
        function mouseRelease(){
            window.removeEventListener("mousemove", mouseMove);
            window.removeEventListener("mouseup", mouseRelease);
            prevX = e.clientX;
            prevY = e.clientY; 
        }
    }
    return(<>
        <div className="image-uploader">
            {(props.images)?"":(<input
                type="file"
                name="file"
                placeholder="Upload a File"
                className="uploader"
                onChange={uploadImage}
            />)}
            <div>
                {loading ? (
                    <h4>loading...</h4>
                ):""}
                {(props.images)?(
                    props.images.map(image => {
                        return (<>
                            <Delete 
                                delete={image.public_id}
                                deleteFrom={props.images}
                                setDeleteFrom={props.setImages}
                            />
                         {
                         }   <Picture
                                className="pictureEdit"
                                publicId={image.public_id}
                                version={image.version}
                                width="300"
                                quality="100"
                            />
                            <div 
                                className="editableArea"
                                onMouseDown={(e)=> moveDiv(e)}
                            >
                                <div className="resizer north"></div>
                                <div className="resizer west"></div>
                                <div className="resizer south"></div>
                                <div className="resizer east"></div>
                                The transfer will spread across this box.
                            </div>
                        </>)
                    })
                ):(<p>No blank image available currently. Upload one to make this option available.</p>)}
            </div>
        </div>
    </>)
}
export default EditableImageUploader;

そしてここに関連するCSSがあります:


.editableArea{
    position: absolute;
    background-color: green;
    height: 150px;
    width: 150px;
    border-style: solid;
    border-color: black;
    border-width: 5px;
    z-index: 5;
    cursor: move;
}

divを移動してその位置を変更できますが、元の位置から遠くに移動しています。

これもページがスクロールされた場所によるものだと思いますが、なぜそれがそのまま反応するのかよくわかりません。

コンソールが読み取るとき:

653
Y = 653
325
X = 367

編集可能領域の実際の位置は次のとおりです。

left: 1005.55px; 
top: -12346.8px;

これが現在のように機能している方法と理由、およびこの問題を修正する方法についてのヘルプや説明をいただければ幸いです。

回答 1 件
  • 計算にoffsetTopとoffsetLeftを含めることを検討してください。たとえば、divがページの幅と高さの100%を占めていない場合、clientX関数とclientY関数は実際には画面内のマウスの位置を返し、それらは相対的ではないため、通常は異なる結果が得られます。 DOM要素。この記事は役に立ちます: ブラウザのビューポートに対して要素の最上位の位置を取得するにはどうすればよいですか?

    また、考慮すべきもう1つの点は、ドラッグを開始したときに要素がクリックされる正確な位置です。例を挙げて説明できます。ドラッグを開始したときに、中央(水平方向と垂直方向の両方)の要素をクリックしたとします。計算が完了すると、取得する位置が上下に設定されます。このオフセットがないと、要素はマウスを離した位置に配置されませんが、少し(または要素のサイズによっては大きく)移動します。

    いくつかのコードを手伝いたいのですが、リソース(画像)やaxios呼び出しなど、ロジックがたくさんあるので難しいでしょう。この種のロジックを切り取っていくつかの画像をハードコーディングし、オンラインエディターとコンパイラーでコードを追加してリンクを設定すると、コードのサポートも試みます。

    他にご不明な点がございましたら、お気軽にお問い合わせください。

あなたの答え