How can I draw text that looks embossed using Kinetic JS and canvas?

偶尔善良 提交于 2020-06-29 09:41:46

问题


Update - Here is my final jsfiddle working version using Kinetic.

I'm trying to show text with two different shadows to create an "embossed" look. I'm using this jsfiddle as a model of the result I'd like to get which uses CSS.

Here is the jsfiddle of what I'm working on currently with Kinetic JS.

var stage = new Kinetic.Stage({
  container: 'stage-container',
  width: 400,
  height: 200
});

var layer = new Kinetic.Layer();
stage.add(layer);

var darkShadow = new Kinetic.Text({
        text: 'Hello',
    x: 140,
    y: 80,
    fill: '#000000',
    fontSize: 60,
    opacity: 0.8,
    filter: Kinetic.Filters.Blur,
    filterRadius: 1
});                         

layer.add(darkShadow);

var lightShadow = new Kinetic.Text({
        text: 'Hello',
    x: 136,
    y: 76,
    fill: '#FFFFFF',
    fontSize: 60,
    opacity: 0.3,
    filter: Kinetic.Filters.Blur,
    filterRadius: 1
});                         

layer.add(lightShadow);

var mainText = new Kinetic.Text({
        text: 'Hello',
    x: 138,
    y: 78,
    fill: '#FFFFFF',
    fontSize: 60,
    opacity: 0.8
});                         

layer.add(mainText);

layer.draw();

I am currently drawing the text 3 times and just offsetting them to get each shadow and then the main text. My issue is that the main text needs to have opacity to bring forth the background color. Here are a few screenshots to see what I'm up against.

Just the shadows...

With all 3 text objects...

My next thought was to create a clipping mask of the main text to subtract that out of the two shadows, then draw the main text with opacity to bring forth the background color. But I'm not exactly sure how to do that or if there's a better way.


回答1:


Compositing

Use "destination-out" to remove pixels.

If I knew how to use kineticjs I would say just set the layer composite operation for the last text layer to "destination-out" and that will remove the pixels.

But too much work to sift their documentation so here is the same thing without any frameworks.

// constants
const text = "Compositing";
const blur = 2;
const highLight = "rgba(100,190,256,0.75)";
const shadow = "rgba(0,0,0,0.65)";
const font = "84px arial black";
const background = "linear-gradient(to right,  #1e5799 0%,#3096e5 100%)";
const border = "2px solid #6CF"

// create canvas add styles and put on page
const canvas = document.createElement("canvas");
const w = (canvas.width = innerWidth - 24) / 2;  // set size and get centers
const h = (canvas.height = innerHeight - 24) / 2;
canvas.style.background = background;
canvas.style.border = border;
const ctx = canvas.getContext("2d");
document.body.appendChild(canvas);

// set up font and font rendering alignment
ctx.font = font;            
ctx.textAlign = "center";
ctx.textBaseline = "middle";

// draw dark shadow
ctx.shadowBlur = blur; // shadow
ctx.fillStyle = ctx.shadowColor = shadow;
ctx.shadowOffsetY = ctx.shadowOffsetX = blur;
ctx.fillText(text, w, h);

// draw highLight
ctx.fillStyle = ctx.shadowColor = highLight;
ctx.shadowOffsetY = ctx.shadowOffsetX = -blur;
ctx.fillText(text,  w, h);

// draw center text that removes pixels
ctx.shadowColor = "rgba(0,0,0,0.0)";               // turn off shadow
ctx.fillStyle = "black";
ctx.globalCompositeOperation = "destination-out"; // New pixels will remove old pixels making them transparent
ctx.fillText(text,  w, h);
ctx.globalCompositeOperation = "source-over";     // restore default composite operation.


来源:https://stackoverflow.com/questions/43242709/how-can-i-draw-text-that-looks-embossed-using-kinetic-js-and-canvas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!