[D3.js] 예제 Transform Transitions 공부

in #dclick5 years ago (edited)

[D3.js] 예제 Transform Transitions 공부



D3.js로 복귀하면서 예제들을 살펴보다가 재미있는 색상 팔레트가 있어서 한번 소스를 분석해 보았네요. 그리고 몇가지 형태로 수정도 해보았는데 수정 된 내용은 위 링크가 예제의 저작물 라이센서에서는 수정배포는 금지되어 있기 때문에 수정한 코딩은 post에 담지 못한점이 아쉽네요. 하지만 전혀 다른 내용으로 여기서 공부한 원리를 기반으로 간단히 공부차원으로 Tic-Tac-Toe game을 만들어 보았습니다. 그러면 한번 살펴보도록 하죠.

1. Mike Bostock’s Block의 색상 팔레트 예제



[출처 소스]

<!DOCTYPE html>
<meta charset="utf-8">
<style>

body {
  margin: 0;
}

div { //색상 팔레트 사각크기
  position: absolute;
  width: 20px;
  height: 20px;
  border: solid 1px #fff;
}

</style>
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>

var z = 20,
    x = 960 / z,
    y = 500 / z;

d3.select("body").selectAll("div")
    .data(d3.range(x * y))
  .enter().append("div")
    .style("transform", function(d) { return "translate(" + (d % x) * z + "px, " + Math.floor(d / x) * z + "px)"; }) //div 태그 위치
    .style("background-color", function(d) { return d3.hsl(d % x / x * 360, 1, Math.floor(d / x) / y); }) //div 태그 배경색
    .on("mouseover", mouseover); //마우스 이벤트

function mouseover(d) { //마우스를 가져다 대면 이벤트 발생
  d3.select(this)
      .style("pointer-events", "none") //딱 한번만 수행
      .raise() //기존 div태그들에서 현재 div 태그가 제일 앞으로 위치
    .transition()
      .duration(750)
      .style("transform", "translate(480px, 240px) scale(20) rotate(180deg)") //이동, 사각크기, 회전
    .transition()
      .delay(1500)
      .style("transform", "translate(480px, 240px) scale(0.01)") 
      .remove(); //제거
}
</script>

위 주석부분만 이해하시면 됩니다. 이 예제의 핵심은 translate()인데 이 원리를 잘 이해하면 재밌는 것들을 만들 수 있네요.

[결과]

응용편 : 원상복구


여기 예제를 보시면 가운데로 크게 사각형이 완성되었다가 가운데에서 다시 작어지면서 소멸 됩니다.

현재의 위치로 다시 돌아가고 싶다면 어떻게 해야 할까요. mouseover()함수 내부의 코딩을 수정해야 합니다. 0.75초동안 먼저 가운데로 사각형이 커지면서 이동하다가 1.5초동안 가운데로 사각형이 작아지면 remove()하여 제거 됩니다.
다시 돌아가고 싶다면 원래 있던 위치로 돌아가야 한다면 그 부분은 어디일까요. 바로 처음에 div 사각형이 그려지는 위치가 되겠죠.

   .style("transform", function(d) { return "translate(" + (d % x) * z + "px, " + Math.floor(d / x) * z + "px)"; }) //div 태그 위치

이 부분을 커지고 나서 다시 작아지는 코딩부분에 동작하게 하면 되겠죠. 그러면 원래 있던 위치로 돌아갑니다. 이렇게 하고 마무리 하면 문제가 생깁니다.

.style("pointer-events", "none") 

이 부분은 한번 마우스 이벤트가 발생하면 다시 마우스를 해당 div에 이동시켜도 mouseover 이벤트가 발생하지 않습니다. 이부분을 삭제하면 정상적으로 커졌다 작아졌다 하는 동작을 수행하네요.

수정 소스는 저작권내용에 의해 수정본의 코딩은 못올리게 되어 있네요. 영상만 보여드리면 이렇게 동작하네요.


여러분들이 수정할 위치에 잘 삽입하여 원본 소스를 실행시켜 보세요.

응용편 : 클릭 이벤트 후 해당 색상값 출력


만약 이렇게 만든다면 어떻게 해야 할까요.
mouse 이벤트 부분을 Click이벤트로만 바꾸면 됩니다.

위 결과처럼 나올려면 text()함수를 html 태그에 묶어서 클릭이벤트가 수행되는 곳에다가 넣으면 위 그림처럼 출력되는데 수정 코드는 아쉽게 수정본은 못올리네요. 원 저작물의 코딩만 자세히 보시고 이해하시면 쉽게 수정이 됩니다. 이 수정 코딩도 못올립니다. 그래서 영상만으로 어떻게 표현했는지만 보여드려요.

2. Tic-Tac-Toe game 만들기


그냥 이상태로 마무리 하면 아쉬워서 뭔가 코딩하는 실험을 보여 드려야겠다는 생각에 게임을 표현해보면 좋을 것 같아서 한번 간단히 구현만 해보았네요. 완벽하지는 않고 수동으로 2인용이고 간단히 한판만 진행되게 했네요. 원래는 2차원 배열까지 해서 클릭한 정보를 저장하고 체크하고 게임의 승패를 자동을 처리해야 하는데 그 부분은 뺐습니다. 그냥 오늘 공부한 내용의 원리를 기반으로 게임에 응용을 해 보았네요.

<!DOCTYPE html>
<meta charset="utf-8">
<style>

div {
  position: absolute;
  width: 60px;
  height: 60px;
  font-size: 60px;
  color: white;
  border: 1px solid powderblue;
  padding: 20px;
}

</style>
<body>
 <script src="https://d3js.org/d3.v5.min.js"></script>
<script>

var x = 3, y = 3, z = 100;
var state =0;

d3.select("body").selectAll("div")
    .data(d3.range(x*y))
  .enter().append("div")
    .style("transform", function(d) { return "translate(" + ((d % x) * z+50) + "px, " + (Math.floor(d / x) * z+50) + "px)"; })
    .style("background-color", "yellow")
    .on("click",  click);
    

function click(d) {
 var ox = d3.select(this)
      .style("pointer-events", "none")
      .raise()
    .transition()
      .duration(900)
      .style("transform", "translate(150px, 150px) scale(3) rotate(180deg)")
    .transition()
      .delay(1500)
      .style("transform", function(d) { return "translate(" + ((d % x) * z+50) + "px, " + (Math.floor(d / x) * z+50) + "px)"; })  
  
  if(state==0){ 
   ox.style("background-color", "blue")
   .text("O")
    state=1;
  }
  else{ 
   ox.style("background-color", "red")
   .text("X") 
   state=0;
  }
}
</script>

소스는 3x3 크기의 사각형을 만들고 사각형의 기본 베이스 속성은 Style로 CSS로 외부에서 지정했는데 아래와 같이 코딩했네요.

div {
  position: absolute;
  width: 60px;
  height: 60px;
  font-size: 60px;
  color: white;
  border: 1px solid powderblue;
  padding: 20px;
}

다음 게임을 진행한 게임판을 만들어야 겠죠.

d3.select("body").selectAll("div")
    .data(d3.range(x*y))
  .enter().append("div")
    .style("transform", function(d) { return "translate(" + ((d % x) * z+50) + "px, " + (Math.floor(d / x) * z+50) + "px)"; })
    .style("background-color", "yellow")
    .on("click",  click);

style로 그려지 위치와 배경색을 지정했고 클릭 이벤트로 게임을 진행합니다.

클릭한 곳에 O,X를 글자가 출력되도록 코딩하면 다음과 같습니다.

function click(d) {
 var ox = d3.select(this)
      .style("pointer-events", "none") //한번만 클릭 허용
      .raise() // 맨앞으로 이동
    .transition()
      .duration(900) 
      .style("transform", "translate(150px, 150px) scale(3) rotate(180deg)") //클릭 효과 모션
    .transition()
      .delay(1500)
      .style("transform", function(d) { return "translate(" + ((d % x) * z+50) + "px, " + (Math.floor(d / x) * z+50) + "px)"; })  //원래 위치로 이동
  
  if(state==0){  //첫번째 클릭 O 글자 출력
   ox.style("background-color", "blue")
   .text("O")
    state=1;
  }
  else{ //두번째 클릭 X글자 출력
   ox.style("background-color", "red")
   .text("X") 
   state=0;
  }
}

O, X 글자 출력으로 두사람이 마우스로 교대로 클릭하면서 3x3 게임판에 O,X를 만든다.

[결과]
따로 게임상태를 체크하는 코딩은 없습니다. 단순히 O,X만 표시만 됩니다.

마무리


원래는 색상 팔레트를 가지고 약간 수정해서 응용력을 키우는 실험을 해보고 싶어 post를 만들었는데 저작 라이센스 내용을 보니 기존 내용은 출처를 밝히고 배포가 가능하지만 수정하면 안된다고 나오 있는 것 같더군요. 그래서 수정하여 응용력 실험을 한 코딩은 공개가 불가능하게 되어 게임을 급하게 만들어 봤네요. 게임이 좀 조잡하고 미완성 이지만 그래도 게임을 할 수는 있습니다.


Sponsored ( Powered by dclick )

dclick-imagead

Sort:  

짱짱맨 호출에 응답하여 보팅하였습니다. 즐거운 주말 보내세요.

방문감사합니다. 즐거운 주말 되세요.

보클하고갑니다^^

Posted using Partiko Android

감사합니다.

알록달록하니 시각자극이 되서 좋아요~~

실력만 되면 더 많은 것들을 표현하고 싶은데 아직 배우는 입장이라 갈길이 머네요.

색상을 찍어 바르는 저로썬 놀라움이고, 어렵고 그러네요.
E1DDD387-C621-4762-9A3D-C8C84EB2864E.jpeg

이게 코딩에서는 기초적인 부분인데 이제 공부를 열심히 하고 있네요.

화려하네요

d3.js 기반 시각화 차트들이 진짜 화려한 것들이 많은 것 같아요.
매일 해당 사이트의 갤러리를 보면서 감탄하네요.

저에게는 너무 어려운 내용들입니다~ ㅋㅋㅋ

저도 d3.js는 기초부분부터 공부하는 입장이라 열심히 배우고 있네요.

좋아요 부러워요..

감사합니다.

제가 사용하는 색상 팔레트와 많이 다르네용. ㅎㅎ

Coin Marketplace

STEEM 0.32
TRX 0.11
JST 0.034
BTC 66654.57
ETH 3250.95
USDT 1.00
SBD 4.33