daybrush / moveable

Moveable! Draggable! Resizable! Scalable! Rotatable! Warpable! Pinchable! Groupable! Snappable!
https://daybrush.com/moveable/
MIT License
10.09k stars 619 forks source link

moveable-control-box misplaced when used with SVG elements #390

Closed ilyes24 closed 3 years ago

ilyes24 commented 3 years ago

Environments

Description

I'm using MoveableJS to manipulate (translate, scale, rotate, ...) SVG elements (path, text, rect ...) in Angular project The problem is that the surrounded rectangle provided by moveableJS is misplaced (wrong width, height, and starting point).

Bellow is what I tried to do:

HTML

<div id='canvas' class="canvas mt-4 text-center align-self-center" (click)="canvasClicked($event)"
                    style="background-color: white; background-image: url(../../assets/svgs/canva-background.svg);">

    <svg version="1.2" baseProfile="tiny" id="Logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 250 250" xml:space="preserve">
        <text id="text" transform="matrix(1 0 0 1 31.1271 199.1222)" fill="#561010" font-family="'Roboto-Regular'" font-size="25.3945px">Nom d’entreprise</text>
        <g>
            <path transform="matrix(1 0 0 1 0 0)" fill="#000" d="M51.75,55.77c-0.27-0.39,3.97-5.2,10.38-7.74c1.79-0.71,11.97-4.75,21.31,0.8 c8.61,5.12,11.99,15.71,10.53,24.27c-2.38,13.95-17.76,23.37-22.24,20.72c-0.97-0.57-1.32-2.75-1.99-7.09 c-1.81-11.84-1.68-20.54-1.68-20.54c0.05-3.05,0.19-4.38-0.61-6.25c-1.42-3.32-4.9-6.23-8.62-6.47 C54.84,53.21,51.97,56.08,51.75,55.77z"></path>
        </g>
    </svg>
</div>
    <div class="label" style="z-index: 9999999;" #label></div>
    <ngx-moveable
        #moveable
        [target]="target"
        [draggable]="true"
        [scalable]="true"
        [origin]="true"
        [snappable]="true"
        [throttleResize]="0"
        [keepRatio]="true"
        (dragStart)="onDragStart($event)"
        (drag)="onDrag($event)"
        (scaleStart)="onScaleStart($event)"
        (scale)="onScale($event)"
        (scaleEnd)="onScaleEnd($event)"
    >
    </ngx-moveable>

TypeScript

@ViewChild("target", { static: false }) target;
@ViewChild("label", { static: false }) label: ElementRef;
@ViewChild("moveable", { static: false }) moveable: NgxMoveableComponent;

frame = {
    translate: [0, 0],
    scale: [1, 1],
};

onWindowReisze = () => {
    this.moveable.updateRect();
};

onDragStart({ set }) {
    let matrix = this.menuService.getElementMatrix(this.target);
    this.frame.translate = [Number(matrix.x) * this.alignmentService.rapport, Number(matrix.y) * this.alignmentService.rapport]
    set(this.frame.translate);
}
onDrag({ target, beforeTranslate, clientX, clientY }) {
    this.frame.translate = beforeTranslate;
    target.style.transform
        = `translate(${(beforeTranslate[0]/this.alignmentService.rapport)}px, ${(beforeTranslate[1]/this.alignmentService.rapport)}px)`;
}
onDragEnd({ target, isDrag}) {
    console.log("onDragEnd", target, isDrag);
}

onScaleStart({ set, dragStart }) {
    set(this.frame.scale);

    // If a drag event has already occurred, there is no dragStart.
    dragStart && dragStart.set(this.frame.translate);
}
onScale({ target, scale, drag }) {
  this.frame.scale = scale;
  // get drag event
      this.frame.translate = drag.beforeTranslate;
      target.style.transform
          = `translate(${drag.beforeTranslate[0]}px, ${drag.beforeTranslate[1]}px)`
          + `scale(${scale[0]}, ${scale[1]})`;
  }
onScaleEnd({ target, isDrag, clientX, clientY }) {
    console.log("onScaleEnd", target, isDrag);
}
async ngOnInit() {
    window.addEventListener("resize", this.onWindowReisze);
}

In the image below is a demonstration of the issue (i clicked on the leaf)

daybrush commented 3 years ago

@ilyes24

I have several questions.

  1. Where is the area of svg
  2. Where is the area of the leaf
  3. When you click, does the target change to a leaf?

Would you like to mark the area in red?

ilyes24 commented 3 years ago

@daybrush

Thank you for the fast reply.

1. Where is the area of the svg? I have removed elements on the svg in the example just to be clear, the svg is all the element and the mask under the logo is an element.

2. Where is the area of the leaf? The leaf is just an example in general all element are basic elements of svg tiny 1.2 and the logo is inside a tag

3. When you click, does the target change to leaf Yes. And now i'm using Selecto for the selection (thank you very much by the way) and the same problem happened.

daybrush commented 3 years ago

@ilyes24

I've been testing with svg, but it's working. I guess I need to know the svg structure of that logo.

ilyes24 commented 3 years ago

@daybrush

Sorry the svg is little bit complicated

<svg version="1.2" baseProfile="tiny" id="Logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 250 250" xml:space="preserve"><style>@keyframes flickerAnimation {0%   { opacity:1; } 50%  { opacity:0.7; } 100% { opacity:1; }} .animate-flicker { animation: flickerAnimation 1.5s infinite;} .selected{ outline: grey dashed 1px; }</style><rect x="0" y="0" width="100%" height="100%" id="background" style="fill:#fff;"></rect><image x="0" y="0" width="100%" height="100%" id="mask" href="assets/svgs/izeeLogoMask.svg"></image> <text class="draggable selecto" id="slogan" transform="matrix(1 0 0 1 81.7318 233.6328)" fill="#0D0E0E" font-family="'Roboto-Regular'" font-size="25.3945px"></text> <text class="draggable selecto" id="text" transform="matrix(1 0 0 1 24.8186 198.6328)" fill="#561010" font-family="'Roboto-Regular'" font-size="25.3945px" style="">Nom de l'entreprise</text> <g class="draggable" transform="matrix(1 0 0 1 0 0)"> <g> <path class="draggable selecto" transform="matrix(1 0 0 1 0 0)" fill="#FFFFFF" d="M61.3,69.7c3.9,0.1,5.2,0.1,5.2,0.1s0.9-3.1-4.8-3.2c-5.6-0.1-5.6-0.1-5.6-0.1S57.4,69.7,61.3,69.7z"></path> <image width="10" height="17" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAVCAYAAACdbmSKAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA
GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIRJREFUeNpiYBhQ8EZX8/9rLc3/
uOSZcEkwMuM2FEPTG32EDSAbSbIJBrA5k4mQ/SBnomtkwuU0dI3EO48JNUSJ9hNZAYHNNlRNTP+J
MppKziNgG8iJOOIJv0bcfsKjkWQ/iVy8zoiiSeTsTUZibGPEmp+M1f8z/EOSArJBNtA/ZwMEGACv
ISc9aSsJFgAAAABJRU5ErkJggg==" transform="matrix(0.24 0 0 0.24 87.0945 65.28)"> </image> </g> <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="82.6658" y1="106.9799" x2="245.1064" y2="106.9799"> <stop offset="0" style="stop-color:#F78F1E"></stop> <stop offset="0.1536" style="stop-color:#F6881F"></stop> <stop offset="0.4082" style="stop-color:#F47721"></stop> <stop offset="0.5104" style="stop-color:#F36D21"></stop> <stop offset="1" style="stop-color:#EE2C24"></stop> </linearGradient> <path class="draggable selecto" transform="matrix(1 0 0 1 0 0)" fill="url(#SVGID_1_)" d="M244.8,118.5c-0.3-1.3-0.8-3.3-2.1-5.6c-1.3-2.3-3.5-5-7-6.8c-3.4-1.9-7.8-2.9-12.4-3
        c-4.6-0.2-9.5,0.5-14.4,1.6c-4.9,1.1-10,2.7-15,4.7c-5.2,2-9.6,4.1-14.6,5.6c-5,1.6-10.1,3-15.3,4c-5.2,1-10.4,1.8-15.5,2
        c-2.5,0.1-5.1,0.1-7.2-0.1c-2.5-0.2-4.8-0.6-7-1.3c-1.3-0.4-2.6-0.8-3.8-1.3c0.4,0,0.9,0,1.3,0c5.3-0.2,10.5-1.8,14.9-3.9
        c2.3-1,4.4-2.2,6.4-3.4c2-1.2,4.1-2.6,5.9-3.8c3.7-2.6,7.1-5.3,10.4-7.8c3.2-2.5,6.3-4.7,9.3-6.6c0.6-0.4,1.7-1,2.3-1.3
        c0.7-0.4,1.4-0.8,2.2-1.1c1.5-0.8,2.9-1.4,4.4-2c2.9-1,5.7-1.8,8.2-2.1c2.5-0.3,4.8-0.3,6.6-0.1c1.8,0.3,3.4,0.5,4.4,0.9
        c1,0.3,1.6,0.5,1.6,0.5s-0.4-0.4-1.2-1.1c-0.8-0.7-2.1-1.7-4-2.6c-3.7-1.9-9.9-3.3-17.2-2.3c-1.8,0.3-3.7,0.6-5.6,1.1
        c-1,0.2-1.9,0.5-2.9,0.9c-1.1,0.4-1.7,0.6-2.9,1.1c-3.8,1.6-7.6,3.6-11.3,5.9c-3.7,2.2-7.3,4.6-10.8,6.9c-1.8,1.2-3.5,2.1-5.3,3.2
        c-1.8,1-3.7,2-5.5,2.8c-3.6,1.7-7.1,2.8-10.6,3.1c-3.5,0.4-7,0-10.5-1l-1.3-0.4c-0.3-0.1-0.7-0.2-1-0.4c-0.7-0.3-1.4-0.6-2.1-1
        c-1.4-0.8-2.7-1.8-4.1-2.9c-2.7-2.3-5.3-4.9-7.9-7.2c-2.6-2.4-5.3-4.3-7.9-5.7c-2.5-1.5-5-2.3-7-2.8c-2-0.5-3.7-0.4-4.8-0.4
        c-1.1,0.1-1.6,0.2-1.6,0.2s0.5,0.2,1.6,0.5c1,0.3,2.4,1,3.9,2c3.2,2,6.9,5.8,10.6,11c1.9,2.6,3.8,5.7,6.5,8.9
        c0.2,0.3,0.5,0.6,0.8,0.9c0.4,0.6,0.8,1.2,1.2,1.7c2.5,3.5,5.6,7.2,9.4,10.8c3.9,3.4,8.6,6.6,14.1,8.8c2.7,1.1,5.7,1.9,8.5,2.4
        c3.3,0.6,6.1,0.7,9.1,0.8c6,0.1,11.9-0.5,17.6-1.6c5.8-1.1,11.4-2.6,16.9-4.5c5.4-1.8,10.8-4.6,15.2-6.7c9.1-4.4,17.8-7.9,25.4-9.2
        c3.8-0.6,7.2-0.5,10,0.1c2.9,0.7,5.1,2.2,6.9,3.7c1.7,1.6,2.8,3.1,3.5,4.2c0.7,1.1,1.1,1.7,1.1,1.7S245,119.8,244.8,118.5z"></path> <linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="11.3897" y1="92.5374" x2="94.1996" y2="92.5374"> <stop offset="0" style="stop-color:#F78F1E"></stop> <stop offset="0.1536" style="stop-color:#F6881F"></stop> <stop offset="0.4082" style="stop-color:#F47721"></stop> <stop offset="0.5104" style="stop-color:#F36D21"></stop> <stop offset="1" style="stop-color:#EE2C24"></stop> </linearGradient> <path class="draggable selecto selected animate-flicker" transform="matrix(1 0 0 1 0 0)" fill="url(#SVGID_2_)" d="M71.9,88.1C63.3,85.3,63,78.1,63,78.1c14.7-8.7,19.1,1.5,19.1,1.5c2.9-5,7.5,0.5,7.5,0.5
        s7.8-12.5,3.1-19.5c-1.7-2.4-7.1,0.2-13,1.4c-7.9,1.7-10.9,0-10.9,0c-2.6-7.6-12.3-7.3-21.9-6c-9.5,1.4-19-5.3-19.1-5.2
        c0,0,0,0,0,0c0.7,13.4,9.9,14.2,9.9,14.2c-16.3,3.7-21,13.2-21,13.2l5,1.2c-4.8,2.9-8.6,8-10.3,18l4.9-1.4c0,0-3.4,6.9-1.1,13.8
        l4.6-1.8c0,0-2.5,5.9,3.9,13.6l3.7-2c0,0,0.3,6.2,7.4,10.3l2.2-3.1c0,0,5.2,7.1,11.2,7.4l-0.4-4c0,0,4.6,4.1,13.4,3.3
        c7.9-0.7,14.3-2.6,21.3-7.4c0.1-0.1,0.3-0.2,0.4-0.3c-0.4-2.8-1.8-5.7-4.4-8.4c-9.2-9.4-20.1-6-27.8-16.2c-5-6.7-2.7-11.4-2.7-11.4
        c5.3,5.9,10.5,2.2,16,5.5c8.5,5,8.1,10.2,8.1,10.2s3.5-3.6,9.8-8.7c6.3-5.1,2-9.7,2-9.7C82,89.8,78.6,90.4,71.9,88.1z" style=""></path> <path class="draggable selecto" transform="matrix(1 0 0 1 0 0)" fill="#FFFFFF" d="M87.8,65.4c0,0,3,3.5,0.6,3.7C86,69.4,87.8,65.4,87.8,65.4z"></path> <path class="draggable selecto" transform="matrix(1 0 0 1 0 0)" fill="#FFFFFF" d="M56.1,66.5c0,0,0,0,5.6,0.1c5.6,0.1,4.8,3.2,4.8,3.2s-1.3,0-5.2-0.1C57.4,69.7,56.1,66.5,56.1,66.5z"></path> </g> </svg>
daybrush commented 3 years ago

@ilyes24 Thank you. Confirmed. I know reason why.

ilyes24 commented 3 years ago

@daybrush

Can you guide me to resolve this one? (hints or any thing else)

daybrush commented 3 years ago

@ilyes24

I will release tomorrow.

daybrush commented 3 years ago

@ilyes24 moveable's new version is released.

ilyes24 commented 3 years ago

@daybrush

Sorry to bring it up again, but I still have the same problem. I will detail more this time

<svg version="1.1" baseProfile="tiny" id="Logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 250 250" xml:space="preserve" class="Logo">
    <style>
        @keyframes flickerAnimation {0%   { opacity:1; } 50%  { opacity:0.7; } 100% { opacity:1; }} 
        .animate-flicker { animation: flickerAnimation 1.5s infinite;}
    </style>
    <rect x="0" y="0" width="100%" height="100%" id="background" style="fill:#fff;"></rect>
    <image x="0" y="0" width="100%" height="100%" id="mask" href="assets/svgs/izeeLogoMask.svg"></image> 
    <text class="draggable selecto" id="slogan" transform="matrix(1 0 0 1 84.9764 234.1222)" fill="#0D0E0E" font-family="'Roboto-Regular'" font-size="25.3945px"></text>
    <text class="draggable selecto" id="text" transform="matrix(1 0 0 1 30.3612 199.1222)" fill="#561010" font-family="'Roboto-Regular'" font-size="25.3945px">Nom de l'entreprise</text>
    <g class="draggable" transform="matrix(1 0 0 1 0 0)"> 
        <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="161.854" y1="160.0021" x2="170.8624" y2="29.4917"> 
            <stop offset="0" style="stop-color:#C01E6A"></stop> 
            <stop offset="0.449" style="stop-color:#AB226C"></stop> 
            <stop offset="0.9946" style="stop-color:#412767"></stop> 
        </linearGradient> 
        <path class="draggable selecto selected animate-flicker" transform="matrix(1 0 0 1 0 0)" fill="url(#SVGID_1_)" d="M192.51,87.9c5.19,2.29,14.09-4.83,13.57-10.37c-0.98-10.54-3.58-13.2-14.09-14.39 c-7.34-0.84-14.47-9.66-13.52-16.72c1.4-10.36-0.04-12.75-9.59-16.51c-2.32-0.91-4.93-1.37-6.27,0.63 c-1.77,2.64,1.68,3.14,2.95,4.33c7.03,6.63,8.08,13.68,2.92,21.27c-3.97,5.85-11.54,7.61-18.11,4.22 c-7.83-4.05-9.9-10.13-6.66-19.52c0.47-1.36,2.07-3.68-0.32-3.84c-5.51-0.38-6.56-5.24-9.07-8.53c-2.4,1.71-2.21,3.86-2.38,5.86 c-1.82,21.88,10.84,36.73,32.74,38.8c2.78,0.26,6.58-1.58,8.28,2.57c-3.53,0.16-6.5,2.1-9.4,3.64 c-12.59,6.67-24.45,14.4-28.09,29.49c-4.34,18.03,3.57,33.17,12.32,47.92c1.3,2.19,3.75,2.92,6.58,2.5 c11.2-1.7,13.61-4.69,12.8-16.39c5.4-4.79,9.33-12.99,17.86-11.53c8.56,1.47,12.54-2.05,15.61-9.07c1.42-3.24,2.23-6-0.41-8.74 c-2.7-2.81-4.52-7.36-9.73-5.9c-5.64,1.57-9.98-0.25-12.82-5.09c-2.63-4.47-1.58-9.1,1.78-12.61 C183.03,86.19,187.44,85.66,192.51,87.9z M181.45,117.45c-1.82,1.65-4.04,0.67-5.84,1.42c-15.39,2.8-23.62,11.35-23.33,30.33 c-4.45-1.59-4.35-6.39-5.86-10.06c-6.85-23.55-3.22-35.67,14.19-47.44c2.97-3.58,8.39-3.18,11.56-6.41 c1.25,3.37-2.97,5.54-3.04,8.62C166.97,104.96,174.4,111.09,181.45,117.45z" style="transform: translate(-0.281353px, -0.06079px) scale(1.0047, 1.0047);"></path> 
        <linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="75.6214" y1="30.2584" x2="111.2658" y2="154.1672"> 
            <stop offset="0" style="stop-color:#492B71"></stop> 
            <stop offset="0.449" style="stop-color:#3C89BC"></stop> 
            <stop offset="0.9946" style="stop-color:#1DA1A1"></stop> 
        </linearGradient> 
        <path class="draggable selecto" transform="matrix(1 0 0 1 0 0)" fill="url(#SVGID_2_)" d="M115.82,109.44c3.4,18.15-4.75,32.38-13.69,46.16c-1.32,2.05-3.69,2.56-6.36,1.89 c-10.59-2.65-12.24-6.06-10.99-17.51v-0.01c-5.02-5.27-8.48-13.82-16.77-13.12c-8.35,0.71-12.05-3.17-14.72-10.47 c-1.24-3.37-1.91-6.2,0.76-8.71c2.73-2.58,4.67-6.97,9.65-5.05c5.39,2.08,9.65,0.64,12.6-3.95c2.73-4.24,1.91-8.97-1.19-12.78 c-3.3-4.06-7.54-4.98-12.53-3.19c-5.11,1.84-13.43-6.08-12.69-11.59c1.39-10.46,4.01-12.89,14.22-13.15 c7.13-0.18,14.39-8.38,13.76-15.54c-0.92-10.49,0.57-12.76,9.96-15.67c2.28-0.7,4.82-0.93,6.03,1.19c1.61,2.8-1.75,3-3.02,4.08 c-7.08,6-8.38,12.97-3.72,21.03c3.6,6.2,10.85,8.64,17.34,5.83c7.73-3.35,9.98-9.25,7.24-18.94c-0.39-1.4-1.84-3.87,0.47-3.82 c5.35,0.11,6.56-4.66,9.12-7.73c2.26,1.93,1.98,4.06,2.06,6.08c0.85,22.06-12,35.81-33.26,35.92c-2.7,0.02-6.29-2.16-8.11,1.84 c0.82,0.61,1.47,1.25,1.95,1.9c2.31,0.89,4.35,2.44,6.37,3.77C102.01,85.58,112.98,94.24,115.82,109.44z M92.59,90.34 c-2.61-3.7-7.62-3.87-10.53-7.1c-0.02,2.65,2.92,4.9,2.87,7.56c1.63,11.26-5.82,16.73-12.9,22.47c1.7,1.81,3.88,1.04,5.59,1.94 c14.72,4.17,22.33,13.43,21.3,32.29c3.57-1.49,3.75-5.87,5.24-9.14C111.65,115.74,108.69,103.47,92.59,90.34z"></path> 
    </g> 
</svg>

I checked twice, the target element is the one I clicked, and always the control-box is misplaced (I noticed that the origin is always related to the (0, 0)).

Notice: I'm using Selecto right now.

daybrush commented 3 years ago

@ilyes24

Probably setting position: relative on svg will work fine. This will be fixed soon.

And the origin of svg is originally 0, 0.

ilyes24 commented 3 years ago

@daybrush

For the origin, I mean a path origin (a sub-element, the selected item for example)

daybrush commented 3 years ago

@ilyes24

What I'm talking about is the path. The default origin of all sub-elements of svg is 0,0.

ilyes24 commented 3 years ago

@daybrush

ah sorry, can I automatically change it to the center of the element?

ilyes24 commented 3 years ago

@daybrush

Can the container be adapted to viewBox?

daybrush commented 3 years ago

@ilyes24

moveable's new version is released.

ilyes24 commented 3 years ago

This worked great, thank you

ilyes24 commented 3 years ago

When an element is selected and scrolled in the workspace the control-box stick to the position and leave the element

daybrush commented 3 years ago

@ilyes24

I think that the position of the scroll area is not relative.

set scroll's css position:relative

ilyes24 commented 3 years ago

@daybrush i will try it. Also dragEnd scaleEnd are not triggered

ctamiozzo commented 3 years ago

I have updated react-moveable to the version 0.25.2. I'm working with SVG elements (the dimension of the ViewBox is the same of the svg element). The position of the surrounded rectangle is wrong when the target element is a svg group (element ): it is always positioned at (0,0). For other svg elements it works fine. Did someone other have the same problem?

daybrush commented 3 years ago

@ctamiozzo

Show me a demo or screenshot that can be tested

@ilyes24

I don't know why the end event doesn't trigger. Can you show the reproduction demo as a video or gif?

ctamiozzo commented 3 years ago

This is a simple demo to reproduce the problem: react-moveable-demo.zip

and this is a screenshot of the problem: image as you can see the moveable rectangle that should be around the green rectangle is placed at the upper left corner of the svg area. If you move the className='moveable' to the "< rect >" element the rectangle goes to the right position.

Thanks

daybrush commented 3 years ago

@ctamiozzo

First of all, I'm sorry. The g tag is not supported.

daybrush commented 3 years ago

@ctamiozzo

I will support the g tag in the next version.

ilyes24 commented 3 years ago

@daybrush

you have updated the react-moveable only, ngx-moveable also has the same issue. Please if you can support it