Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 12.08.2018, 22:30
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Arhitector,
Canvas globalCompositeOperation
http://minimal.be/lab/jQuery.eraser/
https://pixijs.io/examples/#/demos/m...der-texture.js

Последний раз редактировалось рони, 12.08.2018 в 22:48.
Ответить с цитированием
  #12 (permalink)  
Старый 13.08.2018, 09:39
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

Arhitector,
Просто непересекаемых дырок с небольшим сглаживанием по краю наделать можно так:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

<canvas id="canvas" width="400" height="250" style="border: 1px solid red"></canvas>

<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

class Light1 {
    constructor(x, y, radius) {
        this.x = x;
        this.y = y;
        this.radius = radius;
    }
}
class Dark1 {
    constructor(width, height) {
        this.width = width;
        this.height = height;
        this.lights = [];
    }
    draw(ctx) {
        ctx.save();
        ctx.beginPath();
        ctx.rect(0, 0, this.width, this.height);
        for (let light of this.lights) {
            ctx.moveTo(light.x, light.y);
            ctx.arc(light.x, light.y, light.radius, 0, 6.3);
        }
        ctx.shadowColor = 'rgba(0, 0, 0, 1)';
        ctx.shadowBlur = 20;
        ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
        ctx.fill('evenodd');
        ctx.restore();
    }
}

let dark1 = new Dark1(400, 250);
dark1.lights.push(new Light1(50, 50, 30));
dark1.lights.push(new Light1(150, 100, 50));
dark1.lights.push(new Light1(100, 160, 70));
dark1.lights.push(new Light1(300, 150, 100));

let img = new Image;
img.onload = function() {
    ctx.drawImage(img, 660, 290, 400, 250, 0, 0, 400, 250);
    dark1.draw(ctx);
};
img.src = 'https://javascript.ru/forum/attachments/misc/3976d1534094922-igra-na-js-ehffekt-nochi-game-3-jpg';
</script>
    
</body>
</html>

А так уже с градиентом наверное то что и нужно:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

<canvas id="canvas" width="400" height="250" style="border: 1px solid red"></canvas>

<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

class Light2 {
    constructor(x, y, power, degree0 = 0, degree1 = 360) {
        this.x = x;
        this.y = y;
        this.radius0 = power * 50;
        this.radius1 = power * 100;
        let degree = Math.PI / 180;
        this.angle0 = degree0 * degree;
        this.angle1 = degree1 * degree;
    }
}
class Dark2 {
    constructor(width, height) {
        let offscreen = document.createElement('canvas');
        this.ctx = offscreen.getContext('2d');
        this.width = offscreen.width = width;
        this.height = offscreen.height = height;
        this.lights = [];
    }
    draw(ctx) {
        this.ctx.clearRect(0, 0, this.width, this.height);
        this.ctx.globalCompositeOperation = 'source-over';
        this.ctx.fillStyle = 'rgba(0, 0, 0, 0.75)';
        this.ctx.fillRect(0, 0, this.width, this.height);
        this.ctx.globalCompositeOperation = 'destination-out';
        for (let light of this.lights) {
            this.ctx.moveTo(light.x, light.y);
            this.ctx.arc(light.x, light.y, light.radius1, light.angle0, light.angle1);
            let grd = this.ctx.createRadialGradient(light.x, light.y, light.radius0, light.x, light.y, light.radius1);
            grd.addColorStop(1, 'rgba(0, 0, 0, 0)');
            grd.addColorStop(0, 'rgba(0, 0, 0, 0.75)');
            this.ctx.fillStyle = grd;
            this.ctx.fill();
        }
        ctx.drawImage(this.ctx.canvas, 0, 0);
    }
}

let dark2 = new Dark2(400, 250);
dark2.lights.push(new Light2(50, 50, 0.3));
dark2.lights.push(new Light2(150, 100, 0.5));
dark2.lights.push(new Light2(100, 160, 0.7));
dark2.lights.push(new Light2(300, 150, 1, -150, -10));

