Spets
Spets

Reputation: 2431

Positioning this element to the center of the page - CSS

I've been battling this for quite some time and I'm not having much luck, it always gets repositioned all over the place!

I essentially want my control to center this component in the middle of the page. I also want to rotate flip it(3d) around it's center axis(Y or X, doesn't matter) but I'm having no luck with the first step which is just getting it to the center.

<div className="note-container">
                <div className="note"
                    style={Object.assign({}, note.position) }>
                    <p>{note.text}</p>
                    <span>
                        <button onClick={() => onExpand(note.id) }
                            className="btn btn-warning glyphicon glyphicon-resize-full"/>
                        <button onClick={() => onEdit(note.id) }
                            className="btn btn-primary glyphicon glyphicon-pencil"/>
                        <button onClick={onRemove}
                            className="btn btn-danger glyphicon glyphicon-trash"/>
                    </span>
                </div>
            </div>

The function I'm calling to reposition it to the center is function onExpand(noteId){...}

Here is the CSS for .note-container and .note

div.note-container {
    position: fixed;
    top: 5%;
    left: 90%;
}

div.note {
    height: 150px;
    width: 150px;
    background-color: yellow;
    margin: 2px 0;
    position: relative;
    cursor: -webkit-grab;
    -webkit-box-shadow: 5px 5px 15px 0 rgba(0, 0, 0, .2);
    box-shadow: 5px 5px 15px 0 rgba(0, 0, 0, .2);
}

div.note:active {
    cursor: -webkit-grabbing;
}

div.note p {
    font-size: 22px;
    padding: 5px;
    font-family: "Shadows Into Light", Arial;
}

div.note div.back p {
    font-size: 30px;
    padding: 5px;
    font-family: "Shadows Into Light", Arial;
}

div.note:hover> span {
    opacity: 1;
}

div.note> span {
    position: absolute;
    bottom: 2px;
    right: 2px;
    opacity: 0;
    transition: opacity .25s linear;
}

div.note button {
    margin: 2px;
}

div.note> textarea {
    height: 75%;
    background: rgba(255, 255, 255, .5);
}

And here is the onExpand function

    onExpand(noteId) {

    //This needs a lot of work....
    event.preventDefault();

    let flippedNote = this.props.notes
        .filter(note => note.id === noteId)[0];
    flippedNote.position.transition = "1.0s";
    flippedNote.position.transformStyle = "preserve-3d";
    flippedNote.position.backgroundColor = "#3498db";
    flippedNote.position.color = "white";
    flippedNote.position.width = "300px";
    flippedNote.position.height = "300px";

    flippedNote.position.position = "absolute";
    flippedNote.position.right = `50% -${flippedNote.position.width / 2}px`;
    flippedNote.position.top = `50% -${flippedNote.position.height / 2}px`;
    // flippedNote.position.transform = "translate(-50%, -50%) rotateY(180deg)";

    this.setState({/*Stuff later... */});
}

Also when I render the note on the page I assign it a random location on the page based on this logic(this is what is initially passed into the style attribute in the div.note element:

position: {
                    right: randomBetween(0, window.innerWidth - 150) + "px",
                    top: randomBetween(0, window.innerHeight - 150) + "px",
                    transform: "rotate(" + randomBetween(-15, 15) + "deg)"
                }

Here is what the html on the page looks like(note I am also dragging the sticky note across the page using transform: translate(...).

enter image description here

Upvotes: 3

Views: 164

Answers (3)

Spets
Spets

Reputation: 2431

Here is the final solution after working on it this weekend:

onExpand(noteId, currentNotePosition) {

        event.preventDefault();
        let note = this.props.notes
            .filter(specificNote => specificNote.id === noteId)[0];

        const centerOfWindow = {
            left: window.innerWidth / 2,
            top: window.innerHeight / 2
        };

        if (!note.centered) {
            note.position.transition = "all 1s";
            note.position.transformStyle = "preserve-3d";
            note.position.backgroundColor = "#3498db";
            note.position.color = "white";
            note.position.width = "300px";
            note.position.height = "300px";
            note.position.zIndex = "100";
            note.position.position = "relative";
            const offset = {
                x: 150,
                y: 150
            };
            const translatedCoordinates = this.getCoordinateTarget(centerOfWindow, offset, currentNotePosition);
            note.position.transform = `translate(${translatedCoordinates.x}px, ${translatedCoordinates.y}px) rotateY(180deg)`;

            note.originalPosition = {
                left: currentNotePosition.left,
                top: currentNotePosition.top,
                width: currentNotePosition.width,
                movement: translatedCoordinates
            };

            note.centered = true;
        } else {
            note.position.backgroundColor = "yellow";
            note.position.color = "black";
            note.position.width = "150px";
            note.position.height = "150px";
            note.position.transform = "";
            note.centered = false;
        }

        this.props.stickyNoteActions.repositionedNoteSuccess(Object.assign({}, note));
    }

Upvotes: 1

user6269864
user6269864

Reputation:

To control the position, you can set position: relative; or position: absolute; on your div.note.

Alternatively, this can be done by manipulating margins, but it's not really a good way.

You can test your code manually by opening the page in browser and manipulating CSS values through Chrome's developer tools.

Upvotes: 1

RandyDaddis
RandyDaddis

Reputation: 1050

try this:

div.note 
 {
    position: relative;
    width: 150px;
    left: 0;
    right: 0;
    margin: 2px auto;
 }

Upvotes: 2

Related Questions