canvas实现多种树叶铺满屏幕效果代码
代码语言:html
所属分类:其他
代码描述:canvas实现多种树叶铺满屏幕效果代码,点击切换效果。
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <style> body { height: 100vh; width: 100vw; overflow:hidden; } canvas { height: 100vh; width: 100vw; } </style> </head> <body> <canvas id="canvas"></canvas> <script> (function () { //fields var canvas = document.getElementById("canvas"); var body = document.getElementsByTagName("body")[0]; var positions = [] var ctx = canvas.getContext("2d"); /*Initialize flowers*/ body.addEventListener("click",function(ev){ drawFlowers(false) }) window.onload = ()=>{drawFlowers(true)} window.onresize = ()=>{drawFlowers(false)} /*Flower flunctions*/ function Flower(opt) { this.r = opt.allowLarge && chance(.05) ? getRandomInt(50,150) : getRandomInt(20,50) this.x = getRandomInt(0, canvas.width) this.y = getRandomInt(0, canvas.height) this.lw = 4; this.angle = getRandomInt(-30,30) this.rad = this.angle * (Math.PI / 180) /*FLOWER ROTATION*/ this.opacity = 1; this.petals = chance(.03) ? 4 : 3; this.shiftOut = this.petals == 4 ? 0 : 0 this.petalBase = 0; this.petalSpread1 = getRandomFloat(opt.minSpread, opt.maxSpread) this.petalLength1 = this.petalSpread1 * getRandomFloat(1.4, 1.8) /*length 1.5 longer than spread*/ this.petalSpread2 = getRandomFloat(this.petalSpread1+.15,this.petalSpread1-.15); this.petalLength2 = this.petalLength1 this.leafRotation = Math.floor(360/this.petals)/*PETAL ROTATION*/ this.color1 = vary(opt.color1, opt.colorVariance) } function drawFlowers(firstTime) { scaleCanvas() ctx.clearRect(0, 0, canvas.width, canvas.height) positions = []; //drawing options var opt = { spaceAround:chance(), allowLarge:chance(0), padding:getRandomFloat(.5,3), /*multiplier*/ color1:pick(greens), stems: chance(.7), stemLength : getRandomInt(20,(chance(.2)?150:60)), /*multiplier*/ stemWidth:getRandomInt(2,5), /*multiplier*/ colorVariance:getRandomInt(10,20), minSpread:getRandomFloat(.4,.7), maxSpread:getRandomFloat(.4,1.2), fieldEffect:firstTime || chance(.33), randomY:chance() } opt.stemsFirst = opt.fieldEffect || chance() canvas.style.transform = "rotate(0deg)" if(opt.fieldEffect){ opt.stemLength *= getRandomInt(4,12) opt.stems = true opt.spaceAround = false if(chance(.1)) canvas.style.transform = "rotate(180deg)" } opt.isDark = opt.color1.l<50 console.log(opt.color1.name) let bg = new Color(pick(greens)) if(chance(.2)) bg.h = getRandomInt(0,359) bg.l = bg.l>50? bg.l+15: bg.l-15; canvas.style.backgroundColor = bg.hsl() let screenSize = Math.min(window.innerWidth, window.innerHeight) let numFlower = opt.fieldEffect?getRandomInt(500,1000):getRandomInt(50,screenSize>1000?3000:1500) let flowers = [] let baseHeightRandom = getRandomInt(window.innerHeight-300,window.innerHeight) for(let i=0; i<numFlower; i++){ let f = new Flower(opt) if(opt.fieldEffect) { let yPos = getRandomInt(-150,150)+(opt.randomY?getRandomInt(window.innerHeight/2.25,window.innerHeight):baseHeightRandom); f.y = yPos } flowers.push(f) } /*sort functions*/ function hueSort(a,b) { let greenDistance1 = Math.abs(120-a.color1.h) let greenDistance2 = Math.abs(120-b.color1.h) return (greenDistance1>greenDistance2?-1:1) } function lightSort(a,b){ return a.color1.l>b.color1.l?(opt.isDark?1:-1):(opt.isDark?-1:1) } let filter = pick([hueSort,lightSort]) console.log("filter is:"+filter, ",isDark:\n"+opt.isDark) flowers.sort(filter) //draw stems first then layer on flower part. for(let i=0; i<numFlower; i++){ let previous = flowers.slice(0,i) let f = flowers[i]; if(opt.spaceAround&&previous.some(function(pos) { let d = distance(new Point(f.x,f.y), new Point(pos.x,pos.y)) return d<f.r*opt.padding; })) { f.hide = true; } else { if(opt.stems && opt.stemsFirst) drawStem(f,opt) } } for(let i=0; i<numFlower; i++){ if(opt.stems && !opt.stemsFirst) drawStem(flowers[i],opt) drawFlower(flowers[i],opt) } } function drawStem(f, opt){ if(f.hide) { return false; } ctx.translate(f.x, f.y); let angle = getRandomInt(-20,20)*(Math.PI/180) ctx.rotate(angle); ctx.translate(-f.x, -f.y); ctx.fillStyle = f.color1.hsl() ctx.strokeStyle = ctx.fillStyle; ctx.beginPath() ctx.lineWidth = f.petalSpread1*opt.stemWidth; let stemLength = f.petalSpread1*getRandomFloat(opt.stemLength-2, opt.stemLength+2) ctx.moveTo(f.x,f.y) let curve = getRandomInt(5,20) if(chance()) curve *= -1 //each petal is two curves ctx.quadraticCurveTo(f.x+curve, f.y+(stemLength/2), f.x, f.y+stemLength); ctx.moveTo(f.x,f.y) ctx.quadraticCurveTo(f.x+curve, f.y+(stemLength/2), f.x+1, f.y+stemLength); ctx.save() ctx.setTransform(0, .1, 0, 0, 0, 0) ctx.restore() ctx.stroke() ctx.translate(f.x, f.y); ctx.rotate(-angle); ctx.translate(-f.x, -f.y); ctx.closePath() ctx.restore() } function drawFlower(f,opt) { if(f.hide) { return false; } positions.push(new Point(f.x, f.y)) ctx.save(); ctx.globalAlpha = f.opacity ctx.lineWidth = f.lw; ctx.translate(f.x, f.y); ctx.rotate(f.rad); ctx.translate(-f.x, -f.y); ctx.fillStyle = f.color1.hsl() let lineColor = new Color(f.color1) lineColor.l += getRandomInt(-10,10) //PETALS for (let i = 0; i < f.petals; i++) { ctx.translate(f.x, f.y); ctx.rotate(f.leafRotation * (Math.PI / 180)); ctx.translate(-f.x, -f.y); ctx.beginPath(); ctx.moveTo(f.x, f.y-f.shiftOut); ctx.fillStyle = f.color1.hsl() let sp1 = f.r*f.petalSpread1 let len1 = f.r*f.petalLength1 let sp2 = f.r*f.petalSpread2 let len2 = f.r*f.petalLength2 let endX = f.petalBase let endY = f.shiftOut let angle = getRandomInt(15,50) * (Math.PI / 180) //LEAF for (let j = 0; j < 2; j++) { //'heart' shaped petals via two bezier curves ctx.translate(f.x, f.y) ctx.rotate(j*angle); ctx.translate(-f.x, -f.y) ctx.bezierCurveTo(f.x-sp1,/*control point #1 'upper left'*/ f.y-len1, f.x+sp2,/*control point #2 'upper right'*/ f.y-len2, f.x+endX,/*ending point*/ .........完整代码请登录后点击上方下载按钮下载查看
网友评论0