programing

변경의 원인이 되는 클릭 이벤트와 관련된 ng-repeat 항목을 애니메이션화하는 방법

itsource 2023. 3. 8. 23:24
반응형

변경의 원인이 되는 클릭 이벤트와 관련된 ng-repeat 항목을 애니메이션화하는 방법

여러 항목 집합에서 항목을 선택하는 사용자를 애니메이션으로 만들려고 합니다.선택한 항목 목록의 새 위치에 클릭된 집합에서 항목이 애니메이션으로 표시됩니다.

아래 데모에서는 분홍색 상자를 사용 가능한 항목으로 간주하고 테두리 상자를 선택한 항목 목록(파란색 상자)으로 간주합니다.사용자는 다음 중 하나의 분홍색 상자를 클릭하여 항목을 선택할 수 있습니다.

angular.module('test', ['ngAnimate'])
  .controller('testCtrl', function($scope) {
    $scope.products = [{}, {}, {}, {}];
    $scope.purchased = [{}];
    $scope.purchase = function(dir) {
      $scope.direction = dir
      $scope.purchased.push($scope.products.pop());
    };
  })
  .directive('testDir', function($animate) {
    return {
      link: function(scope, element) {
        $animate.on('enter', element, function(element, phase) {
          $target = scope.direction == 'left' ? $('.stock:first') : $('.stock:last');
          element.position({
            my: 'center',
            at: 'center',
            of: $target,
            using: function(pos, data) {
              $(this).css(pos);
              $(this).animate({
                top: 0,
                left: 0
              });
            }
          });
        });
      }
    };
  });
.stock {
  display: inline-block;
  width: 50px;
  height: 50px;
  background: hotpink;
}
.stock.right {
  margin-left: 100px;
}
.product {
  height: 50px;
  width: 50px;
  border: 1px solid;
}
.purchased {
  height: 60px;
  margin-top: 100px;
  border: 2px dotted;
}
.purchased .product {
  display: inline-block;
  margin: 5px;
  background: dodgerblue;
}
<script src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script src="https://code.angularjs.org/1.4.8/angular-animate.js"></script>
<div ng-app="test" ng-controller="testCtrl">
  <div class="stock" ng-click="purchase('left')"></div>
  <div class="stock right" ng-click="purchase('right')"></div>
  <div class="purchased clearfix">
    <div class="product" ng-repeat="product in purchased" data-test-dir>
    </div>
  </div>
</div>


어느 정도 효과가 있지만, 저는 jQuery-ui를 사용하여 시작 위치(핑크 박스의 위치는 반응하는 디자인으로 경계합니다)와 jquery 애니메이션 방법을 사용하여 요소를 애니메이션화합니다.

또한 클릭된 방향을 스코프에 저장해야 하며 초기 위치와 애니메이션을 둘 다 설정하고 있습니다.enter이벤트 리스너

애니메이션 훅을 비스듬히 삽입한 상태에서 읽고 실험을 많이 해봤지만 상대/동적인 위치에서 요소를 애니메이션화하는 적절한 방법을 찾을 수 없었습니다.

angular js 방식으로 동일한 사용자 경험을 얻을 수 있는 더 좋은 방법이 있을까요??

질문을 올바르게 이해한 경우(그렇지 않은 경우) 문제를 해결하는 방법 중 하나는 다음과 같습니다.

제품의 크기(폭)가 일정하다고 가정하면서 - 50px 또는 다른 것으로 설정 - 핑크 요소의 위치를 absolute로 설정할 수 있습니다.그리고 핑크 요소의 경우 ng-module을 사용하여 다음과 같은 간단한 ng-style 속성을 html에 포함시킵니다.

<div ng-repeat="item in products" ng-style="{'left': $index*50 + 'px'}" ng-click="add-to-purchased($index)"></div>

구입하신 제품에 대해서: "접속" 어레이에 ng-to-to-time을 사용하는 대신 "접속" 어레이에 제품을 푸시한 후 "상단: 경계 요소까지의 거리"와 {$time}에 제품을 애니메이션으로 만들 수 있습니다.구입했습니다.length*50 + 'px'}.그런 다음 컬러링 및 기타 css 항목에 ng-class(토글 포함)를 사용하여 클래스를 추가합니다.(색상의 변경에 대해서도 이행을 검토할 수 있습니다.아시겠지만)

또한, 다른 높이와 상단(제품)에 따라 다른 높이와 접점을 추가할 수 있다고 생각합니다. (Top) 값을 기준으로 다른 클래스) 값을 추가할 수 있다고 생각합니다.잘 지내세요....

이게 도움이 됐으면 좋겠다


업데이트:

불행히도 나는 질문을 잘 이해하지 못했지만, 지금 문제를 보면 이것을 좀 더 역동적으로 할 수 있는 방법이 있을 것 같다.

내 the의 $scope.purchasefunction, function으로 수 .$broadcast클릭된 요소를 다음과 같이 전달합니다(재고 있는 요소의 경우 ng-module로 작성되었는지 여부에 관계없이).

<div class="stock" ng-click="purchase($event)"></div>

또, 다음과 같이 합니다.

$scope.purchase = function(event) {
  $scope.purchased.push($scope.products.pop());
  $scope.$broadcast('purchaseHappened', event.target);
};

지시문 안에 이벤트 청취자를 넣습니다.

scope.$on('purchaseHappened', function(event, target) {
     //catch target in here, and then use it's position to animate the new elements...
})

쓰실 수 것 같아요.target.getBoundingClientRect().top,.leftjquery-ui가 .position★★★★★★★★★★★★…

솔루션에 가까운가?

이 솔루션은 구매 기능에서 스코프에 정보를 추가할 필요가 없으며 "소스" 디렉티브를 사용하여 컨트롤러 속성에 원본 정보를 저장함으로써 모델 데이터와 UI 세부 정보가 혼재되지 않는다는 점에서 개선되었습니다.이 예는 단순화되고 물론 개선될 수 있습니다.중요한 점은 프로세스를 관리하는 데 필요한 데이터는 범위를 통해 노출되지 않는다는 것입니다.

대상 요소가 DOM에서 삭제될 경우(즉, ng-repeat의 일부), 애니메이션 시작 위치를 계산하고 모니터의 일부로 저장하기 위해 이 솔루션을 약간 수정해야 합니다.대상 요소 자체를 저장하지 말고 핸들러를 클릭하십시오.

애니메이션 제작 방식은 제멋대로인 것 같아요.이 예에서는 OP의 jquery를 사용합니다.UI 애니메이션 방식이지만 css 전환이나 $animate 사용 시에도 동일하게 작동합니다.

완전한 예는 다음과 같습니다.

angular.module('app', [])
.controller('main', function($scope) {
  $scope.products = [{},{}];
  $scope.purchased = [{}];
  $scope.Purchase = function() {
    $scope.purchased.push({});
  };
})
.directive('source', function(){
  return {
    controller: function($scope) {
    }
  };
})
.directive('originator', function(){
  return{
    require: '^source',
    priority: 1,
    link:{
      pre: function(scope, element, attr, ctrl){
        element.on('click', function(evt){
          ctrl.target = evt.target;    
        });
      } 
    }
  };
})
.directive('sink', function(){
  return {
    require: '^source',
    link: function(scope, element, attr, ctrl){
      var target = ctrl.target;
      if(target){
        var $target = $(target);
        //animate from target to current position
        element.position({
            my: 'center',
            at: 'center',
            of: $target,
            using: function(pos, data) {
              $(this).css(pos);
              $(this).animate({
                top: 0,
                left: 0
              });
            }
          });
        ctrl.target = undefined;
      }
    }
  };
});

언급URL : https://stackoverflow.com/questions/34875771/how-to-animate-ng-repeat-items-relative-to-click-events-causing-the-change

반응형