티스토리 뷰

Private

OpenLayers Animation

wldnjd2 2022. 4. 15. 11:12

OpenLayers를 공부하면서  Animation이 뭔지 감이 안왔는데, 

오픈레이어즈 사이트에서 예시를 보니까 animation이 뭔지 감이 왔다.

역시 글로 봐서 이해가 안될때 실행결과랑 코드를 먼저 보는게 더 이해가 빠른것 같다.

 

https://openlayers.org/en/latest/examples/animation.html

 

View Animation

Demonstrates animated pan, zoom, and rotation. This example shows how to use the view.animate() method to run one or more animations.

openlayers.org

 

OpenLayers에서 Animation은 지도를 동적으로 움직여 애니메이션 효과를 주는것을 말한다.

사이트의 예제 코드를 살펴보자.

 

                                          

main.js
import 'ol/ol.css';
import Map from 'ol/Map';
import OSM from 'ol/source/OSM';
import TileLayer from 'ol/layer/Tile';
import View from 'ol/View';
import {easeIn, easeOut} from 'ol/easing';
import {fromLonLat} from 'ol/proj';

//각 나라의 좌표를 변수에 지정
const london = fromLonLat([-0.12755, 51.507222]);
const moscow = fromLonLat([37.6178, 55.7517]);
const istanbul = fromLonLat([28.9744, 41.0128]);
const rome = fromLonLat([12.5, 41.9]);
const bern = fromLonLat([7.4458, 46.95]);

//시작화면 view 변수에 좌표 지정
const view = new View({
  center: istanbul,
  zoom: 6,
});

//맵생성
const map = new Map({
  target: 'map',
  layers: [
    new TileLayer({
      preload: 4,
      source: new OSM(),
    }),
  ],
  view: view,		//이스탄불 센터
});

//이게 뭐야ㅡㅡ
function bounce(t) {
  const s = 7.5625;
  const p = 2.75;
  let l;
  if (t < 1 / p) {
    l = s * t * t;
  } else {
    if (t < 2 / p) {
      t -= 1.5 / p;
      l = s * t * t + 0.75;
    } else {
      if (t < 2.5 / p) {
        t -= 2.25 / p;
        l = s * t * t + 0.9375;
      } else {
        t -= 2.625 / p;
        l = s * t * t + 0.984375;
      }
    }
  }
  return l;
}

// An elastic easing method (from https://github.com/DmitryBaranovskiy/raphael).
function elastic(t) {
  return (
    Math.pow(2, -10 * t) * Math.sin(((t - 0.075) * (2 * Math.PI)) / 0.3) + 1
  );
}

//onClick 메서드
function onClick(id, callback) {
  document.getElementById(id).addEventListener('click', callback);
}


onClick('rotate-left', function () {
  view.animate({
    rotation: view.getRotation() + Math.PI / 2,
  });
});

onClick('rotate-right', function () {
  view.animate({
    rotation: view.getRotation() - Math.PI / 2,
  });
});

onClick('rotate-around-rome', function () {
  // Rotation animation takes the shortest arc, so animate in two parts
  const rotation = view.getRotation();
  view.animate(
    {
      rotation: rotation + Math.PI,
      anchor: rome,
      easing: easeIn,
    },
    {
      rotation: rotation + 2 * Math.PI,
      anchor: rome,
      easing: easeOut,
    }
  );
});

onClick('pan-to-london', function () {
  view.animate({
    center: london,
    duration: 2000,
  });
});

onClick('elastic-to-moscow', function () {
  view.animate({
    center: moscow,
    duration: 2000,
    easing: elastic,
  });
});

onClick('bounce-to-istanbul', function () {
  view.animate({
    center: istanbul,
    duration: 2000,
    easing: bounce,
  });
});

onClick('spin-to-rome', function () {
  // Rotation animation takes the shortest arc, so animate in two parts
  const center = view.getCenter();
  view.animate(
    {
      center: [
        center[0] + (rome[0] - center[0]) / 2,
        center[1] + (rome[1] - center[1]) / 2,
      ],
      rotation: Math.PI,
      easing: easeIn,
    },
    {
      center: rome,
      rotation: 2 * Math.PI,
      easing: easeOut,
    }
  );
});

function flyTo(location, done) {
  const duration = 2000;
  const zoom = view.getZoom();
  let parts = 2;
  let called = false;
  function callback(complete) {
    --parts;
    if (called) {
      return;
    }
    if (parts === 0 || !complete) {
      called = true;
      done(complete);
    }
  }
  view.animate(
    {
      center: location,
      duration: duration,
    },
    callback
  );
  view.animate(
    {
      zoom: zoom - 1,
      duration: duration / 2,
    },
    {
      zoom: zoom,
      duration: duration / 2,
    },
    callback
  );
}

onClick('fly-to-bern', function () {
  flyTo(bern, function () {});
});

function tour() {
  const locations = [london, bern, rome, moscow, istanbul];
  let index = -1;
  function next(more) {
    if (more) {
      ++index;
      if (index < locations.length) {
        const delay = index === 0 ? 0 : 750;
        setTimeout(function () {
          flyTo(locations[index], next);
        }, delay);
      } else {
        alert('Tour complete');
      }
    } else {
      alert('Tour cancelled');
    }
  }
  next(true);
}

onClick('tour', tour);

 

 

 

index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>View Animation</title>
    <!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
    <script src="https://unpkg.com/elm-pep@1.0.6/dist/elm-pep.js"></script>
    <!-- The lines below are only needed for old environments like Internet Explorer and Android 4.x -->
    <script src="https://cdn.polyfill.io/v3/polyfill.min.js?features=fetch,requestAnimationFrame,Element.prototype.classList,TextDecoder"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/3.18.3/minified.js"></script>
    <style>
      .map {
        width: 100%;
        height:400px;
      }
    </style>
  </head>
  <body>
    <div id="map" class="map"></div>
    <button id="rotate-left" title="Rotate clockwise">↻</button>
    <button id="rotate-right" title="Rotate counterclockwise">↺</button>
    <button id="pan-to-london">Pan to London</button>
    <button id="elastic-to-moscow">Elastic to Moscow</button>
    <button id="bounce-to-istanbul">Bounce to Istanbul</button>
    <button id="spin-to-rome">Spin to Rome</button>
    <button id="fly-to-bern">Fly to Bern</button>
    <button id="rotate-around-rome">Rotate around Rome</button>
    <button id="tour">Take a tour</button>
    <script src="main.js"></script>
  </body>
</html>

 

 

 

Callback function

오픈레이어즈를 공부하면서 종종 나오는  callback이 무슨 말인지 이해가 안됐다. (기본기가 하나도 없어서 ㅠㅜ)

callback function

어떤 이벤트가 발생한 후, 수행될 함수를 의미한다.

콜백함

 

 

 


Ref.

아래 블로그에서 애니메이션 공부좀 하기...

https://lts0606.tistory.com/208

 

Openlayers Flight Animation (오픈레이어스 항공 애니메이션, Openlayers 항공 애니메이션, Openlayers 비행

이번엔 비행기가 지나가는 노선도 효과의 에니메이션 입니다. 레이어는 항상 사용하던 기본 OSM 레이어를 사용 하였습니다. 일단, 시작점과 끝점이 존재하는 배열을 생성 하였습니다. 출발나라

lts0606.tistory.com

 

'Private' 카테고리의 다른 글

20220418~ cav study  (0) 2022.04.19
OpenLayers 응용해보기  (0) 2022.04.14
댓글