Coding/JavsScript 삽질기2020. 9. 10. 01:40

자바스크립트를 이용하여 테트리스를 만들고, 이를 Android의 WebView를 이용하여 Android 앱으로 만들어 보았다.

소스코드: github.com/chobocho/JsTetris

 

chobocho/JsTetris

Javascript tetris. Contribute to chobocho/JsTetris development by creating an account on GitHub.

github.com

다운로드: play.google.com/store/apps/details?id=com.chobocho.jstetris

 

Classic Block Game V2 - Google Play 앱

Simple block game

play.google.com

웹 브라우저로 해보기 (크롬에서만 동작 확인을 했습니다)

www.chobocho.com/game/tetris/tetris.html

 

Chobocho's Tetris

 

www.chobocho.com

* 사용키 : 방향키, 스페이스 (블록 아래로 내리기), Ctrl (Hold), S (Start / Resume), P (Pause)

 

Posted by chobocho

댓글을 달아 주세요

Coding/JavsScript 삽질기2020. 1. 13. 01:04

소개 https://chobocho.tistory.com/2461396
실행하기 http://www.chobocho.com/javascript/painter.html
전체 소스코드 https://github.com/chobocho/painter

 

chobocho/painter

Painter written html5. Contribute to chobocho/painter development by creating an account on GitHub.

github.com

9.1 Undo/Redo 기능 구현

Undo/Redo 기능을 구현하기 위해서는 모든 사용자의 동작을 저장해야 합니다

그럼 사용자의 동작을 저장하기 위해서, 선을 그리거나, 원을 그리는 동작을

아래와 같이 커맨드로 정의 해야 합니다.

마우스로 그린 그림

color red 
color lightblue 
rect 8 6 713 356 F 
color white 
ellipse 190 116 93 44 F 
ellipse 456 115 87 42 F 
color black 
ellipse 226 116 31 31 F 
ellipse 489 113 29 30 F 
ellipse 420 277 0 0 F 

그리고 그 커맨드를 stack에 저장합니다.

 

Posted by chobocho

댓글을 달아 주세요

소개 https://chobocho.tistory.com/2461396
실행하기 http://www.chobocho.com/javascript/painter.html
전체 소스코드 https://github.com/chobocho/painter

8.1 저장하기

painter.html에 save를 위한 버튼을 추가 합니다.

<div>
  <a id="saveImage" download="image.png">
      <INPUT type="button" value="Save" onClick="saveImage()" />
  </a>
</div>

그리고, painter.js에 saveImage()함수를 추가합니다.

function saveImage() {
  console.log("saveImage()");
  var imageName = document.getElementById("title").value;
  console.log(imageName.lenght);
  if (imageName.length == 0) {
    imageName = "image";
  }
  imageName += ".png";
  var savedImage = document.getElementById("saveImage");
  var image = document
    .getElementById("canvas")
    .toDataURL("image/png")
    .replace("image/png", "image/octet-stream");
  savedImage.setAttribute("download", imageName);
  savedImage.setAttribute("href", image);
}

여기 까지 소스코드는 아래 링크를 참고 하시면 됩니다.

https://github.com/chobocho/painter/commit/dceabd6f3ace4d39e21260d593dc55a2d15e47df

Posted by chobocho

댓글을 달아 주세요

Coding/JavsScript 삽질기2019. 12. 25. 23:49

소개 https://chobocho.tistory.com/2461396
실행하기 http://www.chobocho.com/javascript/painter.html
전체 소스코드 https://github.com/chobocho/painter

 

chobocho/painter

Painter written html5. Contribute to chobocho/painter development by creating an account on GitHub.

github.com

 

7.1 Refactoring

선, 원등을 그릴때, 반복되는 코드를 preprocessMouseUp(), postprocessMouseUp() 으로 묶습니다.

function circleMouseMove(event) {
  if (!painter.isDraw()) {
    return;
  }
  var currentPos = getMousePosition(event);
  cvs.beginPath();
  // Need a delay
  cvs.clearRect(0, 0, canvas.width, canvas.height);
  cvs.drawImage(bufCanvas, 0, 0);

  cvs.strokeStyle = painter.getColor();

  var circle = {
    X: Math.round((painter.shape.point.x + currentPos.X) / 2),
    Y: Math.round((painter.shape.point.y + currentPos.Y) / 2),
    R: Math.round(Math.abs(currentPos.Y - painter.shape.point.y) / 2)
  };
  cvs.arc(circle.X, circle.Y, circle.R, 0, Math.PI * 2);
  cvs.closePath();
  cvs.stroke();
}

위의 코드를 아래와 같이 수정하였습니다. 기존 함수 내부를 preprocess()와 postprocess()로 나누어서 묶은 것입니다.

Shape.prototype.preprocessMouseUp = function() {
  bufCtx.beginPath();
  bufCtx.strokeStyle = painter.getColor();
}

Shape.prototype.postprocessMouseUp = function() {
  bufCtx.closePath();
  bufCtx.stroke();

  cvs.clearRect(0, 0, canvas.width, canvas.height);
  cvs.drawImage(bufCanvas, 0, 0);

  this.setDrawMode(false);
}

function circleMouseMove(event) {
  if (!painter.isDraw()) {
    return;
  }
  
  painter.preprocessMouseMove();
  
  var currentPos = getMousePosition(event);
  var circle = {
    X: Math.round((painter.shape.point.x + currentPos.X) / 2),
    Y: Math.round((painter.shape.point.y + currentPos.Y) / 2),
    R: Math.round(Math.abs(currentPos.Y - painter.shape.point.y) / 2)
  };
  cvs.arc(circle.X, circle.Y, circle.R, 0, Math.PI * 2);
  
  painter.postprocessMouseMove();
}

 

7.2 나머지 도형 구현

직선, 원과 같이 삼각형, 직사각형에 대해서도 mouseDown, mouseMove, mouseUp에 대한 이벤트를 정의하고

painter 객체에 추가해 줍니다.

 

여기까지의 참고 자료는 아래 링크를 참고 하시면 됩니다.

https://github.com/chobocho/painter/tree/master/doc/tutorial/007

Posted by chobocho

댓글을 달아 주세요

Coding/JavsScript 삽질기2019. 12. 17. 00:22

