- var y_table_top = 100;
- var x_table_support = 90;
- var r_table_foot = 65;
- var x_glass = 87;
- var y_glass = -215;
- var d_ctrl = 20;
- var x_diff_liquid = 7;
- var y_diff_liquid_top = 50;
- var y_diff_liquid_bottom = 20;
- var r_orange = 65;
- var n_slices = 8;
- var slice_deg = 360/n_slices;
- var slice_rad = 2*Math.PI/n_slices;
- var x_slice = Math.round(r_orange*Math.cos(slice_rad));
- var y_slice = Math.round(r_orange*Math.sin(slice_rad));
- var k_orange = (r_orange + d_ctrl)/r_orange;
- var xc_slice = Math.round(k_orange*x_slice);
- var yc_slice = Math.round(k_orange*y_slice);
svg(viewbox='-600 -500 1200 900')
defs
ellipse#te(cy='#{y_table_top}'
rx='190' ry='40')/
linearGradient#table(gradientTransform='rotate(90)')
stop(offset='0%' stop-color='#f2740c')/
stop(offset='100%' stop-color='#f6781b')/
path#liquid(d='M#{-(x_glass - x_diff_liquid)} #{y_glass + y_diff_liquid_top} L#{(x_glass - x_diff_liquid)} #{y_glass + y_diff_liquid_top} L#{(x_glass - x_diff_liquid)} #{y_table_top - y_diff_liquid_bottom} C#{(x_glass - x_diff_liquid)} #{y_table_top - y_diff_liquid_bottom + d_ctrl} #{-(x_glass - x_diff_liquid)} #{y_table_top - y_diff_liquid_bottom + d_ctrl} #{-(x_glass - x_diff_liquid)} #{y_table_top - y_diff_liquid_bottom}')/
circle#bubble(r='7')/
circle#bubble-small(r='5')/
path#slice(d='M0 0 L#{r_orange} 0 C#{r_orange + d_ctrl} 0 #{xc_slice} #{yc_slice} #{x_slice} #{y_slice}z' transform='rotate(#{-.5*slice_deg}) scale(.8)')/
linearGradient#glass
stop(offset='50%' stop-color='rgba(255, 255,255,.3)')/
stop(offset='50%' stop-color='rgba(255, 255,255,.2)')/
g#assembly
g.table
path.table__support(d='M#{-x_table_support} #{y_table_top} L#{x_table_support} #{y_table_top} L#{x_table_support} #{y_table_top + 195} A#{r_table_foot} #{r_table_foot} 0 0 1 #{x_table_support + r_table_foot} #{y_table_top + 195 + r_table_foot} L#{-x_table_support - r_table_foot} #{y_table_top + 195 + r_table_foot} A#{r_table_foot} #{r_table_foot} 0 0 1 #{-x_table_support} #{y_table_top + 195}z')/
use.table__main(xlink:href='#te' y='15')/
use.table__top(xlink:href='#te')/
g.orange(transform='translate(#{x_glass} #{y_glass}) rotate(#{.25*slice_deg})')
circle(r='#{r_orange}')/
g.slices
while n_slices--
use(xlink:href='#slice' transform='rotate(#{n_slices*slice_deg}) translate(2)')/
circle(r='10')/
g.content--bg
use(xlink:href='#liquid')/
line.straw(x1='-72' y1='-378' x2='16' y2='84')/
g.content
use(xlink:href='#liquid')/
g.bubbles
use(xlink:href='#bubble' x='-19' y='-114')/
use(xlink:href='#bubble' x='-48' y='-78')/
use(xlink:href='#bubble' x='-36' y='-14')/
use(xlink:href='#bubble' x='-18' y='41')/
use(xlink:href='#bubble-small' x='-48' y='31')/
use(xlink:href='#bubble' x='53' y='43')/
use(xlink:href='#bubble' x='27' y='-2')/
use(xlink:href='#bubble' x='16' y='-49')/
use(xlink:href='#bubble-small' x='48' y='-48')/
use(xlink:href='#bubble-small' x='29' y='-80')/
use(xlink:href='#bubble-small' x='62' y='-83')/
path.glass(d='M#{-x_glass} #{y_glass} L#{x_glass} #{y_glass} L#{x_glass} #{y_table_top} C#{x_glass} #{y_table_top + d_ctrl} #{-x_glass} #{y_table_top + d_ctrl} #{-x_glass} #{y_table_top}')/
View Compiled
$bg: #f5891f /* top */, #f6781b /*bottom*/;
$table: #f58420 #f2740c;
$orange: #fcc786;
$liquid: #99d6ff;
$bubble: #b6d9f1;
@mixin proportional-box($a: 4, $b: 3) {
position: absolute;
top: 0; left: calc(50vw - #{$a/$b*50vh});
width: $a/$b*100vh; height: 100vh;
@media (max-aspect-ratio: #{$a}/#{$b}) {
top: calc(50vh - #{$b/$a*50vw}); left: 0;
width: 100vw; height: $b/$a*100vw;
}
}
html { background: #222; }
svg {
overflow: hidden; /* because IE */
@include proportional-box();
background: linear-gradient($bg);
}
.assembly { opacity: 0; }
.table {
&__top { fill: nth($table, 1); }
&__main { fill: nth($table, 2); }
&__support { fill: url(#table); }
}
.orange {
circle { fill: $orange; }
use { fill: nth($bg, 1); }
}
.straw {
stroke: #fff;
stroke-width: 13;
}
.content {
use { fill: rgba($liquid, .4); }
&--bg use { fill: rgba($liquid, .5); }
}
[id*='bubble'] {
fill: none;
stroke: rgba($bubble, .95);
stroke-width: 5;
}
.glass { fill: url(#glass); }
View Compiled
Object.getOwnPropertyNames(Math).map(function(p) {
window[p] = Math[p];
});
var timeline = {
'glassEnter': 20,
'glassStop': 50,
'oscStop': 120,
'glassStart': 130,
'glassExit': 160,
'end': 180
},
assembly = document.getElementById('assembly'),
x_off, x,
liquid = document.getElementById('liquid'),
d_fixed, x_fixed, y_base, amp = 45,
t = 0;
var init = function() {
var svg = document.querySelector('svg'),
vb = svg.getAttribute('viewBox').split(' '),
vb_w = ~~vb[2], vb_x = ~~vb[0],
te = document.getElementById('te'),
max_assembly_w = 2*te.getAttribute('rx'),
d_a = liquid.getAttribute('d').split('L'), a_tmp;
x_off = vb_w + vb_x + .5*max_assembly_w;
x = -x_off;
a_tmp = d_a[0].replace('M', '').split(' ');
x_fixed = abs(~~a_tmp[0]);
y_base = ~~a_tmp[1];
if(!a_tmp[0]) { // oh, IE...
x_fixed = abs(~~a_tmp[1]);
y_base = ~~a_tmp[2];
}
d_a.splice(0, 2);
d_fixed = ' L' + d_a.join(' L');
assembly.setAttribute('transform', 'translate(' + x_off + ')');
assembly.style.opacity = 1;
ani();
};
var ani = function() {
var dt, t_rel, curr_amp, curr_d;
if(t > timeline.end) { t = 0; }
if(t >= timeline.glassEnter) {
t_rel = t - timeline.glassEnter;
if(t <= timeline.glassStop) {
dt = timeline.glassStop - timeline.glassEnter;
x = -x_off*pow(1 - t_rel/dt, 3);
assembly.setAttribute('transform', 'translate(' + x + ')');
}
if(t <= timeline.oscStop) {
dt = timeline.oscStop - timeline.glassEnter;
curr_amp = amp*(1 - t_rel/dt);
y_var = round(curr_amp*cos(t_rel/dt*3*PI));
curr_d = 'M' + -x_fixed + ' ' + (y_base - y_var) +
' L' + x_fixed + ' ' + (y_base + y_var) + d_fixed;
liquid.setAttribute('d', curr_d);
}
}
if(t >= timeline.glassStart && t <= timeline.glassExit) {
dt = timeline.glassExit - timeline.glassStart;
t_rel = t - timeline.glassStart;
x = x_off*pow(t_rel/dt, 2);
assembly.setAttribute('transform', 'translate(' + x + ')');
curr_amp = amp*t_rel/dt;
y_var = round(curr_amp*sin(t_rel/dt*1.5*PI));
curr_d = 'M' + -x_fixed + ' ' + (y_base - y_var) +
' L' + x_fixed + ' ' + (y_base + y_var) + d_fixed;
liquid.setAttribute('d', curr_d);
}
t++;
requestAnimationFrame(ani);
};
init();
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.