html2canvas를 통한 div 이미지 저장 관련 질문


일정관리 달력을 만들고 있습니다. 달력을 클릭하면 일정을 추가할 수 있고 일정의 길이만큼 노란색으로 달력에 표시가 되는 기능인데, 문제는 "달력저장"버튼을 클릭하면 html2canvas를 이용하여 달력의 div를 png파일로 저장이 되는데, 이 이미지 파일이 브라우저에 렌더링되는 것과는 달리 일정만큼의 색깔로 표시되지 않고 첫날과 일요일에만 색깔이 표시가 됩니다. 무슨 문제일까요? 이미지 이미지 이미지

...
$(function() { 
    $("#test33").click(function() { 
        html2canvas($("#mycal"), {
            onrendered: function(canvas) {
                theCanvas = canvas;

                canvas.toBlob(function(blob) {
                    saveAs(blob, "일정관리달력.png"); 
                });
            }
        });
    });
});
<div id="add-event-form" title="일정등록">
        <p class="validateTips">일정을 입력하세요.</p>
        <form>
        <fieldset>
            <label for="calcal">개인/공식 일정</label>
            <select id="calcal" class="text ui-widget-content ui-corner-all" style="margin-bottom:12px; width:95%; padding: .4em;">
                            <option value="private" SELECTED>개인일정</option>
                            <option value="public">공식일정</option>
            <label for="name">일정내용</label>
            <input type="text" name="what" id="what" class="text ui-widget-content ui-corner-all" style="margin-bottom:12px; width:95%; padding: .4em;"/>
            <table style="width:100%; padding:5px;">
                <tr>
                    <td>
                        <label>시작하는 날</label>
                        <input type="text" name="startDate" id="startDate" value="" class="text ui-widget-content ui-corner-all" style="margin-bottom:12px; width:95%; padding: .4em;"/>                
                    </td>
                    <td>&nbsp;</td>
                    <td>
                        <label>시</label>
                        <select id="startHour" class="text ui-widget-content ui-corner-all" style="margin-bottom:12px; width:95%; padding: .4em;">
                            <option value="12" SELECTED>12</option>
                            <option value="1">1</option>
                            <option value="2">2</option>
                            <option value="3">3</option>
                            <option value="4">4</option>
                            <option value="5">5</option>
                            <option value="6">6</option>
                            <option value="7">7</option>
                            <option value="8">8</option>
                            <option value="9">9</option>
                            <option value="10">10</option>
                            <option value="11">11</option>
                        </select>               
                    <td>
                    <td>
                        <label>분</label>
                        <select id="startMin" class="text ui-widget-content ui-corner-all" style="margin-bottom:12px; width:95%; padding: .4em;">
                            <option value="00" SELECTED>00</option>
                            <option value="10">10</option>
                            <option value="20">20</option>
                            <option value="30">30</option>
                            <option value="40">40</option>
                            <option value="50">50</option>
                        </select>               
                    <td>
                    <td>
                        <label>AM/PM</label>
                        <select id="startMeridiem" class="text ui-widget-content ui-corner-all" style="margin-bottom:12px; width:95%; padding: .4em;">
                            <option value="AM" SELECTED>AM</option>
                            <option value="PM">PM</option>
                        </select>               
                    </td>
                </tr>
                <tr>
                    <td>
                        <label>끝나는 날</label>
                        <input type="text" name="endDate" id="endDate" value="" class="text ui-widget-content ui-corner-all" style="margin-bottom:12px; width:95%; padding: .4em;"/>                
                    </td>
                    <td>&nbsp;</td>
                    <td>
                        <label>시</label>
                        <select id="endHour" class="text ui-widget-content ui-corner-all" style="margin-bottom:12px; width:95%; padding: .4em;">
                            <option value="12" SELECTED>12</option>
                            <option value="1">1</option>
                            <option value="2">2</option>
                            <option value="3">3</option>
                            <option value="4">4</option>
                            <option value="5">5</option>
                            <option value="6">6</option>
                            <option value="7">7</option>
                            <option value="8">8</option>
                            <option value="9">9</option>
                            <option value="10">10</option>
                            <option value="11">11</option>
                        </select>               
                    <td>
                    <td>
                        <label>분</label>
                        <select id="endMin" class="text ui-widget-content ui-corner-all" style="margin-bottom:12px; width:95%; padding: .4em;">
                            <option value="00" SELECTED>00</option>
                            <option value="10">10</option>
                            <option value="20">20</option>
                            <option value="30">30</option>
                            <option value="40">40</option>
                            <option value="50">50</option>
                        </select>               
                    <td>
                    <td>
                        <label>AM/PM</label>
                        <select id="endMeridiem" class="text ui-widget-content ui-corner-all" style="margin-bottom:12px; width:95%; padding: .4em;">
                            <option value="AM" SELECTED>AM</option>
                            <option value="PM">PM</option>
                        </select>               
                    </td>               
                </tr>           
            </table>
            <table>
                <tr>
                    <td>
                        <label>배경색 선택</label>
                    </td>
                    <td>
                        <div id="colorSelectorBackground"><div style="background-color: #333333; width:30px; height:30px; border: 2px solid #000000;"></div></div>
                        <input type="hidden" id="colorBackground" value="#333333">
                    </td>
                    <td>&nbsp;&nbsp;&nbsp;</td>
                    <td>
                        <label>글자색 선택</label>
                    </td>
                    <td>
                        <div id="colorSelectorForeground"><div style="background-color: #ffffff; width:30px; height:30px; border: 2px solid #000000;"></div></div>
                        <input type="hidden" id="colorForeground" value="#ffffff">
                    </td>                       
                </tr>               
            </table>
        </fieldset>
        </form>
    </div>