소개 (https://chobocho.tistory.com/2461396)
실행하기 http://www.chobocho.com/javascript/painter.html
전체 소스코드 https://github.com/chobocho/painter

 

chobocho/painter

Painter written html5. Contribute to chobocho/painter development by creating an account on GitHub.

github.com

6.1 원 그리기

원을 그리는 함수를 추가합니다.

circle = new Shape("Circle");
circle.mouseAction = new MouseAction(circleMouseUp, circleMouseDown, circleMouseMove);
function circleMouseDown(event) {
  console.log("circleMouseDown");
  if (painter.isDraw()) {
    return;
  }
  bufCtx.drawImage(canvas, 0, 0);
  var startPos = getMousePosition(event);
  painter.shape.point.x = startPos.X;
  painter.shape.point.y = startPos.Y;
  painter.setDrawMode(true);
}

function circleMouseMove(event) {
  if (!painter.isDraw()) {
    return;
  }
  var currentPos = getMousePosition(event);
  cvs.beginPath();
  // Need a delay
  cvs.clearRect(0, 0, canvas.width, canvas.height);
  cvs.drawImage(bufCanvas, 0, 0);

  cvs.strokeStyle = painter.getColor();

  var circle = {
    X: Math.round((painter.shape.point.x + currentPos.X) / 2),
    Y: Math.round((painter.shape.point.y + currentPos.Y) / 2),
    R: Math.round(Math.abs(currentPos.Y - painter.shape.point.y) / 2)
  };
  cvs.arc(circle.X, circle.Y, circle.R, 0, Math.PI * 2);
  cvs.closePath();
  cvs.stroke();
}

function circleMouseUp(event) {
  if (!painter.isDraw()) {
    return;
  }

  var currentPos = getMousePosition(event);
  bufCtx.beginPath();
  bufCtx.strokeStyle = painter.getColor();

  var circle = {
    X: Math.round((painter.shape.point.x + currentPos.X) / 2),
    Y: Math.round((painter.shape.point.y + currentPos.Y) / 2),
    R: Math.round(Math.abs(currentPos.Y - painter.shape.point.y) / 2)
  };
  bufCtx.arc(circle.X, circle.Y, circle.R, 0, Math.PI * 2);
  bufCtx.closePath();
  bufCtx.stroke();

  cvs.clearRect(0, 0, canvas.width, canvas.height);
  cvs.drawImage(bufCanvas, 0, 0);

  painter.setDrawMode(false);
}

 

6.2 도형의 선택

원과 선을 선택 할 수 있도록 html 파일에 함수를 연결 합니다.

[paint.js]

function selectShape(choosedShape) {
  console.log("selectShape:" + choosedShape);
  painter.setShape(choosedShape);
}

Painter 객체에 선, 원을 tools라는 자료형에 추가를 합니다.

Painter.prototype.init = function () {
  line = new Shape("Line");
  line.mouseAction = new MouseAction(lineMouseUp, lineMouseDown, lineMouseMove);
  this.tools[line.name] = line;

  circle = new Shape("Circle");
  circle.mouseAction = new MouseAction(circleMouseUp, circleMouseDown, circleMouseMove);
  this.tools[circle.name] = circle;

  this.shape = this.tools["Line"];
  this.color = "black";
}
function onLoadPage() {
  
  // ...

  painter = new Painter();
  painter.init();
}

6.3 기타 수정 사항

color 값은 모든 도형이 공통적으로 사용하므로,
shape 에서 painter 객체로 이동을 합니다.

Painter.prototype.init = function () {
  // ...
  this.color = "black";
}

 

여기까지 소스코드:

https://github.com/chobocho/painter/tree/master/doc/tutorial/006/src

 

chobocho/painter

Painter written html5. Contribute to chobocho/painter development by creating an account on GitHub.

github.com

 

공감과 댓글은 큰 도움이 됩니다.

Posted by chobocho

댓글을 달아 주세요

  1. 비밀댓글입니다

    2019.12.24 11:49 [ ADDR : EDIT/ DEL : REPLY ]
    • 안녕하세요. painter.html 파일에서 saveImage()로 검색하시면 됩니다.

      2019.12.24 11:53 신고 [ ADDR : EDIT/ DEL ]

Coding/JavsScript 삽질기2019. 12. 10. 02:06

소개:  https://chobocho.tistory.com/2461396

실행하기: http://www.chobocho.com/javascript/painter.html

전체 소스코드: https://github.com/chobocho/painter

 

경고  

주인장은 자바스크립트 초보입니다.  

자바스크립트 고수의 비급을 원하시는 분은 다른 자료를 참고 하시기 바랍니다.  

과도한 기대는 과도한 실망을 가져옵니다.    

본 강의는 자바스크립트만 사용합니다.  

크롬에서의 동작만 보장 합니다.  

Canvas 기초 사용법은 구글링하시면 친절한 강의가 많습니다

 

5.1 색상 변경 기능 구현

아래와 같이 painter.html 의 각 색상 아이콘에 selectColor() 함수를 연결 합니다.

painter.js에 아래와 같이 selectColor() 함수를 구현 합니다.

function selectColor(choosedColor) {
  console.log("selectColor:" + choosedColor);
  painter.shape.setColor(choosedColor);
}
function Shape(name_) {
    this.name = name_;
    this.point = new Point(0, 0);
    this.color = "black";
    this.state = false;
    this.filled = false;
    this.mouseAction;
}

Shape.prototype.setColor = function(color) {
    this.color = color;
}

Shape.prototype.getColor = function() {
    return this.color;
} 

그럼 아래와 같이 선을 그릴 때, 색상을 변경 할 수 있습니다.

 

여기까지 구현된 소스는 아래와 같습니다.

https://github.com/chobocho/painter/commit/7a79b5edc328ac81706280188f9525d4e17f4c09

Posted by chobocho

댓글을 달아 주세요

Coding/JavsScript 삽질기2019. 11. 26. 01:35

소개:  https://chobocho.tistory.com/2461396

실행하기: http://www.chobocho.com/javascript/painter.html

전체 소스코드: https://github.com/chobocho/painter

 

경고  

  • 주인장은 자바스크립트 초보입니다.  

  • 자바스크립트 고수의 비급을 원하시는 분은 다른 자료를 참고 하시기 바랍니다.  

  • 과도한 기대는 과도한 실망을 가져옵니다.    

  • 본 강의는 자바스크립트만 사용합니다.  

  • 크롬에서의 동작만 보장 합니다.  

  • Canvas 기초 사용법은 구글링하시면 친절한 강의가 많습니다

 

4.1 Drawing state


그림판에서 사각형을 그리고자 할 때, 

먼저 시작 점에서 마우스의 왼쪽 버튼을 누르고,  

원하는 크기로 마우스를 드래그 하고, 

마우스의 왼쪽 버튼 누르기를 중단하면 화면에 사각형이 그려집니다.  

이 것을 State Diagram을 표현하면 아래와 같습니다.  

mouse 동작에 따라서, down, up, move에 연결된 함수를 호출 하도록 합니다.  

 

4.2 Double buffering

 

마우스를 도형을 그릴 때, 화면의 깜박임을 없애기 위해서 아래와 같이 bufCanvas 객체를 사용합니다.

그리는 마우스가 움직임에 따라 업데이트해서 그려야하는 화면을 bufCtx에 미리 그린 후 

이 화면을 cvs에 복사하여, 깜박임을 제거 합니다.

var cvs;
var canvas;

var bufCanvas;
var bufCtx;


function onLoadPage() {
  canvas = document.getElementById("canvas");
  cvs = canvas.getContext("2d");

  bufCanvas = document.createElement("canvas");
  bufCanvas.width = canvas.width;
  bufCanvas.height = canvas.height;
  bufCtx = bufCanvas.getContext("2d");
}

 

4.3 선 그리기 구현

아래와 같이 직선을 그리는 동작을 구현 합니다.

function Painter() {
    this.shape = new Shape("Line");
    this.shape.mouseAction = new MouseAction(lineMouseUp, lineMouseDown, lineMouseMove);
}
function MouseAction(mouseUp, mouseDown, mouseMove) {
    this.up = mouseUp;
    this.down = mouseDown;
    this.move = mouseMove;
}

마우스를 클릭하면, 캔버스에서 마우스의 절대 좌표를 기억합니다.

그리고 현재 canvas의 그려진 이미지를 bufCtx에 복사해 둡니다.

function lineMouseDown(event) {
  if (painter.isDraw()) {
    return;
  }
  bufCtx.drawImage(canvas, 0, 0);
  var startPos = getMousePosition(event);
  painter.shape.point.x = startPos.X;
  painter.shape.point.y = startPos.Y;
  painter.setDrawMode(true);
}

마우스를 움직이면, 클릭했을 때 기억한 시작점부터, 현재의 마우스 위치로 직선을 그립니다.

clearRect() 함수를 불러주는 이슈는, delay()를 주기 위해서입니다.

원인은 모르겠으나, canvas가 제대로 업데이트 되지 않는 문제가 있어서 

clearRect() 함수를 한 번 호출해주어 약간의 delay()를 주어서 해결했습니다.

(원인을 아시분은 댓글로 지도 부탁드립니다. 굽신굽신;;)

function lineMouseMove(event) {
  if (!painter.isDraw()) {
    return;
  }
  
  var currentPos = getMousePosition(event);
  cvs.beginPath();
  // Need a delay
  cvs.clearRect(0, 0, canvas.width, canvas.height);
  cvs.drawImage(bufCanvas, 0, 0);

  cvs.strokeStyle = painter.shape.color;
  cvs.moveTo(painter.shape.point.x, painter.shape.point.y);
  cvs.lineTo(currentPos.X, currentPos.Y);
  cvs.closePath();
  cvs.stroke();
}

마우스가 캔버스를 벗어나거나, 버튼에서 손가락을 때면, 

bufCtx에 저장해둔 이미지 위에, 선을 그립니다.

그리고 그 bufCtx 이미지를 canvas에 덮어 씁니다.

function lineMouseUp(event) {
  if (!painter.isDraw()) {
    return;
  }

  var currentPos = getMousePosition(event);
  bufCtx.beginPath();
  bufCtx.strokeStyle = painter.shape.color;
  bufCtx.moveTo(painter.shape.point.x, painter.shape.point.y);
  bufCtx.lineTo(currentPos.X, currentPos.Y);
  bufCtx.closePath();
  bufCtx.stroke();
  cvs.drawImage(bufCanvas, 0, 0);

  painter.setDrawMode(false);
}

나머지 원, 네모, 세모도 동일한 원리로 구현 합니다.

여기까지 소스는 아래와 같습니다.

https://github.com/chobocho/painter/blob/master/doc/tutorial/004/src/painter.js

Posted by chobocho

댓글을 달아 주세요

  1. 비밀댓글입니다

    2019.12.16 15:13 [ ADDR : EDIT/ DEL : REPLY ]
  2. 도움이 되어서 다행이네요.
    궁금한 사항은 댓글로 남겨 주시면, 최대한 답변 드리겠습니다.

    2019.12.16 23:28 신고 [ ADDR : EDIT/ DEL : REPLY ]

Coding/JavsScript 삽질기2019. 11. 14. 09:43

 
경고  
  • 주인장은 자바스크립트 초보입니다.  
  • 자바스크립트 고수의 비급을 원하시는 분은 다른 자료를 참고 하시기 바랍니다.  
  • 과도한 기대는 과도한 실망을 가져옵니다.    
  • 본 강의는 자바스크립트만 사용합니다.  
  • 크롬에서의 동작만 보장 합니다.  
  • Canvas 기초 사용법은 구글링하시면 친절한 강의가 많습니다
 

3.1  painter.js 파일 생성  


먼저 javascript를 구현하기 위한, painter.js 파일을 만듭니다.  
 
 
 

3.2  기본설계  


painter app의 기본 자료형을 설계 합니다.  

위 내용을 UML로 표시하면 아래와 같습니다

위 UML을 코드로 구현하면 아래와 같습니다. 

 

맘에 드셨다면 공감 버튼 '꼭' 눌러주세요! 댓글과 질문은 늘 환영합니다.

Posted by chobocho

댓글을 달아 주세요

Coding/JavsScript 삽질기2019. 11. 13. 00:37

소개:  https://chobocho.tistory.com/2461396

실행하기: http://www.chobocho.com/javascript/painter.html

전체 소스코드: https://github.com/chobocho/painter


 

경고  

  • 주인장은 자바스크립트 초보입니다.  

  • 자바스크립트 고수의 비급을 원하시는 분은 다른 자료를 참고 하시기 바랍니다.  

  • 과도한 기대는 과도한 실망을 가져옵니다.    

  • 본 강의는 자바스크립트만 사용합니다.  

  • 크롬에서의 동작만 보장 합니다.  

 

 

[강의 001]( https://chobocho.tistory.com/2461414)에서 구상한 화면을 구현하면 아래와 같습니다.  

 

 

화면은 크게 3개의 DIV로 구성되어 있습니다.  

자세한 내용은 아래 코드를 참고 하시면 됩니다.  

 

https://github.com/chobocho/painter/tree/master/doc/tutorial/002/src

 

Posted by chobocho

댓글을 달아 주세요

Coding/JavsScript 삽질기2019. 11. 12. 09:20

https://github.com/chobocho/painter/blob/master/doc/tutorial/001/001.md


Javascript로 그림판 만들기 001
 
모든 프로그래밍의 시작은 요구사항 분석 입니다.
UML 툴을 이용하여 머릿속에 존재하는 그림판의 요구사항을 정리해 봅니다
 
 
요구사항이 정리 되었으면, 만들고자 하는 그림판의 모습을 먼저 그려 봅니다.
 
 
 

 

Posted by chobocho

댓글을 달아 주세요