я хочу, чтобы SVG Elasti c Border изменил горизонтальный эффект - PullRequest
1 голос
/ 18 июня 2020

Я хочу использовать одну анимацию svg, но в настоящее время она находится по вертикали, я хочу двигаться по горизонтали, мне нравится этот эффект и svg, но только я хочу двигаться по горизонтали.

Мне нравится эффект и не нужно никаких изменений в этой анимации, мне нужно только, чтобы эта анимация запускалась слева направо, а не сверху вниз.

  
  (function() {

    // Variables to use later
    var rangeWrapper = document.querySelector('.range__wrapper');
    var rangeInput = document.querySelector('.range__input');
    var rangeValues = document.querySelector('.range__values');
    var rangeValueNumberTop = document.querySelector('.range__value__number--top');
    var rangeValueNumberBottom = document.querySelector('.range__value__number--bottom');
    var rangeSliderPaths = document.querySelectorAll('.range__slider__path');
	var svgWidth = window.innerWidth;
	var svgHeight = window.innerHeight
    var mouseX = 0;
    var mouseY = 0;
    var mouseInitialY = 0;
    var mouseDy = 0;
    var mouseDyLimit = 150;
    var mouseDyFactor = 3;
    var max = 100;
    var rangeMin = parseInt(rangeInput.min);
    var rangeMax = parseInt(rangeInput.max);
    var rangeValue = parseInt(rangeInput.value);
    var rangeHeight = svgHeight;
    var currentY = rangeHeight * rangeValue / max;
    var rangeMinY = rangeHeight * rangeMin / max;
    var rangeMaxY = rangeHeight * rangeMax / max;
    var scaleMax = 0.32;
    var scale, newPath, newY, newSliderY, lastMouseDy, rangeWrapperLeft, pageX, pageY;



    // Update slider value, initially using the `input` value
    updateValue();

    // Function to build the slider `path`, using the given `dy` and `ty` values
    function buildPath(dy, ty) {
        return 'M 0 ' + ty + ' q ' + mouseX + ' ' + dy + ' ' + svgWidth + ' 0 l 0 ' + svgHeight + ' l -' + svgWidth + ' 0 Z'; 	
    }

    // Function to update the slider value
    function updateValue() {
        // Clear animations if are still running
        anime.remove([rangeValues, rangeSliderPaths[0], rangeSliderPaths[1]]);

        // Calc the `input` value using the current `y`
        rangeValue = parseInt(currentY * max / rangeHeight);
        // Calc `scale` value for numbers
        scale = (rangeValue - rangeMin) / (rangeMax - rangeMin) * scaleMax;
        // Update `input` value
        rangeInput.value = rangeValue;
        // Update numbers values
        rangeValueNumberTop.innerText = max - rangeValue;
        rangeValueNumberBottom.innerText = rangeValue;
        // Translate range values
        rangeValues.style.transform = 'translateY(' + (rangeHeight - currentY) + '%)';
        // Apply corresponding `scale` to numbers
        rangeValueNumberTop.style.transform = 'scale(' + (1 - scale) + ')';
        rangeValueNumberBottom.style.transform = 'scale(' + (1 - (scaleMax - scale)) + ')';

        // Some maths calc
        if (Math.abs(mouseDy) < mouseDyLimit) {
            lastMouseDy = mouseDy;
        } else {
            lastMouseDy = mouseDy < 0 ? -mouseDyLimit : mouseDyLimit;
        }

        // Calc the `newSliderY` value to build the slider `path`
        newSliderY = currentY + lastMouseDy / mouseDyFactor;
        if (newSliderY < rangeMinY || newSliderY > rangeMaxY) {
            newSliderY = newSliderY < rangeMinY ? rangeMinY : rangeMaxY;
        }

        // Build `path` string and update `path` elements
        newPath = buildPath(lastMouseDy, rangeHeight - newSliderY);
        rangeSliderPaths[0].setAttribute('d', newPath);
        rangeSliderPaths[1].setAttribute('d', newPath);
    }

    // Function to simulate the elastic behavior
    function elasticRelease() {
        // Morph the paths to the opposite direction, to simulate a strong elasticity
        anime({
            targets: rangeSliderPaths,
            d: buildPath(-lastMouseDy * 1.3, rangeHeight - (currentY - lastMouseDy / mouseDyFactor)),
            duration: 150,
            easing: 'linear',
            complete: function () {
                // Morph the paths to the normal state, using the `elasticOut` easing function (default)
                anime({
                    targets: rangeSliderPaths,
                    d: buildPath(0, rangeHeight - currentY),
                    duration: 4000,
                    elasticity: 880
                });
            }
        });

        // Translate the values to the opposite direction, to simulate a strong elasticity
        anime({
            targets: rangeValues,
            translateY: rangeHeight - (currentY + lastMouseDy / mouseDyFactor / 4),
            duration: 150,
            easing: 'linear',
            complete: function () {
                // Translate the values to the right position, using the `elasticOut` easing function (default)
                anime({
                    targets: rangeValues,
                    translateY: rangeHeight - currentY,
                    duration: 4000,
                    elasticity: 880
                });
            }
        });
    }

    // Handle `mousedown` and `touchstart` events, saving data about mouse position
    function mouseDown(e) {
        mouseY = mouseInitialY = e.targetTouches ? e.targetTouches[0].pageY : e.pageY;
        rangeWrapperLeft = rangeWrapper.getBoundingClientRect().left;
    }

    // Handle `mousemove` and `touchmove` events, calculating values to morph the slider `path` and translate values properly
    function mouseMove(e) {
        if (mouseY) {
            pageX = e.targetTouches ? e.targetTouches[0].pageX : e.pageX;
            pageY = e.targetTouches ? e.targetTouches[0].pageY : e.pageY;
            mouseX = pageX - rangeWrapperLeft;
            mouseDy = (pageY - mouseInitialY) * mouseDyFactor;
            newY = currentY + mouseY - pageY;
            if (newY >= rangeMinY && newY <= rangeMaxY) {
                currentY = newY;
                mouseY = pageY;
            } else {
                currentY = newY < rangeMinY ? rangeMinY : rangeMaxY;
            }
            // After doing maths, update the value
            updateValue();
        }
    }

    // Handle `mouseup`, `mouseleave` and `touchend` events
    function mouseUp() {
        // Trigger elastic animation in case `y` value has changed
        if (mouseDy) {
            elasticRelease();
        }
        // Reset values
        mouseY = mouseDy = 0;
    }

    // Events listeners
    rangeWrapper.addEventListener('mousedown', mouseDown);
    rangeWrapper.addEventListener('touchstart', mouseDown);
    rangeWrapper.addEventListener('mousemove', mouseMove);
    rangeWrapper.addEventListener('touchmove', mouseMove);
    rangeWrapper.addEventListener('mouseup', mouseUp);
    rangeWrapper.addEventListener('mouseleave', mouseUp);
    rangeWrapper.addEventListener('touchend', mouseUp);


})();
  
 html,
body {
  margin: 0;
  height: 100%;
}
svg {
  display: block;
}
.path {
  animation: dash 10s linear infinite;
}
@-webkit-keyframes dash {
  to {
    stroke-dashoffset: 0;
  }
}
  body {
  background-color: #ffffff;
 
  overflow: hidden;
}

.range__wrapper {
  position: absolute;
  left: 0;
  top: 0;
 /* -webkit-transform: translate(-50%, -50%);
          transform: translate(-50%, -50%);*/
  width: 100%;
  height: 100%;
  background-color: #018fff;
  /*border-radius: 20px;*/
  box-shadow: 0 0 100px rgba(0, 0, 0, 0.2);
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
  cursor: pointer;
  overflow: hidden;
}

.range__input {
  display: none;
}

.range__slider {
  position: absolute;
  left: 0;
  top: 0;
}

.range__slider__path {
  fill: #006cff;
}

.range__marks__path {
  fill: none;
  stroke: inherit;
  stroke-width: 1px;
}

.range__marks__pink {
  stroke: #FF4B81;
}

.range__marks__white {
  stroke: white;
}

.range__values {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
}

.range__value {
  box-sizing: border-box;
  display: -webkit-box;
  display: flex;
  width: 100%;
  padding: 40px 30px;
}

.range__value--top {
  position: absolute;
  bottom: 100%;
  color: #ffffff;
}

.range__value--bottom {
  color: white;
}

.range__value__number {
  font-size: 70px;
  margin: 0 10px;
}

.range__value__number--top {
  -webkit-transform-origin: 100% 100%;
          transform-origin: 100% 100%;
}

.range__value__number--bottom {
  -webkit-transform-origin: 100% 0;
          transform-origin: 100% 0;
}

.range__value__text {
  display: -webkit-box;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
          flex-direction: column;
  font-size: 13px;
  text-transform: uppercase;
}
.range__value__text span:first-child {
  margin-bottom: 3px;
}

.range__value__text--top {
  align-self: flex-end;
  margin-bottom: 13px;
}

.range__value__text--bottom {
  margin-top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"></script>
<div class="range__wrapper">
    <!-- The real input, it will be hidden, but updated properly with Javascript -->
    <!-- For a production usage, you may want to add a label, and also put it inside a form -->
    <input class="range__input" type="range" min="5" max="95" value="64"/>

    <!-- SVG elements -->
    <svg class="range__slider" width="100%" height="100%" viewBox="0">
        <defs>
            <!-- Range marks symbol, it will be reused below -->
            <symbol id="range__marks" shape-rendering="crispEdges">
                <path class="range__marks__path" d="M 257 30 l 33 0"></path>
                <path class="range__marks__path" d="M 268 60 l 22 0"></path>
                <path class="range__marks__path" d="M 278 90 l 12 0"></path>
                <path class="range__marks__path" d="M 278 120 l 12 0"></path>
                <path class="range__marks__path" d="M 278 150 l 12 0"></path>
                <path class="range__marks__path" d="M 278 180 l 12 0"></path>
                <path class="range__marks__path" d="M 278 210 l 12 0"></path>
                <path class="range__marks__path" d="M 278 240 l 12 0"></path>
                <path class="range__marks__path" d="M 278 270 l 12 0"></path>
                <path class="range__marks__path" d="M 278 300 l 12 0"></path>
                <path class="range__marks__path" d="M 278 330 l 12 0"></path>
                <path class="range__marks__path" d="M 278 360 l 12 0"></path>
                <path class="range__marks__path" d="M 278 390 l 12 0"></path>
                <path class="range__marks__path" d="M 268 420 l 22 0"></path>
                <path class="range__marks__path" d="M 257 450 l 33 0"></path>
            </symbol>
            <!-- This clipPath element will allow us to hide/show the white marks properly -->
            <!-- The `path` used here is an exact copy of the `path` used for the slider below -->
            <clipPath id="range__slider__clip-path">
                <path class="range__slider__path" d="M 0 480 l 320 0 l 0 480 l -320 0 Z"></path>
            </clipPath>
        </defs>
        <!-- Pink marks -->
      
        <!-- Slider `path`, that will be morphed properly on user interaction -->
        <path class="range__slider__path" d="M 0 480 l 320 0 l 0 480 l -320 0 Z"></path>
        <!-- Clipped white marks -->
       
    </svg>

    <!-- Range values -->
    <div class="range__values">
        <div class="range__value range__value--top">
            <!-- This element will be updated in the way: `100 - inputValue` -->
            <span class="range__value__number range__value__number--top"></span>
            <!-- Some text for the `top` value -->
            
        </div>
        <div class="range__value range__value--bottom">
            <!-- This element will be updated with the `inputValue` -->
            <span class="range__value__number range__value__number--bottom"></span>
            <!-- Some text for the `bottom` value -->
           
        </div>
    </div>
</div>
...