Skip to content

Commit

Permalink
Proper image scaler
Browse files Browse the repository at this point in the history
  • Loading branch information
samdenty committed May 14, 2018
1 parent d4e660b commit 83311b1
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 44 deletions.
4 changes: 0 additions & 4 deletions src/components/Messages/Message/Embed/elements/thumbnail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,8 @@ export const Thumbnail = styled<Props, any>(ExpandableImage)`
: /^article|image$/.test(theme.embed.type)
? css`
margin-top: 8px;
width: 400px;
height: auto;
`
: css`
max-height: 80px;
margin-left: 20px;
max-width: 80px;
`};
`
25 changes: 20 additions & 5 deletions src/components/Messages/Message/Embed/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,28 @@ const EmbedField = ({ name, value, inline }) => {
)
}

const EmbedThumbnail = ({ proxyURL, height, width }) =>
proxyURL ? <Thumbnail src={proxyURL} height={height} width={width} /> : null
const EmbedThumbnail = ({ type, proxyURL, height, width }) =>
proxyURL ? (
<Thumbnail
src={proxyURL}
height={height}
width={width}
maxWidth={/^article|image$/.test(type) ? 400 : 80}
maxHeight={/^article|image$/.test(type) ? 300 : 80}
/>
) : null

const EmbedImage = ({ proxyURL, height }) =>
const EmbedImage = ({ proxyURL, height, width }) =>
proxyURL ? (
<span>
<Thumbnail rich src={proxyURL} />
<Thumbnail
rich
src={proxyURL}
height={height}
width={width}
maxWidth={400}
maxHeight={300}
/>
</span>
) : null

Expand Down Expand Up @@ -190,7 +205,7 @@ const Embed = ({
<EmbedDescription content={description} />
<EmbedFields fields={fields} />
</div>
<EmbedThumbnail {...thumbnail} />
<EmbedThumbnail type={embed.type} {...thumbnail} />
</Content>
<EmbedImage {...image} />
<EmbedFooter timestamp={timestamp} {...footer} />
Expand Down
38 changes: 7 additions & 31 deletions src/components/Messages/Message/Markdown/elements/media.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,23 @@
import ExpandableImage from 'styled-elements/ExpandableImage'
import styled, { css } from 'typed-emotion'

enum Max {
height = 300,
width = 400
}
import { Scale } from 'styled-elements/ScaledImage'

interface ImageProps {
height: number
width: number
}

/**
* Scales an image to a selected max values
*/
const scale = (Image: ImageProps) => {
if (Image.width && Image.height) {
const ratio =
Image.height < Image.width ? ['width', 'height'] : ['height', 'width']

const factor =
Image[ratio[0]] > Max[ratio[0]]
? ratio[0]
: Image[ratio[1]] > Max[ratio[1]]
? ratio[1]
: null

const scale = factor ? Max[factor] / Image[factor] : 1

return css`
width: ${Image.width * scale}px;
height: ${Image.height * scale}px;
`
}
return null
}

export const Image = styled<ImageProps, any>(ExpandableImage)`
display: block;
margin: 10px 0;
cursor: pointer;
border-radius: 3px;
${scale};
${props =>
new Scale({
...props,
maxWidth: 400,
maxHeight: 300
}).css};
@media (max-width: 700px) {
width: 65%;
Expand Down
11 changes: 10 additions & 1 deletion src/modules/styled-elements/ExpandableImage/elements.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import styled from 'typed-emotion'

import { Loading } from '../../../components/Overlays'
import { Scale } from 'styled-elements/ScaledImage'

export const Root = styled('div')`
interface Props {
maxHeight: number
maxWidth: number
height: number
width: number
}

export const Root = styled<Props, 'div'>('div')`
position: relative;
overflow: hidden;
${props => new Scale(props).css};
`

export const Image = styled('img')`
Expand Down
25 changes: 22 additions & 3 deletions src/modules/styled-elements/ExpandableImage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import { Image, Loader, Root } from './elements'
interface Props {
src: string
className?: string

height?: number
width?: number
maxWidth?: number
maxHeight?: number
}

/**
Expand All @@ -22,7 +27,7 @@ const ExpandableImage = connect<Props>()
type: 'loading'
}

open = () => {
open() {
const { src, toggle } = this.props
if (src) {
toggle({
Expand All @@ -34,10 +39,24 @@ const ExpandableImage = connect<Props>()
}

render() {
const { className, src } = this.props
const {
className,
height,
width,
maxHeight,
maxWidth,
src
} = this.props

return (
<Root className={className || null} onClick={this.open}>
<Root
className={className || null}
onClick={this.open.bind(this)}
maxHeight={maxHeight}
maxWidth={maxWidth}
height={height}
width={width}
>
<Image
src={src}
onLoad={() => this.setState({ type: 'loaded' })}
Expand Down
6 changes: 6 additions & 0 deletions src/modules/styled-elements/ScaledImage/elements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import styled from 'typed-emotion'

export const Root = styled('img')`
width: ${({ width }) => (width ? `${width}px` : null)};
width: ${({ height }) => (height ? `${height}px` : null)};
`
86 changes: 86 additions & 0 deletions src/modules/styled-elements/ScaledImage/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import * as React from 'react'
import { css } from 'typed-emotion'
import { Root } from './elements'

interface Scaler {
width?: number
height?: number
maxWidth?: number
maxHeight?: number
}
interface Props extends Scaler {
src: string
className?: string
}

class ScaledImage extends React.PureComponent<Props> {
render() {
const { className, src } = this.props

const { width, height } = new Scale(this.props)

return (
<Root
className={className || ''}
src={src}
height={height}
width={width}
/>
)
}
}

export default ScaledImage

export class Scale {
public width: number
public height: number
public scale: number

public css: string

private Image: { width: number; height: number }
private Max: { width: number; height: number }

constructor({ width, height, maxWidth, maxHeight }: Scaler) {
this.Image = {
width,
height
}
this.Max = {
height: maxHeight,
width: maxWidth
}

this.scaleImage()

this.css = css`
${this.width && `width: ${this.width}px`};
${this.height && `height: ${this.height}px`};
`
}

scaleImage() {
const { Image, Max } = this

if (!(Image.width && Image.height)) {
return {}
}

const ratio =
Image.height < Image.width ? ['width', 'height'] : ['height', 'width']

const factor =
Image[ratio[0]] > Max[ratio[0]]
? ratio[0]
: Image[ratio[1]] > Max[ratio[1]]
? ratio[1]
: null

const scale = factor ? Max[factor] / Image[factor] : 1

this.scale = scale
this.width = Image.width * scale
this.height = Image.height * scale
}
}

0 comments on commit 83311b1

Please sign in to comment.