question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Drawing gradients doesn't work

See original GitHub issue

Expected Behaviour

  1. When using createLinearGradient, should work

Actual Behaviour

  1. c.createLinearGradient is not a function

Steps To Reproduce

  1. Copy the code from https://joshmarinacci.github.io/node-pureimage/test-file/specs/gradientfill.test.js.html#lineNumber3
  2. Run

Any Relevant Code Snippets

  var PImage = require('pureimage');
  let image  = PImage.make(20,20)
  let c = image.getContext('2d');
  c.fillStyle = 'black'
  c.fillRect(0,0,200,200)

  const grad = c.createLinearGradient(0,0,20,20)
  grad.addColorStop(0,'white')
  grad.addColorStop(1,'blue')

Platform

OS: Windows 10, Ubuntu 18 Node Version: v10.15.0 NPM Version: 6.13.7 PureImage Version: 0.1.6

Any Additional Info

Its definately in the code base: https://github.com/joshmarinacci/node-pureimage/blob/1d4bdd54e1e4f1b3ed9f94cb90c639bfbe078cd3/src/context.js

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
joshmarinaccicommented, Jun 26, 2022

This should be fixed now with release 0.3.13

0reactions
kfaubelcommented, Sep 13, 2021

I spent some time looking at gradients with stroke() and was able to get it working for what I need.
I can’t say that I understand the code well enough to propose a pull request but my changes are described below.

This did work for strokeRect, lineTo and arc

        // myApp.js - this worked as expected once I made the changes to pureimage that I describe below
	
	const centerX = 200;
	const centerY = 200;
	const sunRadius = 100;
	
	var grad = ctx.createLinearGradient(centerX + sunRadius, centerY, centerX, centerY + sunRadius);
	grad.addColorStop(0, "#00ff00");
	grad.addColorStop(1, "#0000ff");
	ctx.strokeStyle = grad;
	ctx.lineWidth = 10;

	ctx.beginPath();
	ctx.moveTo(centerX + sunRadius, centerY);
	ctx.lineTo(centerX, centerY + sunRadius);
	ctx.stroke();
	
	ctx.beginPath();
	ctx.arc(centerX, centerY, sunRadius, 0, 0.5 * Math.PI);
	ctx.stroke();

These are the changes that worked for me:

	// in context.js:
	// Make calculateRGBA_stroke() like calculateRGBA()
        calculateRGBA_stroke(x,y) {
		if(this._strokeColor instanceof CanvasGradient) {  // new
			return this._strokeColor.colorAt(x,y)      // new
		}                                                  // new
		return this._strokeColor;                          
	}
	
	// in context.js:
	// modify fill_aa() to support gradients
	// I am not familiar with how anti-aliasing is done here so I am not sure if this is 100% correct.
	for(let ii=start; ii<=end; ii++) {
		if(ii === start) {
			//first
			// const int = or(rgb,(1-fstartf)*alpha);
			const newRgb = this.calculateRGBA(ii, j);  // new
			const int = or(newRgb,(1-fstartf)*alpha);  // new
			this.fillPixelWithColor(ii,j, int);
			continue;
		}
		if(ii === end) {
			//last
			// const int = or(rgb,fendf*alpha);
			const newRgb = this.calculateRGBA(ii, j);  // new
			const int = or(newRgb,fendf*alpha);        // new
			this.fillPixelWithColor(ii,j, int);
			continue;
		}
		//console.log("filling",ii,j);
		// this.fillPixelWithColor(ii,j, rgb);
		const newRgb = this.calculateRGBA(ii, j);      // new
		this.fillPixelWithColor(ii,j, newRgb);         // new
	}
	
	// in context.js:
	// Save the gradient when one is set
	// Put the gradient into this._strokeStyle_text since this is read in stroke()
	set strokeStyle (val) {
		// this._strokeColor = Context.colorStringToUint32(val);
		// this._strokeStyle_text = val;
		if(val instanceof CanvasGradient) {                           // new
			this._strokeColor = val;                              // new
			this._strokeStyle_text = val;                         // new - stroke() needs this
		} else {                                                      // new
			this._strokeColor = Context.colorStringToUint32(val); // new
			this._strokeStyle_text = val;                         // new
		}                                                             // new
	};
	
	// in context.js:
	// Use calculateRGBA_stroke which is gradient aware
	strokeRect(x,y,w,h) { 
		// for(let i=x; i<x+w; i++) {
		//     this.bitmap.setPixelRGBA(i, y, this._strokeColor);
		//     this.bitmap.setPixelRGBA(i, y+h, this._strokeColor);
		// }
		// for(let j=y; j<y+h; j++) {
		//     this.bitmap.setPixelRGBA(x, j, this._strokeColor);
		//     this.bitmap.setPixelRGBA(x+w, j, this._strokeColor);
		// }
		for(let i=x; i<x+w; i++) {                                                    // new
			this.bitmap.setPixelRGBA(i, y, this.calculateRGBA_stroke(i,y));       // new
			this.bitmap.setPixelRGBA(i, y+h, this.calculateRGBA_stroke(i,y+y));   // new
		}                                                                             // new
		for(let j=y; j<y+h; j++) {                                                    // new
			this.bitmap.setPixelRGBA(x, j, this.calculateRGBA_stroke(x,j));       // new
			this.bitmap.setPixelRGBA(x+w, j, this.calculateRGBA_stroke(x+w,y));   // new
		}                                                                             // new
	}
	
	// I think strokePixel() and strokeText() are OK with the other changes.
	
	// in util.js:
	// remove the references to unit32 since 'toUint32', 'shiftLeft' and 'or' are imported specifically
	const colorStringToUint32 = function(str) {
        if(!str) return 0x000000;
        //hex values always get 255 for the alpha channel
        if(str.indexOf('#')===0) {
            // let int = uint32.toUint32(parseInt(str.substring(1),16));
            // int = uint32.shiftLeft(int,8);
            // int = uint32.or(int,0xff);
            let int = toUint32(parseInt(str.substring(1),16));  // new
            int = shiftLeft(int,8);                             // new
            int = or(int,0xff);                                 // new
            return int;
        }
Read more comments on GitHub >

github_iconTop Results From Across the Web

Solved: illustrator gradient tool not working? - 8570511
Fill the shape with a gradient first, then use the tool. ... I select the gradient (not the tool) and the color doesn't...
Read more >
Gradient tool in Adobe Illustrator not working - YouTube
Update: I figured it out, the circle shape was (for some reason) having issues (even after "expanding" or making it a compound shape),...
Read more >
NEED HELP!! Have a problem with gradients. - Inkscape
But my gradients don't work. I was drawing a white button, but when I use a gradients, it all turn to black!! Does...
Read more >
How To Draw Gradients With The Gradient Tool In Photoshop
Drawing A Gradient With The Gradient Tool​​ Simply click in your document to set a starting point for the gradient, then keep your...
Read more >
Gradient tool issues - Illustrator UserVoice
Gradient tool doesn't work when applying the same gradient across multiple objects. If you try to adjust the gradient it will simply just ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found