Creativity in Programming
@sarah_edo
For fun and $profit$
Sarah Drasner
#CreativeCode
(504) BAYOU-AT
What does it mean to be creative?
Programming is Creative
function fizzBuzz() {
for (var i = 1; i <= 100; i++) {
if (i%5 === 0 && i%3 === 0) {
print('FizzBuzz');
} else if (i % 3 === 0) {
print ('Fizz');
} else if (i % 5 === 0) {
print ('Buzz');
} else {
print (i);
}
}
}
vs
for(i=0;i<50;)console.log(++i,i%3?'':'fizz',i%5?'':'buzz')
Important for your business
why?
- Hewlett-Packard: invested over $2 billion in R&D in 1999, and generated more than 1,300 patent applications. Net revenue: $42.37 billion.
- Frito-Lay: cost savings over a four-year period of almost $600 million due to creativity training programs
- CEOs look creativity over any other quality -survey of more than 1,500 CEOs across 33 industries and 60 countries
Sources: 1. HP 2000 Annual report 2. VanGundy, 2004, 3. IBM Survey
Important for you
Flow
- Complete immersion in tasks
- Shares traits with hyperfocus
- Loss of self-reflective conciousness
- Subjective experience of time is altered
Happiest points in life
Photos by #WOCinTech
Fighting Burnout
Not just about resting?
Experiencing flow can give a lift to other activities
Using your brain in different ways strengthens it
- Our neural pathways become set
- Thinking about varied and new subjects increases plasticity
- Flow plus varied thinking can cause reduced stress and happiness while programming for other tasks
Push yourself a little each time
*though too much at a time won't work
This demo.
How?
-
Questioning the base premises
-
Impose artificial bounds
-
Repurposing
-
Combining
-
Freedom
-
Use open source as a tool
Questioning the Base Premises
1
- “Let’s spend more money.”
- “Why don’t we spend more money, but on fewer vendors? We’ll reduce the number of vendors. We’ll place larger orders to some vendors, and we’ll get better price breaks.”
- += $1 million dollars a year savings, based upon a one-hour creativity session.
Linear Thinking
Lateral Thinking
“We reduce costs by spending less money.”
source: Tanner, Igniting Innovation
Ethernet
Token Ring Networks
Ethernet
React
Questioned:
- What if we write inline JavaScript?
- What if we don't use the DOM?
- What if we create a syntax that replaces our use for HTML?
You don't have x in CSS
- What if we have variables?
- What if we have for loops?
- What if we can use mixins to pass in parameters like functions for DRYer code?
This shaped our specs.
Impose artificial bounds
2
HSLA
Generative color is easier with HSLA because it's a little more human-readable
background: hsl(($i - 1)*($color / $color-frequency), 80%, 60%);
This demo.
This demo.
function combination() {
var combo2 = "hsl(+=5%, +=2%, -=10%)";
tl.to(body, 1, {
backgroundColor: combo2
}, "sated");
tl.to(mult, 2, {
fill: combo2
}, "sated");
...
return tl;
}
Artificial Physics
update: function (dt) {
// friction opposes the direction of velocity
var acceleration = -Math.sign(this.vx) * friction;
// distance = velocity * time + 0.5 * acceleration * (time ^ 2)
this.x += this.vx * dt + 0.5 * acceleration * (dt ^ 2);
...
}
Hack Physics and JavaScript by Rachel Smith
The Nature of Code, JS Stroll
This demo.
Recursion
...
if (length < 6) return;
cx.save();
cx.translate(0, length);
cx.rotate(-angle);
branch({length: length*scale, angle: angle, scale:scale});
...
Check a boundary
Or call itself again
This demo.
This demo.
Altering one expected thing
Works for comedy!
I haven’t slept for 10 days…
because that would be too long.
I used to do drugs.
I still do, but I used to, too.
Mitch Hedberg
This demo
Repurposing
3
This pen.
SVG
React
Request Animation Frame
GreenSock
CSS
Web technologies
const HeartMeter = React.createClass({
render() {
return (
<div>
<svg className="heartmeter" xmlns="http://www.w3.org/2000/svg" width="250" height="50" viewBox="0 0 1741.8 395.6">
<path d="M1741.8 197.7c0 109.3-89 197.8-198.8 197.8a198.6 198.6 0 0 1-158.5-78.4H11.2A11.2 11.2 0 0 1 0 305.9V89.5a11.2 11.2 0 0 1 11.2-11.1h1373.4A198.8 198.8 0 0 1 1543 0c109.8 0 198.8 88.5 198.8 197.7z" fill="#000"/>
<path d="M1591.8 127c-18.3 0-34.1 14.8-41.4 30.3-7.3-15.5-23.1-30.3-41.4-30.3a45.7 45.7 0 0 0-45.7 45.5c0 51.1 51.8 64.5 87.1 115.1 33.4-50.2 87.1-65.6 87.1-115.1a45.7 45.7 0 0 0-45.7-45.5z" fill="#b29968"/>
<rect x="68.2" y="140.8" width={this.props.score} height="101.55" fill="#9391aa"/>
</svg>
</div>
)
}
});
Request Animation Frame
(function getCoords() {
let tCoords = tC1.getBoundingClientRect(),
txCoords = txC1.getBoundingClientRect(),
mCoords = mC1.getBoundingClientRect(),
elCoords = ele1.getBoundingClientRect();
function intersectRect(a, b) {
return Math.max(a.left, b.left + 40) < Math.min(a.right, b.right - 40) &&
Math.max(a.top, b.top + 40) < Math.min(a.bottom, b.bottom - 40);
}
// can't do if/else because sometimes they both come out at once
// and one of them will be ignored
if (intersectRect(tCoords, elCoords)) {
getHitTestIncrease();
}
if (intersectRect(txCoords, elCoords)) {
getHitTestDecrease();
}
if (intersectRect(mCoords, elCoords)) {
getHitTestMargarita();
}
requestAnimationFrame(getCoords);
}());
GSAP for Animation
_flyBy: function(el, amt, name, delay) {
if (this.props._isGameOver()) return;
...
TweenMax.fromTo(el, amt, {
rotation:0,
y:randY,
x:window.innerWidth + 200
}, {
x: -200,
y:randY,
rotation: 360,
delay: delay,
onComplete:this._flyBy,
onCompleteParams:[el, amt, name, delay],
ease: Power1.easeInOut
});
},
History of Generative Art/Music
- Mozart- Musical Dice Game
- John Cage - Ambient Noises
- Max Ernst - Automatism
- Sol Lewitt- Wall Drawings
//balloon
function balloonGrow(){
var balloon = $("#balloon")[0];
var radius = balloon.getAttribute("r");
var cySet = balloon.getAttribute("cy");
balloon.setAttribute('r', parseInt(radius) + 10);
balloon.setAttribute('cy', parseInt(cySet) - 10);
if (parseInt(radius) > 125) {
ion.sound.play("balloon-pop3");
var balloonTl = new TimelineMax();
balloonTl.add("pop");
balloonTl.to("#balloon", 0.05, {
scale: 5,
opacity: 0,
transformOrigin: "50% 50%",
ease: Circ.easeOut
}, "pop");
...
setTimeout(function(){
balloon.setAttribute("r", "45");
balloon.setAttribute("cy", "233.5");
}, 200);
}
}
Touch on Mobile
Jake Albaugh
This demo.
This demo.
You already know this :)
Combining
4
Flow
Flow for our users too
Kathy Sierra- Badass: Making Users Awesome
Mapping- cognitive leaks
You're on a trip exploring a city
You want to build out the day of activities
Lonely Planet
but...
Google Maps
Let's empower the user
This demo.
DorisLeBot
By Brendan Dawes
Another Combination:
Creatures from Tweets
- Commissioned by Bright for Twitter France
- Real-time tweets
- Created from properties: color from years on twitter, following more than followed had larger antennae
- Bots are cubes
3d printing
FWA Site of the Day, 16th February 2015
Freedom
5
Umm....
Functional Programming
- Pure: Avoids changing-state and mutable data
- Eliminates side effects
- Expressions or declarations instead of statements
"Object-Oriented Programming makes code understandable by encapsulating moving parts
-Michael Feather
Functional Programming
makes code understandable by minimizing moving parts"
Imperative
var canvasElement = document.querySelector("#canvas");
var context = canvasElement.getContext("2d");
// the triangle
context.beginPath();
context.moveTo(100, 100);
context.lineTo(100, 200);
context.lineTo(200, 200);
context.closePath();
// the outline
context.lineWidth = 5;
context.strokeStyle = '#747C92';
context.stroke();
// the fill color
context.fillStyle = "#A1E8AF";
context.fill();
var canvasElement = document.querySelector("#canvas");
var context = canvasElement.getContext("2d");
// the triangle
function drawTri(size, amt) {
var amt = amt * 10;
context.beginPath();
context.moveTo(0, 0);
context.lineTo(0, size*amt);
context.lineTo(size*amt, size*amt);
context.closePath();
}
//call it
drawTri(1, 10);
// the outline
context.lineWidth = 5;
context.strokeStyle = '#747C92';
context.stroke();
// the fill color
context.fillStyle = "#A1E8AF";
context.fill();
var canvasElement = document.querySelector("#canvas");
var context = canvasElement.getContext("2d");
// the triangle
function drawTri(size, amt) {
var amt = amt * 10;
context.beginPath();
context.moveTo(0, 0);
context.lineTo(0, size*amt);
context.lineTo(size*amt, size*amt);
context.closePath();
}
//call it
drawTri(1, 10);
function appearance(stWidth, stColor, fillColor) {
// the outline
context.lineWidth = stWidth;
context.strokeStyle = stColor;
context.stroke();
// the fill color
context.fillStyle = fillColor;
context.fill();
}
//call it
appearance(5,'#747C92', '#A1E8AF');
var makeSpiral = function(value) {
if (value > 0) {
drawTri(value/10, 1);
appearance(5, '#747C92', 'hsl(' + value/2 + ', ' + (40 + (value/40)) + '%, 77%)');
return makeSpiral(value - 1);
} else {
return value;
}
};
makeSpiral(1000);
^ES6! ^
Destructured Objects as Parameters
Template Literals
// the triangle
function drawTri(
{ size = 1,
amt = 1,
stWidth = 5,
stColor = '#747C92',
fillColor = '#A1E8AF'
} = {}) {
var amt = amt * 10;
//draw the triangle
context.beginPath();
context.moveTo(0, 0);
...
// the outline
context.lineWidth = stWidth;
...
}
function makeSpiral(value) {
if (value > 0) {
//call the function to draw it
drawTri({
size: value/10,
amt: 1,
fillColor: `hsl(${value/2}, ${40 + (value/40)}%, 77%)`
});
//call makeSpiral again and change it
return makeSpiral(value - 1);
} else {
return value;
}
};
makeSpiral(1000);
Constraints are good!
Not the wrong ones.
- Custom Abstractions
- Ability to use in a multitude of fashions
- Less brittle
- Move things around easily without worry
Make use of open source for tools
5
Aframe-React
This repo
This demo
Aframe
class App extends React.Component {
render () {
...
for (let i = 0; i < 30; i++) {
...
items.push(<Entity geometry="primitive: box; depth: 1.5; height: 1.5; width: 6"
material={{color: updateColor}}
position={randoPos}
pivot="0 0.5 0"
key={i}>
<Animation attribute="rotation"
dur="12000"
to={updateRot}/>
...
</Entity>);
}
return (
<Scene>
...
{items}
</Scene>
);
}
}
This demo.
function flame() {
var tl = new TimelineMax();
tl.add("begin");
tl.fromTo(blurNode, 2.5, {
attr: {
stdDeviation: 9
}
}, {
attr: {
stdDeviation: 3
}
}, "begin");
var num = 9;
for (var i = 1; i <= num; i++) {
tl.to(fStable, 1, {
morphSVG: {
shape: "#f" + i
},
opacity: ((Math.random() * 0.7) + 0.7),
ease: Linear.easeNone
}, "begin+=" + i);
}
More than one way of working
By Blake Bowen
function solve(data) {
var size = data.length;
var last = size - 4;
var path = "M" + [data[0], data[1]];
for (var i = 0; i < size - 2; i +=2) {
var x0 = i ? data[i - 2] : data[0];
var y0 = i ? data[i - 1] : data[1];
var x1 = data[i + 0];
var y1 = data[i + 1];
var x2 = data[i + 2];
var y2 = data[i + 3];
var x3 = i !== last ? data[i + 4] : x2;
var y3 = i !== last ? data[i + 5] : y2;
var cp1x = (-x0 + 6 * x1 + x2) / 6;
var cp1y = (-y0 + 6 * y1 + y2) / 6;
var cp2x = (x1 + 6 * x2 - x3) / 6;
var cp2y = (y1 + 6 * y2 - y3) / 6;
path += "C" + [cp1x, cp1y, cp2x, cp2y, x2, y2];
}
return path;
}
Catmull-Rom Spline
Article about history in computer science.
var poly = document.querySelector("polyline");
var path = document.querySelector("path");
var points = [
100,350,
200,100,
300,350,
400,150,
500,350,
600,200,
700,350
];
poly.setAttribute("points", points);
path.setAttribute("d", solve(points));
var points = [
100,350,
200,150,
300,350,
400,120,
500,350,
600,180,
700,350
];
var points = [
100,350,
200,100,
300,350,
400,150,
500,350,
600,200,
700,350
];
This pen.
Social Coding Sites Help You Learn
Fun. Remember fun?
Codepen
JS Fiddle
Dabblet
-
Questioning the base premises
-
Impose artificial bounds
-
Repurposing
-
Combining
-
Freedom
-
Use open source as a tool
Creativity!
🌋
🌋
Impact
with Val Head
🎉
#CreativeCode
(504) BAYOU-AT
1-5
5 is high
Thank you!
@sarah_edo on twitter