Анимация svg с помощью «stroke-dashoffset» не проходит гладко

#css #css-animations #stroke-dasharray

Вопрос:

Я следую этому коду, чтобы создать анимацию диалога. Но анимация, похоже, не идет так гладко, как ссылка, когда я устанавливаю большую ширину и высоту диалогового окна. Похоже, проблема в stroke-dashoffset значениях svg, но я не уверен, какие значения мне нужно установить. Вот кодовый код, который я воспроизвел.

 <div id="modal-close-default" class="" uk-modal>
   <div class="uk-modal-dialog custom-modal six uk-modal-body lab-border-7 uk-margin-auto-vertical">
      ..
      <svg class="modal-svg" xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" preserveAspectRatio="none">
         <rect x="0" y="0" fill="none" width="600" height="376" rx="3" ry="3"></rect>
      </svg>
   </div>
</div>
 
 #modal-close-default {
    .uk-modal-dialog.custom-modal {
        ..
    }
    .modal-svg {
        position: absolute;
        top: 0;
        left: 0;
        height: 100%;
        width: 100%;
        border-radius: 3px;
        rect {
            stroke: #fff;
            stroke-width: 2px;
            stroke-dasharray: 976; // total of dialog width and height (not sure what value to add)
            stroke-dashoffset: 976;
        }
    }
    amp;.uk-open>.uk-modal-dialog.custom-modal {
        .. 
        .modal-svg {
            rect {
                animation: sketchIn .5s .3s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards; // animation is not smooth
            }
        }
    }
}

@keyframes sketchIn {
    0% {
        stroke-dashoffset: 976;
    }
    100% {
        stroke-dashoffset: 0;
    }
}
 

Ответ №1:

Вы неправильно рассчитали длину периметра прямоугольника

Если это грубо, то вам нужно это учитывать (width height) * 2 = 1952px

Метод JS getTotalLength() поможет вам точно рассчитать периметр с учетом округлений.

Произошло с округлением ~= 1946px

 .modal-svg {
        position: absolute;
        top: 0;
        left: 0;
        
        border-radius: 3px;
        }
        rect {
            stroke: silver;
            stroke-width: 6px;
            stroke-dasharray: 1946; // total of dialog width and height (not sure what value to add)
            stroke-dashoffset: 1946;
            animation: sketchIn 5s .3s cubic-bezier(0.165, 0.840, 0.440, 1.000) forwards; // animation is not smooth
            }
        @keyframes sketchIn {
    0% {
        stroke-dashoffset: 1946;
    }
    100% {
        stroke-dashoffset: 0;
    }
}
     
 <div id="modal-close-default" class="uk-modal">
   <div class="uk-modal-dialog custom-modal six uk-modal-body lab-border-7 uk-margin-auto-vertical">
   
      <svg class="modal-svg" xmlns="http://www.w3.org/2000/svg"  viewBox="0 0 600 376" width="600" height="376"  >
         <rect id="rect" x="0" y="0" fill="none" width="600" height="376" rx="3" ry="3"></rect>
      </svg>
   </div>
</div> 
<script>
let total = rect.getTotalLength();
console.log(total)
</script>