├── README.md
├── css
└── style.css
├── index.html
└── js
├── exampleUsage.js
├── smartContentPlacer.js
└── smartContentPlacer_min.js
/README.md:
--------------------------------------------------------------------------------
1 | Smart-Content-Placer
2 | ====================
3 |
4 | A small JavaScript class to programmatically position difficult content. What do I mean by that? Well lets assume you have many images which are different widths and heights. How do you place them on a page such that there are no "gaps"? This is basically a constrained bin packing problem. Using just CSS this is a no go as you will end up with blocks of whitespace appearing, thus some JavaScript is required. This little component allows for variable width and height content - imagine Pinterest on steroids (Pinterest only allows for variable height).
5 |
6 | ## Live Demo
7 |
8 | Please read comments in JavaScript for examples on how to use.
9 |
10 | A live demo is available on my website - resize the window to see how it adapts:
11 | http://jasonmayes.com/projects/contentPlacer/
12 |
13 | 
14 |
15 | ## Key features
16 |
17 | * Fully responsive (up to the largest element width used).
18 | * Allows for variable width AND height content. All content must be a multiple of a base unit size.
19 | * Works with any type of responsive content (not just images).
20 | * Supports margins between content.
21 | * Works in all modern browsers.
22 | * Supports transitions for initial display and for fluid repositioning of content.
23 | * Requires no 3rd party libraries to work - pure native JavaScript.
24 | * Lightweight and efficient.
25 | * Fully customizable - all transitions / style is defined via CSS.
26 |
27 | ## Why does this exist?
28 |
29 | After a quick Google it seemed many other existing solutions required some third party library to work (jQuery), or were not as efficient as I wanted. I therefore decided to roll my own from a blank canvas to keep it as lightweight and efficient as possible.
30 |
31 | ## Browser support
32 |
33 | All popular browsers supported. Chrome, Firefox, Safari, Opera, Internet Explorer 9+ and I have tested on Android/iOS which seems to be fine too.
34 | 
35 |
36 | ## Got suggestions? Feedback? Feature requests? Tell me!
37 |
38 | Really, I like to hear feedback, and love to see what projects you have used it in. Feel free to give me a shoutout if you have used it.
39 | Talk to me: Via [Google+](https://plus.google.com/110804953626559077511/posts/iPbbwX7ivqW), [twitter](http://www.twitter.com/jason_mayes), or my [website](http://www.jasonmayes.com/).
40 |
41 | ## Terms
42 |
43 | Feel free to use in your own personal projects. I only ask you keep any disclaimers with my code (even if code is modified / minified) so others can find the original source should they wish to get updates or support. A link back / social media shout out is always appreciated to help others discover it (and for me to see what great things it is being used for) but not required :-)
44 |
45 | If you plan to use in a commercial project please contact me first if you are unable to adhere to the above terms.
46 |
--------------------------------------------------------------------------------
/css/style.css:
--------------------------------------------------------------------------------
1 | /*
2 | * General Styles - not component critical but used to achieve demo
3 | * look and feel.
4 | */
5 |
6 | html, body {
7 | margin:0;
8 | }
9 |
10 | body {
11 | font-family:Arial,"Liberation Sans",sans-serif;
12 | }
13 |
14 | h1, p {
15 | margin:25px;
16 | color:#3d3d3d;
17 | margin-bottom:10px;
18 | }
19 |
20 | p {
21 | color:#7d7d7d;
22 | padding-right:100px;
23 | float:left;
24 | margin:0 25px 25px 25px;
25 | font-size:10pt;
26 | }
27 |
28 | #intro1, #intro2, #intro3 {
29 | font-size:12pt;
30 | }
31 |
32 | #linkage {
33 | position:fixed;
34 | top:70px;
35 | right:0px;
36 | background-color:#2d2d3d;
37 | color:#ffffff;
38 | text-decoration:none;
39 | padding:10px;
40 | width:100px;
41 | z-index:2;
42 | }
43 |
44 | #listView {
45 | width:100%;
46 | min-width:150px;
47 | clear:both;
48 | }
49 |
50 | .container {
51 | margin:25px;
52 | }
53 |
54 | .hide {
55 | display:none;
56 | }
57 |
58 | .contentPlacerContainer .bar {
59 | position:absolute;
60 | bottom:0;
61 | height:50px;
62 | background-color:rgba(30,30,30, 0.8);
63 | width:100%;
64 | color:#ffffff;
65 | }
66 |
67 | .contentPlacerContainer h2 {
68 | margin:6px 15px 0 10px;
69 | font-size:10pt;
70 | }
71 |
72 | .contentPlacerContainer p {
73 | color:#dfdfdf;
74 | margin:5px 15px 0 10px;
75 | font-size:10pt;
76 | float:none;
77 | padding:0;
78 | }
79 |
80 | .contentPlacerContainer .content {
81 | width:100%;
82 | height:100%;
83 | overflow:hidden;
84 | background-repeat:no-repeat;
85 | background-size:cover;
86 | display:block;
87 | position:relative;
88 | }
89 |
90 |
91 | /*
92 | * Component Critical Styles - you must include these!
93 | * Dont change unless you know what you are doing.
94 | */
95 |
96 | .contentPlacerContainer {
97 | position:relative;
98 | margin:0;
99 | padding:0;
100 | }
101 |
102 | .contentPlacerContainer .contentPlacerElement {
103 | position:absolute;
104 | overflow:hidden;
105 | opacity:1;
106 | background-color:transparent;
107 | }
108 |
109 | .contentPlacerElement.hidden {
110 | opacity:0;
111 | -ms-Transform:scale(0, 0);
112 | -webkit-Transform: scale(0, 0);
113 | transform: scale(0, 0);
114 | }
115 |
116 | .contentPlacerContainer .transition {
117 | -webkit-transition: all 500ms ease-in-out;
118 | -moz-transition: all 500ms ease-in-out;
119 | -o-transition: all 500ms ease-in-out;
120 | transition: all 500ms ease-in-out;
121 | }
122 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 seconds after this page loads we shall change the margin to 1px and the base unit size to 200px.
14 |
In another 5 seconds we shall simulate updating the component with new data (e.g. from some API) and change the draw speed.
15 |
Cool huh? Now resize this page!
16 |
I have created a small component to programmatically position difficult content. What do I mean by that? Well lets assume you have many images which are different widths and heights. How do you fit them on a page such that there are no "gaps"? Using just CSS this is a no go. Imagine Pinterest on steroids Pinterest only allows for variable height), this little component allows for variable width and height content! Enjoy :-) Give me a shoutout if you use it, would love to see!
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/js/exampleUsage.js:
--------------------------------------------------------------------------------
1 | // ***********************************************************************
2 | // Example usage... Please note how the content is responsive to fill it's
3 | // Container - eg in this case we set image width to 100%. Content must be
4 | // responsive because if margins are used the image must be stretched ever
5 | // so slightly to compensate for margins. If you do not have responsive
6 | // data you will end up with a double margin gap on larger sized data.
7 | // ***********************************************************************
8 |
9 | // To make things easier to read I have made a little class to hold data
10 | // attributes. You could just use a JSON object with the same properties exposed
11 | // if you desired.
12 | var ContentPlacerData = function(content, unitWidth, unitHeight) {
13 | this.content = content;
14 | this.height = unitHeight;
15 | this.width = unitWidth;
16 | };
17 |
18 | var dataArrayExample = [];
19 | dataArrayExample.push(new ContentPlacerData('