...
<js>
this.renderAgendaDivElement = function(agi,displayMessage,startDayObject,endDayObject,leftEnd,rightEnd){

            //alert("Calendar.renderAgendaDivElement() called.");

            if(displayMessage == null || startDayObject == null || endDayObject == null){
                return;
            }

            var startX = startDayObject.getX() /*+ this.cellBorderWidth*/ + 1;
            var endX = endDayObject.getX() /*+ this.cellBorderWidth*/ + endDayObject.getWidth() - 1;
            var width = endX - startX;

            var spacerBetweenAgendaDivs = 1;

            var agendaDivHeight = this.agendaItemHeight;
            var moreDivHeight = agendaDivHeight;

            var nextY = this.getNextAgendaYPosition(startDayObject,endDayObject,agendaDivHeight,moreDivHeight);
            //alert("Next Y for item " + displayMessage + ": " + nextY);

            if(nextY > 0){

                var d = $("<div/>");
                // store agenda ID in agenda div so we can get it later in the drag-drop event
                d.data("agendaId",agi.getAgendaId());
                // item is draggble and will revert to it's original position if not dropped into a valid droppable (another day cell)
                if(this.dragAndDropEnabled){
                    d.bind(
                        "drag",
                        function(event, ui) {
                            // do something when dragging
                        }
                    );
                    d.bind(
                        "dragstart",
                        {
                            agendaDivElement: d,
                            agendaId: agi.getAgendaId(),
                            agendaItem: Calendar.buildUserAgendaObject(agi),
                            callBack: this.dragStart_agendaCell
                        },                      
                        function(event, ui) {
                            var callBack = event.data.callBack;
                            if(callBack != null){
                                callBack(
                                    event,
                                    event.data.agendaDivElement,
                                    event.data.agendaItem
                                );
                            }
                        }
                    );
                    d.bind(
                        "dragstop",
                        {
                            agendaDivElement: d,
                            agendaId: agi.getAgendaId(),
                            agendaItem: Calendar.buildUserAgendaObject(agi),
                            callBack: this.dragStop_agendaCell
                        },                      
                        function(event, ui) {
                            var callBack = event.data.callBack;
                            if(callBack != null){
                                callBack(
                                    event,
                                    event.data.agendaDivElement,
                                    event.data.agendaItem
                                );
                            }
                        }
                    );                      
                    d.draggable("enable");
                    d.data("agendaDivElement",d);
                    d.data("agendaId",agi.getAgendaId());
                    d.data("agendaItem", Calendar.buildUserAgendaObject(agi));
                    d.data("revertCallBack",this.callBack_agendaTooltip);
                    d.draggable({ 
                        revert: function(event,ui){
                            var callBack = $(this).data("revertCallBack");
                            var agendaDiv = $(this).data("agendaDivElement");
                            var agendaItem = $(this).data("agendaItem");
                            if(callBack != null){
                                callBack(
                                    agendaDiv,
                                    agendaItem
                                );
                            }
                            return true;
                        },                      
                        scroll: true
                    });
                }
                d.addClass("JFrontierCal-Agenda-Item");

                //수정 - class부여하는부분
                //console.log(agi.opt1+" 도나안도나/ ");
                if( agi.opt1 == "public")
                {
                    d.addClass("public");
                }
                else
                {
                    d.addClass("private");
                }

                if(agi.getBackgroundColor() != null){
                    d.css("background-color",agi.getBackgroundColor());
                }
                if(agi.getForegroundColor() != null){
                    d.css("color",agi.getForegroundColor());
                }
                d.css("position","absolute");
                d.css("left",startX+"px");
                d.css("top",nextY+"px");                    
                d.css("width",width+"px");
                d.css("white-space","nowrap");
                // round corners for webkit & safari (poor IE :( )
                if(leftEnd){
                    d.css("-moz-border-radius-bottomleft","3px");
                    d.css("-moz-border-radius-topleft","3px");
                    d.css("-webkit-border-bottom-left-radius","3px");
                    d.css("-webkit-border-top-left-radius","3px");
                }else{
                    // left end is not the start day of the agenda item. Show our jquery trianle icon
                    var triangle = $("<span/>");
                    triangle.css("float","left");
                    triangle.addClass("ui-icon ui-icon-circle-triangle-w");
                    d.append(triangle);                 
                }
                var mesg = $("<span/>");
                mesg.css("float","left");
                mesg.html(displayMessage);
                d.append(mesg);             
                if(rightEnd){
                    d.css("-moz-border-radius-topright","3px");
                    d.css("-moz-border-radius-bottomright","3px");
                    d.css("-webkit-border-top-right-radius","3px");
                    d.css("-webkit-border-bottom-right-radius","3px");
                }else{
                    // right end is not the end day of the agenda item. Show our jquery trianle icon
                    var triangle = $("<span/>");
                    triangle.css("float","right");
                    triangle.addClass("ui-icon ui-icon-circle-triangle-e");
                    d.append(triangle);
                }
                // add click even lister for agenda item
                if(this.clickEvent_agendaCell != null){
                    d.bind(
                        'click',
                        {
                            // pass agenda ID so user will have access to it in their custom click callback function
                            agendaId: agi.getAgendaId(),
                            // pass click event callback function so we can call it in clickAgendaFromCalendarHandler() function
                            callBack: this.clickEvent_agendaCell
                        },                      
                        this.clickAgendaFromCalendarHandler
                    );
                }
                // add mouse over event listener
                if(this.mouseOverEvent_agendaCell != null){
                    d.bind(
                        'mouseover',
                        {
                            // pass agenda ID so user will have access to it in their custom click callback function
                            agendaId: agi.getAgendaId(),
                            // pass mouseover event callback function so we can call it in mouseOverAgendaFromCalendarHandler() function
                            callBack: this.mouseOverEvent_agendaCell
                        },                      
                        this.clickAgendaFromCalendarHandler
                    );              
                }
                // change mouse cusor to pointer when hovering over agenda divs.
                d.hover(
                    function() {
                        $(this).css('cursor','pointer');
                    },
                    function() {
                        $(this).css('cursor','auto');
                    }
                );
                // call the users custom tooltip function if they provided one. pass the agenda item div element so they have access to it,
                // add pass the user a agenda item object so they have access to the data.
                if(this.callBack_agendaTooltip){
                    this.callBack_agendaTooltip(d,Calendar.buildUserAgendaObject(agi));
                }

                // add agenda <div> to all day cells.
                this.addAgendaDivToDays(startDayObject,endDayObject,d,agi.getAgendaId());

                // add agenda <div> to DOM.
                startDayObject.appendHtml(d);

            }else{

                this.addMoreDivToDays(startDayObject,endDayObject,moreDivHeight);

            }

        };
조회수 708


로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close