Canvas Watermark 텍스트 X 좌표, Y 좌표, 회전각도, 투명도 컨트롤
페이지 정보
본문
Canvas Watermark 텍스트 X 좌표, Y 좌표, 회전각도, 투명도 컨트롤
| 예제 |
|---|
폰트크기 :
폰트색 :
최대 Width :
그라데이션 Color 1 :
오프셋 1 :
그라데이션 Color 2 :
오프셋 2 :
그라데이션 Color 3 :
오프셋 3 :
X 좌표 :
Y 좌표 :
회전각도 :
투명도 :
|
Tag And Script
<style>
.watermark_ex_wrapper{position: relative; display: inline-block;padding:5px;text-align:center;}
.watermark_ex_wrapper .watermark_ex_input_box {position: relative; display: inline-block; float: left; width: 100%; padding:5px;}
.watermark_ex_wrapper .watermark_ex_input_box .div_space{position: relative; clear:both; width: 100%; height: 5px;}
.watermark_ex_wrapper .watermark_ex_input_box span{position: relative; margin:5px;}
.watermark_ex_wrapper .watermark_ex_input_box span .btn_add_watermark_ex{float: right;}
.watermark_ex_wrapper .watermark_ex_input_box span input[type='number'].frm_input{text-align:center; width:60px;}
.watermark_ex_wrapper .watermark_ex_input_box span input[type='number'].frm_ex_watermark_x{}
.watermark_ex_wrapper .watermark_ex_input_box span input[type='number'].frm_ex_watermark_y{}
.watermark_ex_wrapper .watermark_ex_input_box span input[type='color'].frm_color {width: 30px; height: 30px; border-radius: 30px; border: 1px solid #ccc; padding: 0; cursor: pointer; -webkit-appearance: none; -moz-appearance: none; appearance: none; background-color: transparent;}
.watermark_ex_wrapper .watermark_ex_input_box span input[type='color'].frm_color::-webkit-color-swatch-wrapper {padding: 2px;}
.watermark_ex_wrapper .watermark_ex_input_box span input[type='color'].frm_color::-webkit-color-swatch {border-radius: 50%;border: none;}
.watermark_ex_wrapper .watermark_ex_input_box span.frm_ex_watermark_gradient_box{position: relative; width: 100%; padding:0; margin:5px; 0;}
.watermark_ex_wrapper .watermark_ex_input_box .gradient_none{display: none;}
.watermark_ex_wrapper .watermark_ex_input_box .gradient_none.active{display: inline-block;}
.watermark_ex_wrapper .watermark_ex_input_box span.frm_ex_watermark_text_box{position: relative; display: inline-block; width: 100%; padding:0; margin:5px; 0;}
.watermark_ex_wrapper .watermark_ex_input_box span.frm_ex_watermark_text_box::after{position: absolute;top:2px;right:7px;content:""attr(data-stitle)"";display:inline-block;font-weight: normal;color:#7c7c7c;}
.watermark_ex_wrapper .watermark_ex_input_box span.frm_ex_watermark_text_box:hover::after{content:"";}
.watermark_ex_wrapper .watermark_ex_input_box .frm_ex_watermark_text_box textarea.frm_ex_watermark_text{width:100%; min-height:50px;}
</style><div class="watermark_ex_wrapper"> <img id="target_image_ex" src="/cma_img/cginjs_sample.png" alt="원본 이미지" /> <div class="watermark_ex_input_box"> <span>폰트크기 : <input type="number" value="30" class="frm_input frm_ex_watermark_fontsize frm_ex_watermark" min="5" placeholder="폰트크기" /></span> <span class="ex_watermark_color"><font>폰트색</font> : <input type="color" value="#ffffff" class="frm_color frm_ex_watermark_color frm_ex_watermark" min="5" placeholder="폰트색" /></span> <span> <select class="frm_input frm_ex_watermark_text_align frm_ex_watermark"> <option value="">:: 텍스트 정렬 :: </option> <option value="start">start(디폴트)</option> <option value="end">end</option> <option value="center" selected="selected">center</option> <option value="left">left</option> <option value="right">right</option> </select> </span> <span> <select class="frm_input frm_ex_watermark_text_baseline frm_ex_watermark"> <option value="">:: 텍스트 상하정렬 :: </option> <option value="alphabetic">alphabetic(디폴트)</option> <option value="top">top</option> <option value="hanging">hanging</option> <option value="middle" selected="selected">middle</option> <option value="ideographic">ideographic</option> <option value="bottom">bottom</option> </select> </span> <span> <select class="frm_input frm_ex_watermark_line_type frm_ex_watermark"> <option value="">:: 선 타입 :: </option> <option value="fill" selected="selected">채워진 텍스트</option> <option value="stroke">선 텍스트</option> </select> </span> <span>최대 Width : <input type="number" value="0" class="frm_input frm_ex_watermark_max_width frm_ex_watermark" min="0" placeholder="최대 Width" /></span> <span> <select class="frm_input frm_ex_gradient_use frm_ex_watermark"> <option value="y">그라데이션 사용(Y)</option> <option value="n" selected="selected">그라데이션 사용(N)</option> </select> </span> <div class="div_space gradient_none"></div> <span class="frm_ex_watermark_gradient_box gradient_none" data-stitle="그라데이션(gradient)"> <span>그라데이션 Color 1</font> : <input type="color" value="#99ff00" class="frm_color frm_ex_watermark_gradient_color1 frm_ex_watermark" min="5" placeholder="그라데이션 Color 1" /></span> <span>오프셋 1 : <input type="number" value="0.0" class="frm_input frm_ex_watermark_gradient_num1 frm_ex_watermark" min="0.0" max="1.0" step="0.1" placeholder="그라데이션 오프셋 1" /></span> <span>그라데이션 Color 2</font> : <input type="color" value="#0099ff" class="frm_color frm_ex_watermark_gradient_color2 frm_ex_watermark" min="5" placeholder="그라데이션 Color 2" /></span> <span>오프셋 2 : <input type="number" value="0.5" class="frm_input frm_ex_watermark_gradient_num2 frm_ex_watermark" min="0.0" max="1.0" step="0.1" placeholder="그라데이션 오프셋 2" /></span> <span>그라데이션 Color 3</font> : <input type="color" value="#ee5155" class="frm_color frm_ex_watermark_gradient_color3 frm_ex_watermark" min="5" placeholder="그라데이션 Color 3" /></span> <span>오프셋 3 : <input type="number" value="1.0" class="frm_input frm_ex_watermark_gradient_num3 frm_ex_watermark" min="0.0" max="1.0" step="0.1" placeholder="그라데이션 오프셋 3" /></span> </span> <div class="div_space"></div> <span>X 좌표 : <input type="number" value="0" class="frm_input frm_ex_watermark_x frm_ex_watermark" min="0" placeholder="X 좌표" /></span> <span>Y 좌표 : <input type="number" value="0" class="frm_input frm_ex_watermark_y frm_ex_watermark" min="0" placeholder="Y 좌표" /></span> <span>회전각도 : <input type="number" value="0" class="frm_input frm_ex_watermark_rotate frm_ex_watermark" min="-360" max="360" placeholder="회전각도" /></span> <span>투명도 : <input type="number" value="0.5" class="frm_input frm_ex_watermark_alpha frm_ex_watermark" min="0.0" max="1.0" step="0.1" placeholder="투명도(Alpha)" /></span> <span><button class="btn btn_add_watermark_ex">Add Watermark</button></span> <span class="frm_ex_watermark_text_box" data-stitle="Watermark 내용"> <textarea class="frm_input frm_ex_watermark_text frm_ex_watermark" placeholder="Watermark 내용">@워터마크 Cginjs.com</textarea> </span> </div> <div id="output_container"></div> </div>
<script>
function addWatermarkInputInit() {
var imgElement = document.getElementById('target_image_ex');
var $watermark_ex_input_box = $('.watermark_ex_wrapper .watermark_ex_input_box');
// 진행하기 전에 두 이미지가 모두 로드되었는지 확인 (특히 동적으로 로드되는 경우)
if (!imgElement.complete) {
console.error("이미지가 완전히 로드되지 않았습니다.");
return;
}
var img_width = imgElement.naturalWidth;
var img_height = imgElement.naturalHeight;
var padding = 20;
var watermarkWidth = 100;
var watermarkHeight = img_height * (watermarkWidth / img_height);
var x = img_width - watermarkWidth - padding;
var y = img_height - watermarkHeight - padding;
$watermark_ex_input_box.find('input[type="number"].frm_ex_watermark_x').val(x - 100);
$watermark_ex_input_box.find('input[type="number"].frm_ex_watermark_y').val(y + 50);
}
function addWatermarkToText() {
var imgElement = document.getElementById('target_image_ex');
var $watermark_ex_input_box = $('.watermark_ex_wrapper .watermark_ex_input_box');
var canvas_x = parseInt( $watermark_ex_input_box.find('input[type="number"].frm_ex_watermark_x').val() );
var canvas_y = parseInt( $watermark_ex_input_box.find('input[type="number"].frm_ex_watermark_y').val() );
var canvas_rotate = parseInt( $watermark_ex_input_box.find('input[type="number"].frm_ex_watermark_rotate').val() );
var sfontsize = parseInt( $watermark_ex_input_box.find('input[type="number"].frm_ex_watermark_fontsize').val() );
var canvas_alpha = parseFloat( $watermark_ex_input_box.find('input[type="number"].frm_ex_watermark_alpha').val() ).toFixed(1);
var max_width = parseInt( $watermark_ex_input_box.find('input[type="number"].frm_ex_watermark_max_width').val() ).toFixed(1);
var max_width_str = (max_width > 0) ? max_width : '';
var watermark_text = $.trim( $watermark_ex_input_box.find('textarea.frm_ex_watermark_text').val() );
var font_color = $.trim( $watermark_ex_input_box.find('input[type="color"].frm_ex_watermark_color').val() );
var text_align = $.trim( $watermark_ex_input_box.find('select.frm_ex_watermark_text_align').val() );
text_align = text_align ? text_align : 'center';
var text_baseline = $.trim( $watermark_ex_input_box.find('select.frm_ex_watermark_text_baseline').val() );
text_baseline = text_baseline ? text_baseline : 'middle';
var line_type = $.trim( $watermark_ex_input_box.find('select.frm_ex_watermark_line_type').val() ); // 선 타입 : fill : 채워진 텍스트, stroke : 선 텍스트
line_type = line_type ? line_type : 'fill';
var gradient_use = $.trim( $watermark_ex_input_box.find('select.frm_ex_gradient_use').val() );
var gradient_color1 = $.trim( $watermark_ex_input_box.find('input[type="color"].frm_ex_watermark_gradient_color1').val() );
var gradient_num1 = parseFloat( $watermark_ex_input_box.find('input[type="number"].frm_ex_watermark_gradient_num1').val() ).toFixed(1);
var gradient_color2 = $.trim( $watermark_ex_input_box.find('input[type="color"].frm_ex_watermark_gradient_color2').val() );
var gradient_num2 = parseFloat( $watermark_ex_input_box.find('input[type="number"].frm_ex_watermark_gradient_num2').val() ).toFixed(1);
var gradient_color3 = $.trim( $watermark_ex_input_box.find('input[type="color"].frm_ex_watermark_gradient_color3').val() );
var gradient_num3 = parseFloat( $watermark_ex_input_box.find('input[type="number"].frm_ex_watermark_gradient_num3').val() ).toFixed(1);
// 진행하기 전에 두 이미지가 모두 로드되었는지 확인 (특히 동적으로 로드되는 경우)
if (!imgElement.complete) {
console.error("이미지가 완전히 로드되지 않았습니다.");
return;
}
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// 캔버스 크기를 원본 이미지의 크기로 설정
canvas.width = imgElement.naturalWidth;
canvas.height = imgElement.naturalHeight;
// 원본 이미지를 캔버스에 그리기
ctx.drawImage(imgElement, 0, 0, canvas.width, canvas.height);
// 워터마크 모양 사용자 지정
ctx.font = sfontsize+'px Arial';
ctx.textAlign = text_align; // 텍스트 정렬 : start(디폴트)|end|center|left|right
ctx.textBaseline = text_baseline; // 상하정렬 : alphabetic(디폴트)|top|hanging|middle|ideographic|bottom
var watermarkText = watermark_text;
var x = canvas.width / 2;
var y = canvas.height / 2;
// 선택 사항: 대각선 효과를 위해 워터마크를 회전할 수 있슴
ctx.save(); // 현재 캔버스 상태를 저장
ctx.translate(canvas_x, canvas_y); // 원점을 중심으로 이동
// 워터마크 회전
var rotate_calc = ( (canvas_rotate * Math.PI) / 180 );
ctx.rotate(rotate_calc); // 가도가 양수이면 시계반향 , 각도가 음수미염 반시계 방향으로 canvas_rotate만큼 좌표계를 기울임
// 선택 사항: 투명도 조정(globalAlpha 값은 0~1 사이)
ctx.globalAlpha = canvas_alpha;
// 선형 그라데이션 객체 생성
var gradient = ctx.createLinearGradient(0, 0, 0, 100); //그라데이션 방향 (X0, Y0, X1, Y1)
// 그라데이션 색 추가
gradient.addColorStop(gradient_num1, gradient_color1);
gradient.addColorStop(gradient_num2, gradient_color2);
gradient.addColorStop(gradient_num3, gradient_color3);
// 텍스트 그리기
if(line_type == 'fill') {
ctx.fillStyle = (gradient_use == 'y') ? gradient : font_color; // 글자색
max_width_str ? ctx.fillText(watermarkText, 0, 0, max_width_str) : ctx.fillText(watermarkText, 0, 0); // 채워진 텍스트
} else {
ctx.strokeStyle = (gradient_use == 'y') ? gradient : font_color; // 테두리색
max_width_str ? ctx.strokeText(watermarkText, 0, 0, max_width_str) : ctx.strokeText(watermarkText, 0, 0); // 선 텍스트
}
ctx.restore(); // 캔버스의 원래 상태를 복원
// 선택 사항: 캔버스 전체에 워터마크를 반복 표시
// 이는 더 복잡한 논리를 필요로 하지만 기본 원리는 동일
// --- 결과 출력 ---
//캔버스를 이미지로 변환하여 표시하거나 다운로드
var watermarkedImageUrl = canvas.toDataURL(); // 캔버스 콘텐츠를 데이터 URL로 변환
var newImg = new Image();
newImg.src = watermarkedImageUrl;
$('#output_container').html(newImg); // 새 이미지를 DOM에 추가
}
addWatermarkInputInit();
$(function(e) {
$(document).on('change', '.watermark_ex_wrapper .watermark_ex_input_box .frm_ex_gradient_use', function(e){
var sValue = $(this).val();
var $gradient_none = $('.watermark_ex_input_box .gradient_none');
(sValue == 'y') ? $gradient_none.addClass('active') : $gradient_none.removeClass('active');
});
$(document).on('change', '.watermark_ex_wrapper .watermark_ex_input_box .frm_ex_watermark_line_type', function(e){
var sValue = $(this).val();
var $ex_watermark_color = $('.watermark_ex_input_box span.ex_watermark_color');
var $ex_input = $ex_watermark_color.find('.frm_ex_watermark_color');
var stext = (sValue == 'fill') ? '폰트색' : '테두리색';
$ex_watermark_color.find('font').text(stext); $ex_input.attr('placeholder', stext);
});
$(document).on('click', '.watermark_ex_wrapper .watermark_ex_input_box .btn_add_watermark_ex', function(e){
addWatermarkToText();
});
$(document).on('change keyup', '.watermark_ex_wrapper .watermark_ex_input_box .frm_ex_watermark', function(e){
addWatermarkToText();
});
});
</script>
- 다음글 Canvas Watermark 텍스트 26.02.12