let img = new Image;
img.onload = function() {
    ctx.drawImage(img, 660, 290, 400, 250, 0, 0, 400, 250);
    dark2.draw(ctx);
};
img.src = 'https://javascript.ru/forum/attachments/misc/3976d1534094922-igra-na-js-ehffekt-nochi-game-3-jpg';
</script>
    
</body>
</html>

Формула радиуса освещения от мощности (или что там у света?) взята от балды.

Последний раз редактировалось Rise, 13.08.2018 в 10:17. Причина: Добавил градусы в свет
Ответить с цитированием
  #13 (permalink)  
Старый 13.08.2018, 15:17
Интересующийся
Отправить личное сообщение для Arhitector Посмотреть профиль Найти все сообщения от Arhitector
 
Регистрация: 12.08.2018
Сообщений: 18

Rise,
Вот это уже почти идеально подходит! Огромное спасибо
Ответить с цитированием
  #14 (permalink)  
Старый 14.08.2018, 09:11
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

Теперь свет можно отдельно использовать:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>

<canvas id="canvas" width="400" height="250" style="border: 1px solid red"></canvas>

<script>
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

class Light {
    constructor(x, y, power, degree0 = 0, degree1 = 360, color0 = 'rgba(255,255,255,0.75)', color1 = 'rgba(255,255,255,0)') {
        this.x = x;
        this.y = y;
        this.radius0 = power * 50;
        this.radius1 = power * 100;
        let degree = Math.PI / 180;
        this.angle0 = degree0 * degree;
        this.angle1 = degree1 * degree;
        this.color0 = color0;
        this.color1 = color1;
    }
    draw(ctx) {
        ctx.beginPath();
        ctx.moveTo(this.x, this.y);
        ctx.arc(this.x, this.y, this.radius1, this.angle0, this.angle1);
        let grd = ctx.createRadialGradient(this.x, this.y, this.radius0, this.x, this.y, this.radius1);
        grd.addColorStop(0, this.color0);
        grd.addColorStop(1, this.color1);
        ctx.fillStyle = grd;
        ctx.fill();
    }
}
class Dark {
    constructor(width, height, color = 'rgba(0,0,0,0.75)') {
        let offscreen = document.createElement('canvas');
        this.ctx = offscreen.getContext('2d');
        this.width = offscreen.width = width;
        this.height = offscreen.height = height;
        this.lights = [];
        this.color = color;
    }
    draw(ctx) {
        this.ctx.clearRect(0, 0, this.width, this.height);
        this.ctx.globalCompositeOperation = 'source-over';
        this.ctx.fillStyle = this.color;
        this.ctx.fillRect(0, 0, this.width, this.height);
        this.ctx.globalCompositeOperation = 'destination-out';
        for (let light of this.lights) light.draw(this.ctx);
        ctx.drawImage(this.ctx.canvas, 0, 0);
    }
}

let dark = new Dark(100, 250);
dark.lights.push(new Light(50, 50, 0.3));
dark.lights.push(new Light(100, 160, 0.7, 90, 270));
let light = new Light(100, 160, 0.7, -90, 90);
let sun = new Light(350, 50, 0.5, 0, 360, 'rgba(255, 255, 0, 1)', 'rgba(255, 0, 0, 0.1)');

let img = new Image;
img.onload = function() {
    ctx.drawImage(img, 660, 290, 400, 250, 0, 0, 400, 250);
    dark.draw(ctx);
    light.draw(ctx);
    sun.draw(ctx);
};
img.src = 'https://javascript.ru/forum/attachments/misc/3976d1534094922-igra-na-js-ehffekt-nochi-game-3-jpg';
</script>
    
</body>
</html>
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
BackEnd/FrontEnd Developer (Native JS) Abab Работа 0 25.12.2016 10:56
js стиль render для react.js vflash Ваши сайты и скрипты 5 01.04.2016 22:57
Вакансия JavaScript разработчик / JS / Frontend developer (Санкт-Петербург) Сергей Грачёв Работа 0 21.09.2015 12:31
Картинка обрабатывается js 4yBaK Общие вопросы Javascript 10 11.09.2011 09:28
Игра на JS. Косяк с массивом treno1 Общие вопросы Javascript 0 08.06.2011 17:13