happy

Can happiness be simulated? What is the difference between real happiness and simulated happiness?

by Andrew Maxwell

HTML

<body style="margin:0;overflow:hidden"><p style="margin:50px">What's the difference between real happiness and simulated happiness?</p><canvas id="C" style="position:absolute;top:0;left:0"></canvas></body>

JavaScript

var W = C.width = innerWidth
var H = C.height = innerHeight
var T = C.getContext('2d')

function Gradient(colors){
	this.colors = colors
}
Gradient.prototype.getColor = function(val){
	val *= this.colors.length - 1
	var c1 = this.colors[Math.floor(val)]
	var c2 = this.colors[Math.ceil(val)]
	var ratio = val % 1
	var r = Math.round(c1[0] * (1 - ratio) + c2[0] * ratio)
	var g = Math.round(c1[1] * (1 - ratio) + c2[1] * ratio)
	var b = Math.round(c1[2] * (1 - ratio) + c2[2] * ratio)
	return "rgb(" + r + "," + g + "," + b + ")"
}

var pet = {
    x: W / 2,
    y: H / 2,
    speed: 0.05,
    happy: 0.5,
    rad: 30,
    iterate: function(){
        if (mouse.x){
            var dx = mouse.x - this.x
            var dy = mouse.y - this.y
            
            this.x += dx * this.speed * this.happy
            this.y += dy * this.speed * this.happy
            
            if (dx * dx + dy * dy < this.rad * this.rad){
                this.happy += (1 - this.happy) * 0.05
            } else {
                this.happy -= (1.01 - this.happy) * 0.01
            }
            
            this.happy = Math.min(1, Math.max(0, this.happy))
        }
    }
}
var colors = new Gradient([
	[120,120,120], // gray
	[255,255,0] // green
])
var mouse = {}

function loop(){
	
    requestAnimationFrame(loop)
    
	T.clearRect(0, 0, W, H)
	T.save()
	T.translate(pet.x, pet.y)
	T.scale(pet.rad, pet.rad)

	T.fillStyle = colors.getColor(pet.happy)
	T.lineWidth = 2 / pet.rad
	T.beginPath()

	T.arc(0, 0, 1, 0, 2 * Math.PI)
	T.fill()

	var eyeHalfDist = 0.5
	var eyeMiddleY = (pet.happy * 2 - 1) * -0.1
	var eyeHalfWidth = 0.15

	T.save()
	T.translate(-eyeHalfDist, 0)
	T.moveTo(-eyeHalfWidth, 0)
	T.quadraticCurveTo(0, eyeMiddleY, eyeHalfWidth, 0)
	T.restore()

	T.save()
	T.translate(eyeHalfDist, 0)
	T.moveTo(-eyeHalfWidth, 0)
	T.quadraticCurveTo(0, eyeMiddleY, eyeHalfWidth, 0)
	T.restore()

	var mouthEdgeY = 0.6 - 0.3 * pet.happy

	T.moveTo(-0.5, mouthEdgeY)
	T.quadraticCurveTo(0, pet.happy *...