Skip to content

Instantly share code, notes, and snippets.

@e1blue
Created July 26, 2018 03:19
Show Gist options
  • Select an option

  • Save e1blue/ba84e7236da39c85f4f6e876fdbdbdec to your computer and use it in GitHub Desktop.

Select an option

Save e1blue/ba84e7236da39c85f4f6e876fdbdbdec to your computer and use it in GitHub Desktop.
3D SVG Orange 🍊

3D SVG Orange 🍊

An experiment into adding some fake depth to an SVG fruit slice, isometric style!

Edit: I've added a noise filter to the orange skin but it only appears on desktop - mobile performance just isn't good enough for filters yet.

A Pen by Chris Gannon on CodePen.

License.

<svg viewBox="0 0 800 600" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="noise" >
<feTurbulence id="turbulence" type="fractalNoise" baseFrequency="30" result="noisy" seed="0" />
<feColorMatrix type="saturate" values="0"/>
<feBlend in2="SourceGraphic" in2="noisy" mode="multiply" />
</filter>
<radialGradient id="orangeGrad" cx="82" cy="70" r="123" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#f19726"/>
<stop offset="0.44" stop-color="#e48f27"/>
<stop offset="0.85" stop-color="#a36a2c"/>
<stop offset="1" stop-color="#7a5227"/>
</radialGradient>
<radialGradient id="orangeShadowGrad" cx="144.47" cy="-26.74" r="143.41" gradientTransform="translate(37.39 65.2) scale(0.71 0.29)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#807670"/>
<stop offset="1" stop-color="#e8e5da"/>
</radialGradient>
<g id="orangeMorph">
<path id="orangeStart" d="M210,105A105,105,0,0,1,0,105c0-3,47,0,105,0S210,104,210,105Z" />
<path id="orangeEnd" d="M210,105A105,105,0,1,1,105,0,105,105,0,0,1,210,105Z" fill="none"/>
<path id="orangeEnd2" d="M210,105c0,2-47,0-105,0S0,108,0,105a105,105,0,0,1,210,0Z" fill="none"/>
</g>
<path id="orangeShadow" d="M278,56.42c0,31.17-62.23,56.43-139,56.43S0,87.59,0,56.42,62.23,0,139,0,278,25.26,278,56.42Z" fill="url(#orangeShadowGrad)"/>
<g id="orangeWithShadow">
<g id="_3dOrange">
<g >
<use id="orangeToFilter" mask="url(#orangeMask)" xlink:href="#orangeMorph" fill="url(#orangeGrad)" opacity="1"/>
</g>
<g id="orange">
<g>
<circle cx="105" cy="105" r="99.17" fill="#FFFEDA"/>
<path d="M105,210A105,105,0,1,1,210,105,105.12,105.12,0,0,1,105,210ZM105,6.52A98.48,98.48,0,1,0,203.48,105,98.59,98.59,0,0,0,105,6.52Z" fill="#f19726"/>
</g>
<g>
<path d="M103.53,17.57s30.46-1.9,24.75,14.28S110.2,82.31,110.2,82.31,107.34,88,104.48,88s-5.71-2.86-6.66-5.71-19-49.51-19-53.32S76.88,20.43,103.53,17.57Z" fill="#FAB82E"/>
<path d="M47.65,38.26s22.11-21,28.14-5S94.37,83.56,94.37,83.56s1.48,6.21-.71,8-6.21,1.48-8.77-.09S38.48,65.83,36,62.92,29.07,57.58,47.65,38.26Z" fill="#FAB82E"/>
<path d="M17.53,90.24s3.41-30.33,18.36-21.89S82.44,94.92,82.44,94.92s5.13,3.8,4.63,6.62-3.8,5.13-6.78,5.57-52.06,10.15-55.81,9.49S15.71,117,17.53,90.24Z" fill="#FAB82E"/>
<path d="M27.87,149.43S11,124,27.86,120.85s52.74-9.56,52.74-9.56,6.38-.38,7.8,2.09.39,6.38-1.61,8.63-33.35,41.24-36.65,43.14S43.67,171.08,27.87,149.43Z" fill="#FAB82E"/>
<path d="M74.26,188.31S45,179.68,55.88,166.43,90.13,125.2,90.13,125.2s4.64-4.39,7.32-3.41,4.4,4.64,4.31,7.65,1,53-.34,56.6S100.28,194.75,74.26,188.31Z" fill="#FAB82E"/>
<path d="M134.78,188.29s-28,12.21-28.14-4.95-.26-53.6-.26-53.6.73-6.35,3.41-7.32,6.35.73,8.22,3.08,34.82,40,36.12,43.59S158.85,176.49,134.78,188.29Z" fill="#FAB82E"/>
<path d="M180.94,149.78s-13.58,27.33-24.74,14.29-34.66-40.89-34.66-40.89-3.51-5.33-2.09-7.8,5.33-3.52,8.28-2.91,52.39,8.26,55.69,10.16S191.79,125.27,180.94,149.78Z" fill="#FAB82E"/>
<path d="M191.35,91s7.16,29.67-9.77,26.85-52.83-9-52.83-9-6.12-1.82-6.61-4.63,1.82-6.12,4.47-7.56,45.44-27.34,49.19-28S183.91,65.27,191.35,91Z" fill="#FAB82E"/>
<path d="M161.36,39.75s24.56,18.12,9.79,26.85-46.29,27-46.29,27-5.86,2.54-8,.71-2.54-5.86-1.43-8.66,17.23-50.16,19.68-53.08S139.11,24.8,161.36,39.75Z" fill="#FAB82E"/>
</g>
</g>
</g>
</g>
<mask id="orangeMask">
<use xlink:href="#orangeMorph" fill="#FFF"/>
</mask>
</defs>
<use class="orangeShadow" xlink:href="#orangeShadow" x="262" y="480" opacity="0.3"/>
<use class="wholeOrange" xlink:href="#orangeWithShadow" x="285" y="185"/>
</svg>
class App {
select = e => document.querySelector(e);
mainTl = new TimelineMax({repeat:-1});
constructor(){
TweenMax.set('svg', {
visibility: 'visible'
});
const orangeStart = this.select('#orangeStart');
const orangeEnd = this.select('#orangeEnd');
const orangeEnd2 = this.select('#orangeEnd2');
const orange = this.select('#orange');
const wholeOrange = this.select('.wholeOrange');
const orangeShadow = this.select('#orangeShadow');
const timeTl = new TimelineMax();
this.mainTl.add(timeTl);
const rotateTl = new TimelineMax({paused:true});
rotateTl.to(orange, 2, {
scaleY:0,
transformOrigin:'50% 50%',
ease:Linear.easeNone
})
.to(orangeStart, 2, {
morphSVG:orangeEnd,
ease:Linear.easeNone
})
.to(orangeStart, 2, {
morphSVG:orangeEnd2,
ease:Linear.easeNone
})
.to(orange, 2, {
scaleY:1,
ease:Linear.easeNone
})
.to(wholeOrange, 4, {
y:-20,
repeat:1,
ease:Sine.easeInOut,
yoyo:true
},0)
.from(orangeShadow, 4, {
scaleY:0.76,
transformOrigin:'50% 50%',
repeat:1,
ease:Sine.easeIn,
yoyo:true
},0)
.from('#noise #turbulence', 8, {
attr:{
seed:60
},
ease:Linear.easeNone
},0);
timeTl.to(rotateTl, 2, {
time:rotateTl.duration(),
ease:Sine.easeInOut
})
if(! /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
this.select('#orangeToFilter').setAttribute('filter', 'url(#noise)')
}
}
}
var app = new App();
<script src="//s3-us-west-2.amazonaws.com/s.cdpn.io/16327/MorphSVGPlugin.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/2.0.1/TweenMax.min.js"></script>
body {
background-color: #E8E5DA;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
}
body,
html {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
svg {
width: 100%;
height: 100%;
visibility: hidden;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment