웹개발 자료실/프론트GUI 개발Code

「zim.js」 유투브 추천수 조작하기(feat.합성)

Recstasy 2021. 7. 30. 05:55

 

zim.js로 유투브 추천수를 조작하는 합성툴을 제작해보자.

결과는 아래와 같으며, 사실상 포토샵 합성과 같은 방식이다. 

(추천 알고리즘을 조작하는 것은 불가능)

 

 

 

 

「구현 단계」

 

1] 컨테이너 생성

2] 이미지 소스 불러오기

3] Stepper( )생성

 

사실상 Stepper( )가 핵심이다.

 

 

 

|구현

먼저 컨테이너와 소스를 불러온다.

 

//생략...
      const pic = frame.asset("img%2FUtub.jpg?alt=media&token=2275f068-289a-4e08-b4f5-44176b0b2ab3")
                  .centerReg(stage)
                  .sca(.7)
                  .drag({onTop:false});

      const panel = new Container()
                    .pos(30, 30);

      new Rectangle(200, 200, dark).addTo(panel);

 

Stepper( )를 생성하고, Stepper( )의 하위구조에 Label( )을 붙여준다.

 

      new Stepper({
          stepperType : 'number',
          max : 999
      })
      .sca(.2)
      .center(panel)
      .mov(0, -50)
      .change((e)=>{
          likes.text = e.target.currentValue;
          stage.update();
      })

      const likes = new Label({
          text : 0,
          color : "#5f5f5f",
          backgroundColor : "#f9f9f9" 
      }).center(panel)
        .mov(0 , 50)
        .sca(.29)
        .drag();
     
     //생략...

 

 

 

|이미지 업로드 & 저장

자체 이미지가 아닌 사용자가 직접 합성할 이미지를 업로드하고 저장하기 위해서는

'Loader', 'Cropper'가 필요하다.

 

위의 코드에서 aseets, path부분을 삭제하고,

새 컨테이너를 생성한 뒤 panel을 위치시킨다.

 

//생략...

      const holder = new Container(stageW, stageH).addTo(stage);
      const loader = new Loader().center(stage).mov(110);
            loader.on("loaded", e =>{
                loader.removeFrom();
                let pic = e.bitmap.center(holder).sca(.7).bot().centerReg(holder).drag({onTop:false});
                stage.update();
            })

      const panel = new Container()
                    .loc(30, 30, holder);

      new Rectangle(200, 350, dark).addTo(panel);
      
 //생략...
       new Button({label:'SAVE'})
          .sca(.3)
          .pos(20, 20, CENTER, BOTTOM, panel)
          .mov(-19,5)
          .tap(()=>{
              loader.save(holder, 'youtube', cropper.x, cropper.y, cropper.width, cropper.height);
          })


 //생략...

 

loader관련 메서드와 이벤트 처리 부분은 zim.js의 문서에서 확인할 수 있다.

https://zimjs.com/docs.html

 

업로드 가능한 파일종류에는

이미지(bitmap)뿐만 아니라 텍스트, json파일도 포함된다.

 

그리고 Stepper, Label의 불필요한 반복을 피하기 위해서는

아래와 같이 Tile( ) + Series( )조합을 사용할 수 있다.

 

//생략...
      const nums = new Tile(
        series(
            new Stepper({stepperType:'number', max:999}),
            new Label({text:'0', color:'#5f5f5f', backgroundColor:'#f9f9f9'}).sca(.9)
        ),
        1, 6, 0, 30
      ).sca(.3).center(panel).mov(0,30);


      nums.getChildAt(0).on('change', setNum);
      nums.getChildAt(2).on('change', setNum);
      nums.getChildAt(4).on('change', setNum);

      nums.getChildAt(1).drag({onTop:false});
      nums.getChildAt(3).drag({onTop:false});
      nums.getChildAt(5).drag({onTop:false});


      function setNum(e){
          let stepper = e.target;
          let label = nums.getChildAt(stepper.tileNum+1);
          label.text = stepper.currentValue;
          stage.update();
      }

      new Label({text:'YOUTUBE\nEditor', color:white})
                .sca(.7)
                .center(panel)
                .pos(null, 30);


      const cropper = new Rectangle(300, 300, null, red, 5, 0, true, {ignoreScale:true})
                      .center(stage)
                      .mov(120)
                      .transform({allowToggle:false, rotate:false, showReg:false});

//생략...

 

Tile( )의 첫번째 파라미터값은 객체이며,

2, 3번째 값은 각각 '행'과 '열'이다.

 

따라서 Stepper, Label은 1행, 6열(3회 반복)로 나열되고,

배열의 index값은 0~5이다.

 

위의 코드에서는 .getChildAt( )메서드에서 Tile내의 Stepper, Label의 인덱스 값을 받아서

setNum함수로 넘겨준다.

 

https://createjs.com/docs/easeljs/classes/Stage.html

 

setNum함수는 Stepper숫자의 값을 받아서

Label의 텍스트 값으로 넘겨준다.

 

위의 코드를 실행했을 때,

아래와 같이 업로드 된 이미지의 추천수를 조작한 뒤

저장할 수 있는 간단한 앱을 구현할 수 있다.

 

 

 

 

[구현]

 

 

 

1. 숫자를 올린다(좌측 Stepper)

2. 숫자 라벨을 이미지 추천수로 이동한다

3. 저장한다