Impl Responsive image (initial, needs more work)

This commit is contained in:
2018-07-11 07:31:15 +10:00
parent 17e10572ea
commit 3a97513648
8 changed files with 115 additions and 21 deletions

View File

@ -4,7 +4,7 @@
"description": "Personal website for Dominic \"YouWish\" Masters.",
"main": "private/index.js",
"scripts": {
"start": "node private/index",
"start": "node private/index",
"serve": "webpack-serve --config ./webpack.config.js",
"watch": "nodemon --watch private private/index.js",
"test": "jest"
@ -58,8 +58,11 @@
"webpack": "^4.14.0"
},
"devDependencies": {
"jimp": "^0.2.28",
"nodemon": "^1.17.5",
"react-hot-loader": "^4.3.3",
"responsive-loader": "^1.1.0",
"sharp": "^0.20.5",
"webpack-cli": "^3.0.8",
"webpack-dev-server": "^3.1.4"
}

View File

@ -22,6 +22,7 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React from 'react';
import LoadableImage from './LoadableImage';
export default class Image extends React.Component {
constructor(props) {
@ -29,6 +30,10 @@ export default class Image extends React.Component {
}
render() {
if(this.props.loadable) {
//return (<LoadableImage {...this.props} />);
}
let sourceProps = Object.assign({}, this.props);
//Prop Manipulation
@ -40,36 +45,56 @@ export default class Image extends React.Component {
}
}
if(sourceProps.src) {
if(sourceProps.src.images) sourceProps.sources = sourceProps.src.images;
if(sourceProps.src.width) sourceProps.width = sourceProps.src.width;
if(sourceProps.src.height) sourceProps.height = sourceProps.src.height;
}
//Image
let sourceElements = [];
let sources = {};
let defaultSrc = sourceProps.src;
let defaultAlt = sourceProps.alt;
let defaultWidth = sourceProps.width;
let defaultHeight = sourceProps.height;
console.log(defaultSrc);
if(sourceProps.sources) {
//Iterate over supplied sources
for(let i = 0; i < sourceProps.sources.length; i++) {
let x = sourceProps.sources[i];
let w = x.size;
sources[w] = sources[w] || [];
sources[w].push(x);
let width = x.size || x.width;
let isLast = (i+1) === sourceProps.sources.length;
defaultSrc = defaultSrc || x.src;
defaultAlt = defaultAlt || x.alt;
for(let scale = 1; scale <= 4; scale++) {
let scaledWidth = Math.round(width / scale);
let o = Object.assign({}, x);
o.scale = scale;
o.isLast = isLast;
sources[scaledWidth] = sources[scaledWidth] || [];
sources[scaledWidth].push(o);
}
}
//Now map to components I guess
let keys = Object.keys(sources);
for(let i = 0; i < keys.length; i++) {
let k = keys[i];
let j = sources[k];
let q = j[0];
let mediaQuery = '(max-width:'+q.size+'px)';
let k = keys[i];//The pixel size
let ss = sources[k];//Sources at this pixel resolution
let mediaQuery = '(max-width:'+k+'px)';
let sss = [];
for(let p = 0; p < j.length; p++) {
let v = j[p];
sss.push(v.src + (v.scale && v.scale != 1 ? " "+v.scale+"x" : "" ) );
if(ss.length && ss[0].isLast) {
let prev = i > 0 ? keys[i-1] : 0;
mediaQuery = '(min-width:'+prev+'px)';
}
for(let x = 0; x < ss.length; x++) {
let scale = ss[x];
let source = scale.src || scale.path;
sss.push( source + (scale.scale && scale.scale!=1 ? " "+scale.scale+"x" : "") );
}
sourceElements.push(
@ -81,7 +106,13 @@ export default class Image extends React.Component {
return (
<picture>
{ sourceElements }
<img src={ defaultSrc } alt={ defaultAlt } className={ sourceProps.className } />
<img
src={ defaultSrc }
alt={ defaultAlt }
className={ sourceProps.className }
width={ defaultWidth }
height={ defaultHeight }
/>
</picture>
);
}

View File

@ -0,0 +1,40 @@
// Copyright (c) 2018 Dominic Masters
//
// MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import React from 'react';
import Image from './Image';
import Loader from './../loading/Loader';
class LoadableImage extends React.Component {
constructor(props) {
super(props);
}
render() {
let p = Object.assign({}, this.props);
p.loadable = false;
return <Image {...p} />
}
}
export default LoadableImage;

View File

@ -66,6 +66,7 @@ const ExistingWorkFrame = (props) => {
<Image
src={props.src}
alt={props.title}
loadable
className="p-home-page__work-link-image"
/>
</a>

View File

@ -31,9 +31,8 @@ export default function(props) {
image = props.image;
} else {
image = <Image
src={ props.src }
alt={ props.alt }
sources={ props.sources }
{...props}
children={null}
className="c-image-section__image"
/>;
}

View File

@ -8,5 +8,6 @@
img {
display: inline-block;
max-width: 100%;
height: auto;
border: none;
}

View File

@ -78,6 +78,7 @@
&__work-link,&__work-link-image {
display: block;
width: 100%;
}
/* Media Queries */

View File

@ -20,7 +20,7 @@ module.exports = {
path: '/dist',
filename: "app.js"
},
mode: 'development',
resolve: {
@ -43,8 +43,26 @@ module.exports = {
},
{
test: /\.jpe?g$|\.gif$|\.png$|\.svg|\.webm|\.mp4$/i,
loader: "file-loader?name=[path][name].[ext]"
test: /\.svg|\.webm|\.mp4$/i,
use: [{
loader: "file-loader",
options: {
name: "[path][name].[ext]",
context: 'public'
}
}]
},
{
test: /\.jpe?g$|\.gif$|\.png$/i,
use: [{
loader: "responsive-loader",
options: {
sizes: [128, 256, 500, 750, 1000, 1250, 1500, 2000, 2250, 2500],
name: "[path][name]_[width]x.[ext]",
context: 'public'
}
}]
},
{