diff options
| author | Alon Levy <alon@pobox.com> | 2015-01-12 17:27:46 +0200 |
|---|---|---|
| committer | Alon Levy <alon@pobox.com> | 2015-01-13 08:36:09 +0200 |
| commit | 96534de0c0dceefde8795e879927c5bedbdaa858 (patch) | |
| tree | 0c063105fe64f72b90dcf02bb55c0ad2ea4fd2ac /res/client/lib/feedback.js | |
| parent | 118e82810eb87d056d0fdd938dc3d598d0b53ccb (diff) | |
add feedback - no email yet, just client side plus server parse client post
Notes:
* using https://github.com/ivoviz/feedback
+ commit 337a8146e567a06035fb1f1ffedfce083be2a2d1
* with tiny changes to use require.js:
+ html2canvas.js & feedback.js (not minified) start+end lines
changed to call define
+ feedback.js changed to not load html2canvas since require.js does
that for us (dropping _html2canvas and getScript usage)
Diffstat (limited to 'res/client/lib/feedback.js')
| -rw-r--r-- | res/client/lib/feedback.js | 599 |
1 files changed, 599 insertions, 0 deletions
diff --git a/res/client/lib/feedback.js b/res/client/lib/feedback.js new file mode 100644 index 00000000..6274df7c --- /dev/null +++ b/res/client/lib/feedback.js @@ -0,0 +1,599 @@ +// feedback.js +// 2013, Kázmér Rapavi, https://github.com/ivoviz/feedback +// Licensed under the MIT license. +// Version 2.0 + +define(['jquery', 'html2canvas'], function($, _unused_html2canvas) { + + $.feedback = function(options) { + + var settings = $.extend({ + ajaxURL: '', + postBrowserInfo: true, + postHTML: true, + postURL: true, + proxy: undefined, + letterRendering: false, + initButtonText: 'Send feedback', + strokeStyle: 'black', + shadowColor: 'black', + shadowOffsetX: 1, + shadowOffsetY: 1, + shadowBlur: 10, + lineJoin: 'bevel', + lineWidth: 3, + feedbackButton: '.feedback-btn', + showDescriptionModal: true, + isDraggable: true, + onScreenshotTaken: function(){}, + tpl: { + description: '<div id="feedback-welcome"><div class="feedback-logo">Feedback</div><p>Feedback lets you send us suggestions about our products. We welcome problem reports, feature ideas and general comments.</p><p>Start by writing a brief description:</p><textarea id="feedback-note-tmp"></textarea><p>Next we\'ll let you identify areas of the page related to your description.</p><button id="feedback-welcome-next" class="feedback-next-btn feedback-btn-gray">Next</button><div id="feedback-welcome-error">Please enter a description.</div><div class="feedback-wizard-close"></div></div>', + highlighter: '<div id="feedback-highlighter"><div class="feedback-logo">Feedback</div><p>Click and drag on the page to help us better understand your feedback. You can move this dialog if it\'s in the way.</p><button class="feedback-sethighlight feedback-active"><div class="ico"></div><span>Highlight</span></button><label>Highlight areas relevant to your feedback.</label><button class="feedback-setblackout"><div class="ico"></div><span>Black out</span></button><label class="lower">Black out any personal information.</label><div class="feedback-buttons"><button id="feedback-highlighter-next" class="feedback-next-btn feedback-btn-gray">Next</button><button id="feedback-highlighter-back" class="feedback-back-btn feedback-btn-gray">Back</button></div><div class="feedback-wizard-close"></div></div>', + overview: '<div id="feedback-overview"><div class="feedback-logo">Feedback</div><div id="feedback-overview-description"><div id="feedback-overview-description-text"><h3>Description</h3><h3 class="feedback-additional">Additional info</h3><div id="feedback-additional-none"><span>None</span></div><div id="feedback-browser-info"><span>Browser Info</span></div><div id="feedback-page-info"><span>Page Info</span></div><div id="feedback-page-structure"><span>Page Structure</span></div></div></div><div id="feedback-overview-screenshot"><h3>Screenshot</h3></div><div class="feedback-buttons"><button id="feedback-submit" class="feedback-submit-btn feedback-btn-blue">Submit</button><button id="feedback-overview-back" class="feedback-back-btn feedback-btn-gray">Back</button></div><div id="feedback-overview-error">Please enter a description.</div><div class="feedback-wizard-close"></div></div>', + submitSuccess: '<div id="feedback-submit-success"><div class="feedback-logo">Feedback</div><p>Thank you for your feedback. We value every piece of feedback we receive.</p><p>We cannot respond individually to every one, but we will use your comments as we strive to improve your experience.</p><button class="feedback-close-btn feedback-btn-blue">OK</button><div class="feedback-wizard-close"></div></div>', + submitError: '<div id="feedback-submit-error"><div class="feedback-logo">Feedback</div><p>Sadly an error occured while sending your feedback. Please try again.</p><button class="feedback-close-btn feedback-btn-blue">OK</button><div class="feedback-wizard-close"></div></div>' + }, + onClose: function() {}, + screenshotStroke: true, + highlightElement: true, + initialBox: false + }, options); + var supportedBrowser = !!window.HTMLCanvasElement; + var isFeedbackButtonNative = settings.feedbackButton == '.feedback-btn'; + if (supportedBrowser) { + if(isFeedbackButtonNative) { + $('body').append('<button class="feedback-btn feedback-btn-gray">' + settings.initButtonText + '</button>'); + } + $(document).on('click', settings.feedbackButton, function(){ + if(isFeedbackButtonNative) { + $(this).hide(); + } + var canDraw = false, + img = '', + h = $(document).height(), + w = $(document).width(), + tpl = '<div id="feedback-module">'; + + if (settings.initialBox) { + tpl += settings.tpl.description; + } + + tpl += settings.tpl.highlighter + settings.tpl.overview + '<canvas id="feedback-canvas"></canvas><div id="feedback-helpers"></div><input id="feedback-note" name="feedback-note" type="hidden"></div>'; + + $('body').append(tpl); + + moduleStyle = { + 'position': 'absolute', + 'left': '0px', + 'top': '0px' + }; + canvasAttr = { + 'width': w, + 'height': h + }; + + $('#feedback-module').css(moduleStyle); + $('#feedback-canvas').attr(canvasAttr).css('z-index', '30000'); + + if (!settings.initialBox) { + $('#feedback-highlighter-back').remove(); + canDraw = true; + $('#feedback-canvas').css('cursor', 'crosshair'); + $('#feedback-helpers').show(); + $('#feedback-welcome').hide(); + $('#feedback-highlighter').show(); + } + + if(settings.isDraggable) { + $('#feedback-highlighter').on('mousedown', function(e) { + var $d = $(this).addClass('feedback-draggable'), + drag_h = $d.outerHeight(), + drag_w = $d.outerWidth(), + pos_y = $d.offset().top + drag_h - e.pageY, + pos_x = $d.offset().left + drag_w - e.pageX; + $d.css('z-index', 40000).parents().on('mousemove', function(e) { + _top = e.pageY + pos_y - drag_h; + _left = e.pageX + pos_x - drag_w; + _bottom = drag_h - e.pageY; + _right = drag_w - e.pageX; + + if (_left < 0) _left = 0; + if (_top < 0) _top = 0; + if (_right > $(window).width()) + _left = $(window).width() - drag_w; + if (_left > $(window).width() - drag_w) + _left = $(window).width() - drag_w; + if (_bottom > $(document).height()) + _top = $(document).height() - drag_h; + if (_top > $(document).height() - drag_h) + _top = $(document).height() - drag_h; + + $('.feedback-draggable').offset({ + top: _top, + left: _left + }).on("mouseup", function() { + $(this).removeClass('feedback-draggable'); + }); + }); + e.preventDefault(); + }).on('mouseup', function(){ + $(this).removeClass('feedback-draggable'); + $(this).parents().off('mousemove mousedown'); + }); + } + + var ctx = $('#feedback-canvas')[0].getContext('2d'); + + ctx.fillStyle = 'rgba(102,102,102,0.5)'; + ctx.fillRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height()); + + rect = {}; + drag = false; + highlight = 1, + post = {}; + + if (settings.postBrowserInfo) { + post.browser = {}; + post.browser.appCodeName = navigator.appCodeName; + post.browser.appName = navigator.appName; + post.browser.appVersion = navigator.appVersion; + post.browser.cookieEnabled = navigator.cookieEnabled; + post.browser.onLine = navigator.onLine; + post.browser.platform = navigator.platform; + post.browser.userAgent = navigator.userAgent; + post.browser.plugins = []; + + $.each(navigator.plugins, function(i) { + post.browser.plugins.push(navigator.plugins[i].name); + }); + $('#feedback-browser-info').show(); + } + + if (settings.postURL) { + post.url = document.URL; + $('#feedback-page-info').show(); + } + + if (settings.postHTML) { + post.html = $('html').html(); + $('#feedback-page-structure').show(); + } + + if (!settings.postBrowserInfo && !settings.postURL && !settings.postHTML) + $('#feedback-additional-none').show(); + + $(document).on('mousedown', '#feedback-canvas', function(e) { + if (canDraw) { + + rect.startX = e.pageX - $(this).offset().left; + rect.startY = e.pageY - $(this).offset().top; + rect.w = 0; + rect.h = 0; + drag = true; + } + }); + + $(document).on('mouseup', function(){ + if (canDraw) { + drag = false; + + var dtop = rect.startY, + dleft = rect.startX, + dwidth = rect.w, + dheight = rect.h; + dtype = 'highlight'; + + if (dwidth == 0 || dheight == 0) return; + + if (dwidth < 0) { + dleft += dwidth; + dwidth *= -1; + } + if (dheight < 0) { + dtop += dheight; + dheight *= -1; + } + + if (dtop + dheight > $(document).height()) + dheight = $(document).height() - dtop; + if (dleft + dwidth > $(document).width()) + dwidth = $(document).width() - dleft; + + if (highlight == 0) + dtype = 'blackout'; + + $('#feedback-helpers').append('<div class="feedback-helper" data-type="' + dtype + '" data-time="' + Date.now() + '" style="position:absolute;top:' + dtop + 'px;left:' + dleft + 'px;width:' + dwidth + 'px;height:' + dheight + 'px;z-index:30000;"></div>'); + + redraw(ctx); + rect.w = 0; + } + + }); + + $(document).on('mousemove', function(e) { + if (canDraw && drag) { + $('#feedback-highlighter').css('cursor', 'default'); + + rect.w = (e.pageX - $('#feedback-canvas').offset().left) - rect.startX; + rect.h = (e.pageY - $('#feedback-canvas').offset().top) - rect.startY; + + ctx.clearRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height()); + ctx.fillStyle = 'rgba(102,102,102,0.5)'; + ctx.fillRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height()); + $('.feedback-helper').each(function() { + if ($(this).attr('data-type') == 'highlight') + drawlines(ctx, parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height()); + }); + if (highlight==1) { + drawlines(ctx, rect.startX, rect.startY, rect.w, rect.h); + ctx.clearRect(rect.startX, rect.startY, rect.w, rect.h); + } + $('.feedback-helper').each(function() { + if ($(this).attr('data-type') == 'highlight') + ctx.clearRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height()); + }); + $('.feedback-helper').each(function() { + if ($(this).attr('data-type') == 'blackout') { + ctx.fillStyle = 'rgba(0,0,0,1)'; + ctx.fillRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height()) + } + }); + if (highlight == 0) { + ctx.fillStyle = 'rgba(0,0,0,0.5)'; + ctx.fillRect(rect.startX, rect.startY, rect.w, rect.h); + } + } + }); + + if (settings.highlightElement) { + var highlighted = [], + tmpHighlighted = [], + hidx = 0; + + $(document).on('mousemove click', '#feedback-canvas',function(e) { + if (canDraw) { + redraw(ctx); + tmpHighlighted = []; + + $('#feedback-canvas').css('cursor', 'crosshair'); + + $('* :not(body,script,iframe,div,section,.feedback-btn,#feedback-module *)').each(function(){ + if ($(this).attr('data-highlighted') === 'true') + return; + + if (e.pageX > $(this).offset().left && e.pageX < $(this).offset().left + $(this).width() && e.pageY > $(this).offset().top + parseInt($(this).css('padding-top'), 10) && e.pageY < $(this).offset().top + $(this).height() + parseInt($(this).css('padding-top'), 10)) { + tmpHighlighted.push($(this)); + } + }); + + var $toHighlight = tmpHighlighted[tmpHighlighted.length - 1]; + + if ($toHighlight && !drag) { + $('#feedback-canvas').css('cursor', 'pointer'); + + var _x = $toHighlight.offset().left - 2, + _y = $toHighlight.offset().top - 2, + _w = $toHighlight.width() + parseInt($toHighlight.css('padding-left'), 10) + parseInt($toHighlight.css('padding-right'), 10) + 6, + _h = $toHighlight.height() + parseInt($toHighlight.css('padding-top'), 10) + parseInt($toHighlight.css('padding-bottom'), 10) + 6; + + if (highlight == 1) { + drawlines(ctx, _x, _y, _w, _h); + ctx.clearRect(_x, _y, _w, _h); + dtype = 'highlight'; + } + + $('.feedback-helper').each(function() { + if ($(this).attr('data-type') == 'highlight') + ctx.clearRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height()); + }); + + if (highlight == 0) { + dtype = 'blackout'; + ctx.fillStyle = 'rgba(0,0,0,0.5)'; + ctx.fillRect(_x, _y, _w, _h); + } + + $('.feedback-helper').each(function() { + if ($(this).attr('data-type') == 'blackout') { + ctx.fillStyle = 'rgba(0,0,0,1)'; + ctx.fillRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height()); + } + }); + + if (e.type == 'click' && e.pageX == rect.startX && e.pageY == rect.startY) { + $('#feedback-helpers').append('<div class="feedback-helper" data-highlight-id="' + hidx + '" data-type="' + dtype + '" data-time="' + Date.now() + '" style="position:absolute;top:' + _y + 'px;left:' + _x + 'px;width:' + _w + 'px;height:' + _h + 'px;z-index:30000;"></div>'); + highlighted.push(hidx); + ++hidx; + redraw(ctx); + } + } + } + }); + } + + $(document).on('mouseleave', 'body,#feedback-canvas', function() { + redraw(ctx); + }); + + $(document).on('mouseenter', '.feedback-helper', function() { + redraw(ctx); + }); + + $(document).on('click', '#feedback-welcome-next', function() { + if ($('#feedback-note').val().length > 0) { + canDraw = true; + $('#feedback-canvas').css('cursor', 'crosshair'); + $('#feedback-helpers').show(); + $('#feedback-welcome').hide(); + $('#feedback-highlighter').show(); + } + else { + $('#feedback-welcome-error').show(); + } + }); + + $(document).on('mouseenter mouseleave', '.feedback-helper', function(e) { + if (drag) + return; + + rect.w = 0; + rect.h = 0; + + if (e.type === 'mouseenter') { + $(this).css('z-index', '30001'); + $(this).append('<div class="feedback-helper-inner" style="width:' + ($(this).width() - 2) + 'px;height:' + ($(this).height() - 2) + 'px;position:absolute;margin:1px;"></div>'); + $(this).append('<div id="feedback-close"></div>'); + $(this).find('#feedback-close').css({ + 'top' : -1 * ($(this).find('#feedback-close').height() / 2) + 'px', + 'left' : $(this).width() - ($(this).find('#feedback-close').width() / 2) + 'px' + }); + + if ($(this).attr('data-type') == 'blackout') { + /* redraw white */ + ctx.clearRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height()); + ctx.fillStyle = 'rgba(102,102,102,0.5)'; + ctx.fillRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height()); + $('.feedback-helper').each(function() { + if ($(this).attr('data-type') == 'highlight') + drawlines(ctx, parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height()); + }); + $('.feedback-helper').each(function() { + if ($(this).attr('data-type') == 'highlight') + ctx.clearRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height()); + }); + + ctx.clearRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height()) + ctx.fillStyle = 'rgba(0,0,0,0.75)'; + ctx.fillRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height()); + + ignore = $(this).attr('data-time'); + + /* redraw black */ + $('.feedback-helper').each(function() { + if ($(this).attr('data-time') == ignore) + return true; + if ($(this).attr('data-type') == 'blackout') { + ctx.fillStyle = 'rgba(0,0,0,1)'; + ctx.fillRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height()) + } + }); + } + } + else { + $(this).css('z-index','30000'); + $(this).children().remove(); + if ($(this).attr('data-type') == 'blackout') { + redraw(ctx); + } + } + }); + + $(document).on('click', '#feedback-close', function() { + if (settings.highlightElement && $(this).parent().attr('data-highlight-id')) + var _hidx = $(this).parent().attr('data-highlight-id'); + + $(this).parent().remove(); + + if (settings.highlightElement && _hidx) + $('[data-highlight-id="' + _hidx + '"]').removeAttr('data-highlighted').removeAttr('data-highlight-id'); + + redraw(ctx); + }); + + $('#feedback-module').on('click', '.feedback-wizard-close,.feedback-close-btn', function() { + close(); + }); + + $(document).on('keyup', function(e) { + if (e.keyCode == 27) + close(); + }); + + $(document).on('selectstart dragstart', document, function(e) { + e.preventDefault(); + }); + + $(document).on('click', '#feedback-highlighter-back', function() { + canDraw = false; + $('#feedback-canvas').css('cursor', 'default'); + $('#feedback-helpers').hide(); + $('#feedback-highlighter').hide(); + $('#feedback-welcome-error').hide(); + $('#feedback-welcome').show(); + }); + + $(document).on('mousedown', '.feedback-sethighlight', function() { + highlight = 1; + $(this).addClass('feedback-active'); + $('.feedback-setblackout').removeClass('feedback-active'); + }); + + $(document).on('mousedown', '.feedback-setblackout', function() { + highlight = 0; + $(this).addClass('feedback-active'); + $('.feedback-sethighlight').removeClass('feedback-active'); + }); + + $(document).on('click', '#feedback-highlighter-next', function() { + canDraw = false; + $('#feedback-canvas').css('cursor', 'default'); + var sy = $(document).scrollTop(), + dh = $(window).height(); + $('#feedback-helpers').hide(); + $('#feedback-highlighter').hide(); + if (!settings.screenshotStroke) { + redraw(ctx, false); + } + html2canvas($('body'), { + onrendered: function(canvas) { + if (!settings.screenshotStroke) { + redraw(ctx); + } + _canvas = $('<canvas id="feedback-canvas-tmp" width="'+ w +'" height="'+ dh +'"/>').hide().appendTo('body'); + _ctx = _canvas.get(0).getContext('2d'); + _ctx.drawImage(canvas, 0, sy, w, dh, 0, 0, w, dh); + img = _canvas.get(0).toDataURL(); + $(document).scrollTop(sy); + post.img = img; + settings.onScreenshotTaken(post.img); + if(settings.showDescriptionModal) { + $('#feedback-canvas-tmp').remove(); + $('#feedback-overview').show(); + $('#feedback-overview-description-text>textarea').remove(); + $('#feedback-overview-screenshot>img').remove(); + $('<textarea id="feedback-overview-note">' + $('#feedback-note').val() + '</textarea>').insertAfter('#feedback-overview-description-text h3:eq(0)'); + $('#feedback-overview-screenshot').append('<img class="feedback-screenshot" src="' + img + '" />'); + } + else { + $('#feedback-module').remove(); + close(); + _canvas.remove(); + } + }, + proxy: settings.proxy, + letterRendering: settings.letterRendering + }); + }); + + $(document).on('click', '#feedback-overview-back', function(e) { + canDraw = true; + $('#feedback-canvas').css('cursor', 'crosshair'); + $('#feedback-overview').hide(); + $('#feedback-helpers').show(); + $('#feedback-highlighter').show(); + $('#feedback-overview-error').hide(); + }); + + $(document).on('keyup', '#feedback-note-tmp,#feedback-overview-note', function(e) { + var tx; + if (e.target.id === 'feedback-note-tmp') + tx = $('#feedback-note-tmp').val(); + else { + tx = $('#feedback-overview-note').val(); + $('#feedback-note-tmp').val(tx); + } + + $('#feedback-note').val(tx); + }); + + $(document).on('click', '#feedback-submit', function() { + canDraw = false; + + if ($('#feedback-note').val().length > 0) { + $('#feedback-submit-success,#feedback-submit-error').remove(); + $('#feedback-overview').hide(); + + post.img = img; + post.note = $('#feedback-note').val(); + var data = {feedback: JSON.stringify(post)}; + $.ajax({ + url: settings.ajaxURL, + dataType: 'json', + type: 'POST', + data: data, + success: function() { + $('#feedback-module').append(settings.tpl.submitSuccess); + }, + error: function(){ + $('#feedback-module').append(settings.tpl.submitError); + } + }); + } + else { + $('#feedback-overview-error').show(); + } + }); + }); + } + + function close() { + canDraw = false; + $(document).off('mouseenter mouseleave', '.feedback-helper'); + $(document).off('mouseup keyup'); + $(document).off('mousedown', '.feedback-setblackout'); + $(document).off('mousedown', '.feedback-sethighlight'); + $(document).off('mousedown click', '#feedback-close'); + $(document).off('mousedown', '#feedback-canvas'); + $(document).off('click', '#feedback-highlighter-next'); + $(document).off('click', '#feedback-highlighter-back'); + $(document).off('click', '#feedback-welcome-next'); + $(document).off('click', '#feedback-overview-back'); + $(document).off('mouseleave', 'body'); + $(document).off('mouseenter', '.feedback-helper'); + $(document).off('selectstart dragstart', document); + $('#feedback-module').off('click', '.feedback-wizard-close,.feedback-close-btn'); + $(document).off('click', '#feedback-submit'); + + if (settings.highlightElement) { + $(document).off('click', '#feedback-canvas'); + $(document).off('mousemove', '#feedback-canvas'); + } + $('[data-highlighted="true"]').removeAttr('data-highlight-id').removeAttr('data-highlighted'); + $('#feedback-module').remove(); + $('.feedback-btn').show(); + + settings.onClose.call(this); + } + + function redraw(ctx, border) { + border = typeof border !== 'undefined' ? border : true; + ctx.clearRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height()); + ctx.fillStyle = 'rgba(102,102,102,0.5)'; + ctx.fillRect(0, 0, $('#feedback-canvas').width(), $('#feedback-canvas').height()); + $('.feedback-helper').each(function() { + if ($(this).attr('data-type') == 'highlight') + if (border) + drawlines(ctx, parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height()); + }); + $('.feedback-helper').each(function() { + if ($(this).attr('data-type') == 'highlight') + ctx.clearRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height()); + }); + $('.feedback-helper').each(function() { + if ($(this).attr('data-type') == 'blackout') { + ctx.fillStyle = 'rgba(0,0,0,1)'; + ctx.fillRect(parseInt($(this).css('left'), 10), parseInt($(this).css('top'), 10), $(this).width(), $(this).height()); + } + }); + } + + function drawlines(ctx, x, y, w, h) { + ctx.strokeStyle = settings.strokeStyle; + ctx.shadowColor = settings.shadowColor; + ctx.shadowOffsetX = settings.shadowOffsetX; + ctx.shadowOffsetY = settings.shadowOffsetY; + ctx.shadowBlur = settings.shadowBlur; + ctx.lineJoin = settings.lineJoin; + ctx.lineWidth = settings.lineWidth; + + ctx.strokeRect(x,y,w,h); + + ctx.shadowOffsetX = 0; + ctx.shadowOffsetY = 0; + ctx.shadowBlur = 0; + ctx.lineWidth = 1; + } + + }; + +}); |
