Skip to content

Instantly share code, notes, and snippets.

@krivaten
Last active July 26, 2017 20:02
Show Gist options
  • Save krivaten/0a212a3de9ca0e7e6a98c23c44cff267 to your computer and use it in GitHub Desktop.
Save krivaten/0a212a3de9ca0e7e6a98c23c44cff267 to your computer and use it in GitHub Desktop.
Bubble Step
import Ember from 'ember';
const {
get,
computed
} = Ember;
export default Ember.Component.extend({
tagName: 'svg',
attributeBindings: [
'width',
'viewbox'
],
width: null,
bubbleCount: 1,
bubbleSize: 40,
barSize: 100,
viewbox: computed('bubbleIndex', 'bubbleCount', function() {
const count = get(this, 'bubbleCount');
const bubbleSize = get(this, 'bubbleSize');
const barSize = get(this, 'barSize');
const totalSize = bubbleSize + barSize;
return `0 0 ${count * totalSize} ${bubbleSize}`;
})
});
import Ember from 'ember';
const {
get,
computed
} = Ember;
export default Ember.Component.extend({
tagName: 'g',
attributeBindings: [
'componentTransform:transform'
],
activeBubbleIndex: 0,
bubbleCount: null,
bubbleIndex: null,
bubbleSize: 40,
barSize: 40,
offset: 3,
notComplete: computed.not('isComplete'),
showIncompleteBar: computed.and('bubbleIndex', 'notComplete'),
isSuccess: computed.or('isComplete', 'isActive'),
isFirst: computed.equal('bubbleIndex', 0),
isLast: computed('bubbleIndex', 'bubbleCount', function() {
const index = get(this, 'bubbleIndex');
const count = get(this, 'bubbleCount');
return count === (index + 1);
}),
barPos: computed('bubbleIndex', function() {
const index = get(this, 'bubbleIndex');
const bubbleSize = get(this, 'bubbleSize');
return index ? 0 : bubbleSize / 2;
}),
barWidth: computed('barSize', 'bubbleSize', function() {
const isLast = get(this, 'isLast');
const bubbleSize = get(this, 'bubbleSize');
const barSize = get(this, 'barSize');
const index = get(this, 'bubbleIndex');
let result;
if (isLast) {
result = barSize + (bubbleSize / 2);
} else if (index) {
result = barSize + bubbleSize;
} else {
result = bubbleSize / 2;
}
return result;
}),
circleX: computed('bubbleSize', 'bubbleIndex', 'barSize', function() {
const index = get(this, 'bubbleIndex');
const bubbleSize = get(this, 'bubbleSize') / 2;
const barSize = get(this, 'barSize');
const offset = get(this, 'offset');
return index ? barSize + bubbleSize : bubbleSize;
}),
bubbleNumber: computed('bubbleIndex', function() {
return get(this, 'bubbleIndex') + 1;
}),
isComplete: computed('bubbleIndex', 'bubbleCount', function() {
const index = get(this, 'bubbleIndex');
const activeBubbleIndex = get(this, 'activeBubbleIndex');
return (index + 1) <= activeBubbleIndex;
}),
isActive: computed('bubbleIndex', 'bubbleCount', function() {
const index = get(this, 'bubbleIndex');
const activeBubbleIndex = get(this, 'activeBubbleIndex');
return (index + 1) === activeBubbleIndex;
}),
fillColor: computed('isSuccess', function() {
return get(this, 'isSuccess') ? '#81c13b' : '#979797';
}),
circleStrokeColor: computed('isSuccess', function() {
return get(this, 'isSuccess') ? '#81c13b' : '#979797';
}),
circleFillColor: computed('isSuccess', function() {
return get(this, 'isSuccess') ? '#81c13b' : '#e0e0e0';
}),
componentTransform: computed('bubbleIndex', 'bubbleCount', function() {
const index = get(this, 'bubbleIndex');
const barSize = get(this, 'barSize');
const bubbleSize = get(this, 'bubbleSize');
const totalSize = barSize + (bubbleSize);
const calculatedSize = index ? (totalSize * (index - 1)) + bubbleSize : 0;
return index ? `translate(${calculatedSize - (index)})` : undefined;
}),
checkPosX: computed('bubbleIndex', 'barSize', function() {
const index = get(this, 'bubbleIndex');
const barSize = get(this, 'barSize');
return index ? `translate(${barSize * index})` : undefined;
})
});
import Ember from 'ember';
export default Ember.Controller.extend({
activeBubbleIndex: 3,
bubbles: [
'Panda',
'Monkey',
'Thylacine',
'Honey Badger',
'Tiger',
'Pony'
]
});
import { helper } from 'ember-helper';
import { typeOf } from 'ember-utils';
export function repeat([length, value]) {
if (typeOf(length) !== 'number') {
return [value];
}
return Array.apply(null, { length }).map(() => value); // eslint-disable-line
}
export default helper(repeat);
body {
margin: 12px 16px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 12pt;
}
.awesome-sauce {
position: relative;
}
svg {
width: 100%;
}
<div class="awesome-sauce">
{{#bubble-container bubbleCount=bubbles.length as |bubbleSize barSize|}}
{{#each bubbles as |bubble index|}}
{{progress-bubble
activeBubbleIndex=activeBubbleIndex
bubbleIndex=index
bubbleSize=bubbleSize
bubbleCount=bubbles.length
barSize=barSize}}
{{/each}}
{{/bubble-container}}
</div>
<rect x="{{barPos}}" y="12" width="{{barWidth}}" height="18" fill="{{fillColor}}"></rect>
<circle stroke="{{circleStrokeColor}}" fill="{{circleFillColor}}" stroke-width="1" cx="{{circleX}}" cy="20" r="19"></circle>
{{#if showIncompleteBar}}
<rect x="{{barPos}}" y="13" width="{{barWidth}}" height="16" fill="#e0e0e0"></rect>
<text text-anchor="middle" alignment-baseline="middle" x={{circleX}} y=20 fill="{{fillColor}}">{{bubbleNumber}}</text>
{{/if}}
{{#if isActive}}
<circle stroke="#FFFFFF" fill="#FFFFFF" stroke-width="2" cx={{circleX}} cy="20" r="7"></circle>
{{else if isComplete}}
<polyline fill="none" stroke="#FFFFFF" stroke-width="4" stroke-linecap="square" stroke-linejoin="square" points="10 21 17 27 29 13" transform="{{checkPosX}}"></polyline>
{{/if}}
{
"version": "0.12.1",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "2.12.0",
"ember-template-compiler": "2.12.0",
"ember-testing": "2.12.0"
},
"addons": {
"ember-data": "2.12.1"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment