Admin Chat Preview: fix for widescreen & add animation
Turns out that the chat preview was broken on big screens. The website screenshot didn’t span the whole width and the chat was getting cut off. Fixes: - preserve 16:10 browser aspect ratio - rename zoom to 1:1 - hide 1:1 mode on big screens that don’t need it - scale the website screenshot to the full width - scale the website screenshot in 1:1 mode with the chat - make color picker work with changes - use dynamic height in the form preview
This commit is contained in:
parent
577bb5f723
commit
5239c83e71
4 changed files with 143 additions and 99 deletions
|
@ -5,7 +5,7 @@ class App.ChannelChat extends App.ControllerSubContent
|
|||
'change .js-params': 'updateParams'
|
||||
'input .js-params': 'updateParams'
|
||||
'submit .js-demo-head': 'onUrlSubmit'
|
||||
'click .js-selectBrowserWidth': 'selectBrowserWidth'
|
||||
'click .js-selectBrowserSize': 'selectBrowserSize'
|
||||
'click .js-swatch': 'usePaletteColor'
|
||||
'click .js-toggle-chat': 'toggleChat'
|
||||
'change .js-chatSetting input': 'toggleChatSetting'
|
||||
|
@ -104,8 +104,7 @@ class App.ChannelChat extends App.ControllerSubContent
|
|||
]
|
||||
|
||||
isOpen: true
|
||||
browserWidth: 1280
|
||||
browserWidthMax: 1280
|
||||
browserSize: 'desktop'
|
||||
previewUrl: ''
|
||||
previewScale: 1
|
||||
|
||||
|
@ -167,45 +166,33 @@ class App.ChannelChat extends App.ControllerSubContent
|
|||
$(window).off 'resize.chat-designer'
|
||||
@website.off('click.eyedropper')
|
||||
|
||||
selectBrowserWidth: (event) =>
|
||||
tab = $(event.target).closest('[data-value]')
|
||||
selectBrowserSize: (event) =>
|
||||
tab = $(event.target).closest('[data-size]')
|
||||
|
||||
# select tab
|
||||
tab.addClass('is-selected').siblings().removeClass('is-selected')
|
||||
@browserWidth = tab.attr('data-value')
|
||||
@browserSize = tab.attr('data-size')
|
||||
@updatePreview()
|
||||
|
||||
updatePreview: (animate = true) =>
|
||||
width = parseInt @browserWidth, 10
|
||||
|
||||
# reset zoom
|
||||
@chat
|
||||
.removeClass('is-fullscreen')
|
||||
.toggleClass('no-transition', !animate)
|
||||
.css 'transform', "translateY(#{ @getChatOffset() }px)"
|
||||
@browser.css('width', '')
|
||||
@website.css
|
||||
transform: ''
|
||||
width: ''
|
||||
height: ''
|
||||
@browser.attr('data-size', @browserSize)
|
||||
@previewScale = 1
|
||||
|
||||
return if @browserWidth is 'fit'
|
||||
|
||||
if width < @el.width() && width == 375
|
||||
switch @browserSize
|
||||
when 'mobile'
|
||||
@chat.addClass('is-fullscreen').css 'transform', "translateY(#{ @getChatOffset(true) }px)"
|
||||
@browser.css('width', "#{ width }px")
|
||||
else
|
||||
if @el.width() > width && width == @browserWidthMax
|
||||
@previewScale = 1
|
||||
else
|
||||
@previewScale = @el.width()/width
|
||||
|
||||
@chat.css 'transform', "translateY(#{ @getChatOffset() * @previewScale }px) scale(#{ @previewScale })"
|
||||
@website.css
|
||||
transform: "scale(#{ @previewScale })"
|
||||
width: @el.width() / @previewScale
|
||||
height: @browserBody.height() / @previewScale
|
||||
when '1:1'
|
||||
@previewScale = Math.max(1, 1280/@el.width())
|
||||
@website.css 'transform', "scale(#{ @previewScale })"
|
||||
when 'desktop'
|
||||
scale = Math.min(1, @el.width()/1280) # don't use it for the previewScale (used for the color picker)
|
||||
@website.css 'transform', ''
|
||||
@chat.css 'transform', "translateY(#{ @getChatOffset() * scale }px) scale(#{ scale })"
|
||||
|
||||
getChatOffset: (fullscreen) ->
|
||||
return 0 if @isOpen
|
||||
|
@ -296,8 +283,11 @@ class App.ChannelChat extends App.ControllerSubContent
|
|||
@eyedropper.addClass('is-active')
|
||||
|
||||
onColorPicked: (event) =>
|
||||
x = event.pageX - @website.offset().left
|
||||
y = event.pageY - @website.offset().top
|
||||
website_x = @website.position().left
|
||||
website_y = @website.position().top
|
||||
|
||||
relative_x = event.pageX - @browserBody.offset().left
|
||||
relative_y = event.pageY - @browserBody.offset().top
|
||||
|
||||
image = new Image()
|
||||
image.src = @_screenshotSource
|
||||
|
@ -305,11 +295,11 @@ class App.ChannelChat extends App.ControllerSubContent
|
|||
canvas = document.createElement('canvas')
|
||||
ctx = canvas.getContext('2d')
|
||||
|
||||
canvas.width = image.width
|
||||
canvas.height = image.height
|
||||
canvas.width = @browserBody.width()
|
||||
canvas.height = @browserBody.height()
|
||||
|
||||
ctx.drawImage(image, 0, 0, @previewScale * canvas.width, @previewScale * canvas.height)
|
||||
pixels = ctx.getImageData(x, y, 1, 1).data
|
||||
ctx.drawImage(image, website_x, website_y, @website.width() * @previewScale, @website.width() * @previewScale)
|
||||
pixels = ctx.getImageData(relative_x, relative_y, 1, 1).data
|
||||
|
||||
@colorField.val("rgb(#{pixels.slice(0,3).join(',')})").trigger('change')
|
||||
|
||||
|
|
|
@ -19,16 +19,17 @@
|
|||
<div class="form-group">
|
||||
<label class="formGroup-label"><%- @T('Preview Width') %></label>
|
||||
<div class="control">
|
||||
<div class="select-tabs js-selectBrowserWidth">
|
||||
<div class="tab" data-value="375">iPhone 6</div>
|
||||
<div class="tab" data-value="fit">1:1</div>
|
||||
<div class="tab is-selected" data-value="1280">MacBook</div>
|
||||
<div class="select-tabs js-selectBrowserSize">
|
||||
<div class="tab" data-size="mobile">Mobile</div>
|
||||
<div class="tab" data-size="1:1">1:1</div>
|
||||
<div class="tab is-selected" data-size="desktop">Desktop</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="preview-iframe" class="formGroup-label"><%- @T('Preview') %></label>
|
||||
<div class="browser chat-demo js-browser">
|
||||
<div class="browser chat-demo js-browser" data-size="desktop">
|
||||
<div class="browser-ratio">
|
||||
<form class="browser-head js-demo-head" novalidate>
|
||||
<div class="browser-input">
|
||||
<input type="url" class="js-testurl-input" id="preview-iframe" value="<%= @previewUrl %>" placeholder="www.zammad.org">
|
||||
|
@ -38,7 +39,7 @@
|
|||
</form>
|
||||
<div class="browser-body js-browserBody">
|
||||
<div class="browser-website js-website">
|
||||
<img class="js-screenshot">
|
||||
<img class="browser-website-background js-screenshot">
|
||||
</div>
|
||||
<style>@import "/assets/chat/chat.css";</style>
|
||||
<div class="chat-demo-animationHolder">
|
||||
|
@ -79,6 +80,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form class="js-params">
|
||||
<fieldset>
|
||||
|
|
|
@ -117,7 +117,8 @@
|
|||
|
||||
<label class="formGroup-label"><%- @T('Preview') %></label>
|
||||
|
||||
<div class="browser form-demo js-browser">
|
||||
<div class="browser js-browser">
|
||||
<div class="browser-ratio">
|
||||
<div class="browser-body js-browserBody">
|
||||
<div class="browser-website centered vertical fit">
|
||||
<div class="btn js-formBtn"><%- @T('Feedback') %></div>
|
||||
|
@ -126,6 +127,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h3><%- @T('Requirements') %></h3>
|
||||
<p><%- @T("Zammad Forms requires jQuery. If you don't already use it on your website include it like this:") %></p>
|
||||
<pre><code class="language-html js-code"><script src="https://code.jquery.com/jquery-2.1.4.min.js"></script></code></pre>
|
||||
|
|
|
@ -10040,32 +10040,82 @@ output {
|
|||
|
||||
.browser {
|
||||
margin: 0 0 20px;
|
||||
position: relative;
|
||||
|
||||
&[data-size] {
|
||||
padding-bottom: 65%; // 16:10 aspect ratio;
|
||||
|
||||
.browser-ratio {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
transition: 500ms;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.browser-body {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&[data-size="mobile"] .browser-ratio {
|
||||
width: 375px;
|
||||
}
|
||||
|
||||
&-ratio {
|
||||
border: 1px solid hsl(0,0%,90%);
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
transition: 500ms;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: #{1280 + $sidebarWidth + $navigationWidth}) {
|
||||
// hide 1:1 button when it gets inrelevant
|
||||
[data-size="1:1"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.browser[data-size="mobile"] .browser-ratio {
|
||||
width: 500px;
|
||||
}
|
||||
}
|
||||
|
||||
.browser-body {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 450px;
|
||||
padding: 20px;
|
||||
|
||||
&-inner {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.browser-website {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
transform-origin: left top;
|
||||
transform-origin: right bottom;
|
||||
transition: 500ms;
|
||||
overflow: hidden;
|
||||
|
||||
&.is-picking {
|
||||
cursor: image_url("/assets/images/eyedropper.gif") 0 15, auto;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: bottom;
|
||||
&-background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: left top;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue