Страницы

Поиск по вопросам

Показаны сообщения с ярлыком path. Показать все сообщения
Показаны сообщения с ярлыком path. Показать все сообщения

четверг, 2 апреля 2020 г.

Create and used StaticResource Path in XAML code

#wpf #xaml #path #content

                    
Доброго времени суток.

Как можно заставить работать следующий код в XAML






Также, я пробовал так:






Но похоже это не работает
    


Ответы

Ответ 1



Все просто, нужно задать шаблон ContentTemplate:

понедельник, 24 февраля 2020 г.

Растровая картинка как фон для path в SVG

#изображения #svg #png #path


Есть задача установить значение .test {fill: url(image.png)} для 

Гугл уже кипит от моих запросов по этой теме. Пробовал и clippath и mask но почему
то не выходит. Подскажите, что не так делаю или как решить данную задачу?
    


Ответы

Ответ 1



Пробовал и clippath и mask но почему то не выходит. Подскажите что не так делаю или как решить данную задачу? clipPath Представьте, что у вас есть лист с картинкой, вы накладываете на неё шаблон и вырезаете ножом по шаблону. Всё лишнее отбрасываете и используете только вырезанную часть картинки. Вот так работает clippath. В качестве шаблона выступает фигура SVG Далее вы указываете ссылку на изображение из которого вырезаете фигуру. Обратите внимание, что тег SVG используется здесь, как свойство CSS clip-path="url(#clip-ff)"
UPD 26.11.2017 Пример SVG clipPath для оформления шапки сайта .banner_1 { min-height: 100px; background-color: #41dddb; } .banner_2 { background:url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/4273/hawaii-beach.jpg); background-size:cover; } mask Принцип действия здесь другой в отличии от clipPath. Маска это трафарет сквозь который вы смотрите на рисунок, то. что вы видите сквозь трафарет, будет выведено на экран. В качестве трафарета может выступать любая фигура svg: rect, polygon, polyline, circle, ellipse, pathили их совместная комбинация. маску до её применения обязательно прячут в секции Ниже код, использования маски:
Обратите внимание, что обязательно нужно задать цвет заполнения маски: style="fill:white;stroke-width:1;stroke:white" Белый цвет - полная прозрачность, чёрный -маска непрозрачна. Другие цвета заполнения маски будут работать, как свойство opacity. Например: серый цвет - даёт полупрозрачность. Комбинированная маска Состоит из двух фигур SVG: прямоугольника (rect), у которого цвет заполнения отличается от white и black и поэтому мы получаем полупрозрачную область фона. path - шестиугольник с белым цветом заполнения - полностью прозрачная область. Обводка (stroke) шестиугольника оттенок серого.
Более подробно, с примерами, - Практические примеры применения масок svg

Ответ 2



Пожалуй только через defs и инлайново:

суббота, 11 января 2020 г.

Передвижение по svg (path)

#javascript #css #canvas #svg #path


Как организовать движение картинок по path друг за другом, как угодно, только не
друг на друге (задать координаты в цикле не получилось, где-то ошибаюсь..). Фрагмент кода:



var canvas = document.getElementById('canvas');
         var context = canvas.getContext('2d');
    
        var W = window.innerWidth,
            H = window.innerHeight;
        canvas.width  = W;
        canvas.height = H;
    
        var angle = 0;
       
        var currentAngle = 0;
        var TO_RADIANS = Math.PI / 180;
        var particles = [];
        
    
        var counter = 0;
        var svg = document.getElementById("k9");//path из svg
        var straightLength = svg.getTotalLength();
    
        function Particle() {
    
        this.radius = 20;
    
           this.x = svg.getPointAtLength(straightLength).x;
           this.y = svg.getPointAtLength(straightLength).y;
    
        this.move = function() {
    
          for ( var g = 0; g < particles.length; g++){
    
            this.x = svg.getPointAtLength(counter*straightLength).x;
            this.y = svg.getPointAtLength(counter*straightLength).y;
    
        }
    counter+=0.0003;//так картинки передвигаются по path друг на друге, как организовать
нечто вроде "паровозика"? Перебрал много вариантов в цикле, но ничего не вышло..


        context.beginPath();
        context.globalCompositeOperation = "source-over";

        context.save();
        context.translate(this.x, this.y);
        context.rotate(Gangle * TO_RADIANS);
        var image = new Image();
        image.src = 'img/bag.png';
        context.drawImage(image,20, -20, 40, 40);
        context.restore();
        angle+=0.1;


    }
    };


    for (var i = 0; i < 10; i++) {
      var particle = new Particle();
        particles.push(particle);
    }

    function animate() {
      context.clearRect(0, 0, canvas.width, canvas.height);
      for (var i = 0; i < particles.length; i++) {
        particles[i].move();

    }
      requestAnimFrame(animate);
    }
    animate();



    


Ответы

Ответ 1



Как организовать движение картинок по path друг за другом Для решения этой задачи необходимо нарисовать path в векторном редакторе или вручную. Движение вдоль этого пути реализуется командой С привязкой объектов движения к пути посредством ID этого пути с помощью команды Фрагмент кода: ` ` Начало движения при наведении на кнопку "Start" begin="startButton.mouseover" Окончание анимации при наведении на кнопку "Stop" end="stopGreen.mouseover" Далее добавляются еще два подобных блока кода для двух других объектов движения. Для реализации движения друг за другом нескольких объектов, задается пауза до начала анимации для второго и третьего шарика. begin="startButton.mouseover+0.25s" Необязательные украшательства: Добавлены маркеры для указания направления движения, паттерн фона и блок радиокнопок остановки объектов движения. Ниже пример кода: Start Stop Анимация адаптивна, пробуйте изменять размер окна браузера. Вариант #2 Объекты движения заменены на более сложные (ведьмы на метлах) Изменена траектория движения (заменяем патч Start Stop Начало анимации при наведении на кнопку "Start" Приостановка объектов анимации при наведении на соответствующую радиокнопку.

Программа не видит путь к файлу C:\Windows\ System32\nslookup.exe

#c_sharp #windows #файлы #path


Программа не видит путь к файлу C:\Windows\System32\nslookup.exe
Проверка естественно всегда выдает "Путь не найден". То же самое происходит и например
с путем к фалу notepad.exe в этой же папке, но при этом если обратиться к файлу C:\Windows\twin_32.dll
то программа его находит.
Подскажите куда копать? Нужно назначить текущего пользователя владельцем папки System32?

if (File.Exists(@"C:\Windows\System32\nslookup.exe"))
{
Console.WriteLine("Путь найден");
}
else Console.WriteLine("Путь не найден");

    


Ответы

Ответ 1



Дело в File System Redirector'е (https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx) Если кратко, %windir%\System32 - для 64-битных приложений. 32-битные приложения система перенаправляет в %windir%\SysWOW64 где вашего файла вполне может и не быть.

Ответ 2



Используйте путь из переменных окружения if (File.Exists(Path.Combine(Environment.SystemDirectory, "nslookup.exe"))) { Console.WriteLine("Путь найден"); } else Console.WriteLine("Путь не найден");

четверг, 2 января 2020 г.

Python есть в PATH но не запускается из cmd

#python #windows_10 #path


Установил Python для Visual Studio 2019. Хочу также работать с ним из cmd. Добавил
путь к папке, содержащей python.exe в переменную Path. Однако при перезапуске cmd и
введении python снова появляется приглашение ко вводу, а Windows запускает свой магазин
приложений и предлагает скачать Python.

Работаю на Windows 10 Pro.
    


Ответы

Ответ 1



В новой версии Windows 10 (1903) в папку %USERPROFILE%\AppData\Local\Microsoft\WindowsApps разработчики поместили заглушки python.exe, python3.exe и т.д. При обращении к этим заглушкам открывается магазин Microsoft Store. Путь к этой папке прописан почти в самом начале переменной PATH пользователя и добавляется к системному PATH. Если добавить новый путь к файлу python.exe в системный PATH то это поможет решить проблему, хотя могут возникнуть сложности при смене пользователя, когда установка была произведена в локальную папку. В этом случае предпочтительно поместить новый путь в начало пользовательского PATH, а не в конец, как часто происходит. PS. Кардинальный способ решить эту проблему: Параметры > Приложения и возможности > Псевдонимы выполнения приложения > отключить все опции.

Ответ 2



Вопрос решился. Вот в чём была проблема: я недавно перешёл на Windows 10 c 7ой и потому не знал, что там есть два разных Path – системный и пользовательский. Нетрудно догадаться, что путь к Python я добавил как раз в пользовательский, а не в системный, окно для редактирования которого, к слову, находится чуть ниже. После добавления пути в тот Path, который находится в списке системных переменных среды, всё заработало.

вторник, 31 декабря 2019 г.

Как добавить путь в переменную окружения %PATH% на Windows?

#windows #path


Как добавить что-то в путь (PATH или system PATH)? Что такое %PATH% и %что-то%?

Вот примеры:


  
  Add the following string to the PATH, C:\Program Files (x86)\CMake
  2.8\bin.
  Do you have make in your %PATH% environment variable? On my system, I need to add
%MINGW_DIR%\bin to %PATH%.
  Add C:/mingw/bin to the system PATH.
  


Я так понимаю, что надо зайти в Свойства системы → Дополнительно → Переменные среды...

А потом, если говориться про PATH, то добавить в «Переменные среды пользователя такого-то»,
а если system PATH, то «Системные переменные».

Потом нужно нажать «Создать». Что вписывать в «Имя переменной»? В значение переменной
надо записать те строки, которые даны в указании, так?

Qt\_\_directory — это, наверно, путь до папки с Qt. Между двумя % тоже путь до папки?
%PATH% и %MINGW_DIR% — это одно и тоже, если PATH понимают как путь к MinGW?
    


Ответы

Ответ 1



Да, верно, нужно зайти в Свойства системы → Дополнительно → Переменные среды. Там уже будут переменные PATH. Одна для текущего пользователя, вторая — общесистемная. Просто кликаете на них и добавляете нужный путь через точку с запятой. Как вариант, можно написать командный скрипт, в котором будет изменяться переменная окружения. При этом она может менять глобально для всей системы, текущей сессии, так и внутри конкретно той командной оболочки, в которой этот командный скрипт запущен. Смотрите детали в статье «Update Windows Path Environment Variable»[архив].

вторник, 24 декабря 2019 г.

Каким образом можно реализовать бегущую подсветку (выделение) многострочного текста?

#c_sharp #wpf #path


Здесь уже был вопрос про закраску текста и на него был дан  ответ.

Вкратце суть решения состоит в создании FormattedText из содержимого скрытого TextBlock,
а затем создается геометрия из FormattedText, которая отображается с помощью Path,
который в свою очередь закрашивается с помощью анимации на нем.

И все прекрасно работает пока текст занимает одну строку, а вот когда строк несколько,
получается не то, что хотелось бы.

 

XAML я повторять не буду, т.к. он полностью совпадает с таковым в выше указанном
ответе. Мой код тоже мало чем отличается, но я его приведу для ясности вопроса.

private List _RectsForFill;   // прямоугольники с каждым символом
private double _LengthFillText;      // общая ширина рисованного текста

//анимация
Storyboard _Storyboard;
DoubleAnimation _FromAnimation;
DoubleAnimation _ToAnimation;

private void CreateFillText()
{
    //получаем текстовое содержимое
    TextBlock tb = this.textBlockHidden;
    var text = tb.Text;

    //создаем экземпляр форматированного текста
    FormattedText formattedText = new FormattedText(
        text,
        CultureInfo.GetCultureInfo("en-US"),
        FlowDirection.LeftToRight,
        new Typeface(
            tb.FontFamily,
            tb.FontStyle,
            tb.FontWeight,
            tb.FontStretch),
            tb.FontSize,
            Brushes.Black // конкретная кисть нам не важна, мы используем только
геометрию
        );

    //берем переносы строк у эталонного текстблока
    formattedText.MaxTextWidth = this.textBlockHidden.Width;
    formattedText.MaxTextHeight = this.textBlockHidden.Height;

    // стащили геометрию у текста...
    var geo = formattedText.BuildGeometry(new Point());
    // ...и отдали её Path'у
    Target.Data = geo;

    //вычислим прямоугольники для заполнения
    GetRectsForFill(text, formattedText);
}

private void GetRectsForFill(string text, FormattedText formattedText)
{
    var bb = formattedText.BuildHighlightGeometry(new Point());
    _LengthFillText = bb.Bounds.Width; // общая ширина

    //заполняем коллекцию побуквенных боксов
    _RectsForFill = Enumerable.Range(0, text.Length)
                            .Select(k => formattedText.BuildHighlightGeometry(new
Point(), k, 1)
                                                                   .Bounds)
                        .ToList();

    //ссылки на анимацию для дальнейшей работы с ней
    _Storyboard = (Storyboard)Target.Resources["AnimationStoryboard"];
    _FromAnimation = (DoubleAnimation)_Storyboard.Children[0];
    _ToAnimation = (DoubleAnimation)_Storyboard.Children[1];
}


Вот метод, заполняет черным отрисованный текст

/// 
/// Закрашивание рисованного текста
/// 
/// начальная позиция слова
/// число закрашиваемых букв в слове
public void FillTextPath(int startPos, int count)
{
    if (count == 0) throw new ArgumentException(nameof(count));

    //вычисляем индекс необходимого прямоугольника
    int index = startPos + count;
    if (index >= _RectsForFill.Count) index = _RectsForFill.Count - 1;

    //необходимый прямоугольник
    Rect box = _RectsForFill[index];

    //закрашиваем
    _FromAnimation.From = box.Left / _LengthFillText;
    _FromAnimation.To = box.Right / _LengthFillText;
    _ToAnimation.From = box.Left / _LengthFillText;
    _ToAnimation.To = box.Right / _LengthFillText;
    _Storyboard.Begin();
} 

    


Ответы

Ответ 1



Вы пошли правильным путём, разбить на отдельные Path'ы — хорошая идея. Давайте её реализуем до конца. Для начала, функциональность проигрывания уже достаточно сложна, так что вынесем её в отдельный UserControl. Затем, каждый контрол пусть отвечает за одну строку. Чтобы не искать куски по геометрии, просто отрежем эту строку при помощи Clip'а. На вход в UserControl будем подавать результаты разбора текста на геометрию (функцией Create). В code-behind будет анимация: public partial class SingleLine : UserControl { List boundingBoxes; double extent; public SingleLine() { InitializeComponent(); } public SingleLine(Geometry geo, List boundingBoxes, double totalExtent) : this() { Target.Data = geo; extent = totalExtent; Rect clip = boundingBoxes.Aggregate(Rect.Union); Clip = new RectangleGeometry(clip); this.boundingBoxes = boundingBoxes; } public async Task Play() { var storyboard = (Storyboard)Target.Resources["AnimationStoryboard"]; var fromAnimation = (DoubleAnimation)storyboard.Children[0]; var toAnimation = (DoubleAnimation)storyboard.Children[1]; foreach (var b in boundingBoxes) { await Task.Delay(250); // перерыв между буквами fromAnimation.From = b.Left / extent; fromAnimation.To = b.Right / extent; toAnimation.From = b.Left / extent; toAnimation.To = b.Right / extent; storyboard.Begin(); await Task.Delay(250); // дождёмся конца анимации } } } Зачем нам нужна такая сложность с Clip и totalExtent? К сожалению, я не нашёл метода выкусить только нужную часть геометрии. Поэтому мы даём на вход всю геометрию, а хотим показывать только текущую строку. Для этого мы вычисляем прямоугольник, соответствующий нужной части геометрии (текущей строке), и отрезаем отображение остального при помощи Clip'а. Но наши вычисления коэффициентов (b.Left / extent и т. д.) требуют процента от общей ширины Path'а, а не ширины текущей строки! (Напомню, наш Path получает геометрию всей строки, включая остальные строки тоже.) Поэтому приходится передавать ещё и общую ширину. Теперь основной код. Он стал проще, так как часть функциональности отделилась. В нём мы не можем положить один, фиксированный Path, так как у нас количество строк не известно заранее. Поэтому контролы будем добавлять динамически. Главное окно выглядит просто: И code-behind: public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Loaded += (o, args) => Create(); // вначале запустим Create PreviewKeyDown += (o, args) => Play(); // а по нажатию клавиши - Play } // список контролов, отображающих строки List lineControls = new List(); void Create() // https://msdn.microsoft.com/en-us/library/ms745816(v=vs.110).aspx { TextBlock tb = Source; var text = tb.Text; FormattedText formattedText = new FormattedText( text, CultureInfo.GetCultureInfo("en-US"), FlowDirection.LeftToRight, new Typeface( tb.FontFamily, tb.FontStyle, tb.FontWeight, tb.FontStretch), tb.FontSize, Brushes.Black); // установили максимальную ширину, чтобы текст был разбит на части formattedText.MaxTextWidth = Source.ActualWidth; var boundingBoxes = // побуквенная ширина и позиции Enumerable.Range(0, text.Length) .Where(k => !char.IsWhiteSpace(text[k])) .Select(k => formattedText.BuildHighlightGeometry(new Point(), k, 1) .Bounds) .ToList(); // вычисляем охватывающий прямоугольник всех прямоугольников var totalBb = boundingBoxes.Aggregate(Rect.Union); var totalExtent = totalBb.Width; List> boundingBoxesByLine = new List>(); List currentLine = null; double lastRectBottom = double.NegativeInfinity; foreach (var rect in boundingBoxes) { // проверка на новую строку. если верх текущего прямоугольника там же, // где низ предыдущего прямоугольника, или ещё ниже - новая строка, иначе нет if (rect.Top >= lastRectBottom) { // добавим старую строку в список строк if (currentLine != null) boundingBoxesByLine.Add(currentLine); // новый пустой контейнер прямоугольников для новой строки currentLine = new List(); } currentLine.Add(rect); lastRectBottom = rect.Bottom; } if (currentLine != null) // последнюю строку не теряем boundingBoxesByLine.Add(currentLine); // стащили геометрию у текста... var geo = formattedText.BuildGeometry(new Point()); // строим по контролу для каждой строки: foreach (var line in boundingBoxesByLine) { // ... отдавая ему геометрию: var lineControl = new SingleLine(geo, line, totalExtent); Container.Children.Add(lineControl); lineControls.Add(lineControl); } } async void Play() { // проигрываем просто построчно foreach (var line in lineControls) await line.Play(); } } Всё! Результат:

Почему при включении аппаратного ускорения отображение svg файла становится размытым?

#android #svg #path #assets


Почему происходит размытие элемента path в то время как rectangle и circle без размытия?
Я нашёл решение в виде отключения аппаратного ускорения (заменой на программное), но
мне хотелось бы оставить аппаратное ускорение для данного View и избавиться от размытия.

android:layerType="hardware" // аппаратное
android:layerType="software" // программное 


В gradle важная строчка указана

android {
  defaultConfig {
    vectorDrawables.useSupportLibrary = true
  }
}


Вот код загрузки изображения SVG формата из Assets. 

// https://github.com/Pixplicity/sharp          
Sharp sharp = Sharp.loadAsset(getAssets(), "drawing.svg"); 
Drawable drawable = sharp.getDrawable();
view = findViewById(R.id.photo_view); //ImageView
view.setImageDrawable(drawable);


Прошу не предлагать импорт Vector asset в Drawable ресурсы. Мне это не подходит.
В моём приложении планируется сотня небольших векторных изображений, которые я планирую
размещать в папке assets.

Проблема одинаково выглядит как на эмуляторе так и на реальных устройствах.

android:layerType="hardware" // аппаратное




android:layerType="software" // программное  



    


Ответы

Ответ 1



Несколько дней мучился меняя библиотеки для работы с SVG. Но как это обычно бывает, ответ на собственный вопрос находится сразу же после того как задашь вопрос на стэковерфлоу ) Для назначения изображения нужно было использовать метод into(): view = findViewById(R.id.photo_view); //ImageView Sharp.loadAsset(getAssets(), "drawing.svg") .into(view); Всем спасибо! Надеюсь этот вопрос поможет кому нибудь в будущем ) Размытие исчезло во всех режимах android:layerType. P.S. Всё равно загадка остаётся неразгаданной, откуда берётся размытие и почему оно возникает только на path элементах svg файла

Ответ 2



Для path даже при android:layerType="hardware" все линии сначала будут переведены с помощью CPU в растовое изображение, и только потом оно передается в GPU. И если после этого, изображению будет необходимо масштабирование, у path будет растягиваться/сжиматься растр, в отличии от примитивных фигур. Вот line например будет рисоваться нормально.

пятница, 20 декабря 2019 г.

CSS-свойства SVG-изображения

#javascript #css #svg #path


Интересует, можно ли как-то при помощи JS или CSS менять свойства сложного SVG-элемента,
такие как "scale", "transform" и другие. Нужно применить к элементу с классом gear


    
        
        
            
            
        
    
    
        
        
        
        
        
    


    


Ответы

Ответ 1



Изменение размеров и цвета звёздочки при наведении курсора. Используется совместно трансформация scale и translate. Если использовать только одну команду scale звездочка уйдет по диагонали вниз и вправо, поэтому возвращаем её на место -влево и вверх отрицательными значениями translateX(-200000px) translateY(-220000px) Теперь я понимаю, почему не рекомендуют использовать файлы SVG, нарисованные в Corel. Просто жуткие цифры - сотни тысяч пикселей и соответственно размеры viewBox отличаются от viewport в десять тысяч раз. Соответственно масштаб 1:10000 Это же не карта страны а всего лишь иконка :)

Ответ 2



Проще всего при помощи CSS: .gear { transition: all 1s; transform-origin: 50% 50%; } svg:hover .gear { -webkit-transform: rotate(1turn); transform: rotate(1turn); } Через JS также можно динамически добавлять атрибут transform с нужными значениями, но тогда также придется определять точку вращения, что (по-моему) — чистейший геморрой.

Ответ 3



Пример: svg { transition: all 1s; transform-origin: 50% 50%; } svg:hover { fill: url(#bgh); transform: rotate(1turn); } circle:hover { fill: url(#bgh); }

суббота, 14 декабря 2019 г.

Почему slash (“/”) в начале пути к файлу где-то нужен, а где-то не нужен?

#java #path


Здравствуйте.
Есть примеры приложений на Java, там прописываются пути к картинкам так

construirDatabase.setIcon(new javax.swing.ImageIcon(getClass().getResource("/logo_pequeño.png")));


У меня нет ошибки только если "косую черту" убрать. Почему это?
    


Ответы

Ответ 1



Имя ресурса может быть абсолютным и относительным. Абсолютное имя начинается с символа /. В этом случае ресурс ищется относительно корня classpath. Т.е. берутся все пути и jar-файлы, входящие в classpath, и ресурс ищется относительно совокупности этих точек. Если же имя относительное – к нему в начало приписывается путь, полученный из пакета текущего класса, и далее поиск ведется как в случае абсолютного имени. Для примера, пусть у нас задан classpath c:\projects\someproject\classes;c:\libs\somelib.jar. Код примера находится в классе com.example.SomeClass. Поиск ресурса по абсолютному имени getClass().getResource("/images/logo.png") происходит следующим образом: К пути из classpath c:\projects\someproject\classes приписывается имя ресурса /images/logo.png, в результате чего ищется файл c:\projects\someproject\classes\images\logo.png. Если файл найден – поиск прекращается. Если нет, то в jar-файле c:\libs\somelib.jar ищется файл /images/logo.png, причем поиск ведется от корня jar-файла. Поиск ресурса по относительному имени getClass().getResource("res/data.txt") происходит следующим образом: К пути из classpath c:\projects\someproject\classes приписывается текущий пакет класса, где находится код (/com/example) и далее имя ресурса res/data.txt, в результате чего ищется файл c:\projects\someproject\classes\com\example\res\data.txt. Если файл найден – поиск прекращается. Иначе: В jar-файле c:\libs\somelib.jar ищется файл /com/example/res/data.txt, поиск ведется от корня jar-файла.

суббота, 7 декабря 2019 г.

Что значат две звездочки в пути?

#path #пути


Например тут:
gulp.src('src/scss/**/*.scss')
    


Ответы

Ответ 1



Все поддиректории - рекурсивно.

понедельник, 8 июля 2019 г.

Свойство clip-path через свой path

Добрый день уважаемые. Подскажите, пожалуйста как запускать данное свойство по лично нарисованному пути? (Почему то не выходит, хотя на простых фигурах хорошо отрабатывает) Приведу простой пример
.mainBlock{ width: 180px; height: 245px; } svg{ width: 180px; } .block{ width: 180px; height: 245px; border: 1px solid #000; background: url("https://cdn.rawgit.com/BlackStar1991/Pictures-for-sharing-/ad0580ed/code.jpg?raw=true") no-repeat 50% 50%; -webkit-clip-path: url("#part1"); clip-path: url("#part1"); /// не срабатывает? }


Как "порезать" эти два изображения по тем путям которые нарисованы в svg? Буду очень благодарен, если объясните на этом примере


Ответ

Путь надо вставить в . Ну и предварительно изучить как это свойство вообще работает (например, тут или тут), как надо пути составлять и т. д. С вашим текущим путем обрезает как-то странновато.
.mainBlock { width: 180px; height: 245px; } svg { width: 180px; } .block { width: 180px; height: 245px; border: 1px solid #000; background: url("https://cdn.rawgit.com/BlackStar1991/Pictures-for-sharing-/ad0580ed/code.jpg?raw=true") no-repeat 50% 50%; -webkit-clip-path: url("#clip"); clip-path: url("#clip"); }


воскресенье, 9 июня 2019 г.

Create and used StaticResource Path in XAML code

Доброго времени суток.
Как можно заставить работать следующий код в XAML


Также, я пробовал так:


Но похоже это не работает


Ответ

Все просто, нужно задать шаблон ContentTemplate:

понедельник, 4 марта 2019 г.

Передвижение по svg (path)

Как организовать движение картинок по path друг за другом, как угодно, только не друг на друге (задать координаты в цикле не получилось, где-то ошибаюсь..). Фрагмент кода:
var canvas = document.getElementById('canvas'); var context = canvas.getContext('2d'); var W = window.innerWidth, H = window.innerHeight; canvas.width = W; canvas.height = H; var angle = 0; var currentAngle = 0; var TO_RADIANS = Math.PI / 180; var particles = []; var counter = 0; var svg = document.getElementById("k9");//path из svg var straightLength = svg.getTotalLength(); function Particle() { this.radius = 20; this.x = svg.getPointAtLength(straightLength).x; this.y = svg.getPointAtLength(straightLength).y; this.move = function() { for ( var g = 0; g < particles.length; g++){ this.x = svg.getPointAtLength(counter*straightLength).x; this.y = svg.getPointAtLength(counter*straightLength).y; } counter+=0.0003;//так картинки передвигаются по path друг на друге, как организовать нечто вроде "паровозика"? Перебрал много вариантов в цикле, но ничего не вышло.. context.beginPath(); context.globalCompositeOperation = "source-over"; context.save(); context.translate(this.x, this.y); context.rotate(Gangle * TO_RADIANS); var image = new Image(); image.src = 'img/bag.png'; context.drawImage(image,20, -20, 40, 40); context.restore(); angle+=0.1; } }; for (var i = 0; i < 10; i++) { var particle = new Particle(); particles.push(particle); } function animate() { context.clearRect(0, 0, canvas.width, canvas.height); for (var i = 0; i < particles.length; i++) { particles[i].move(); } requestAnimFrame(animate); } animate();


Ответ

Как организовать движение картинок по path друг за другом
Для решения этой задачи необходимо нарисовать path в векторном редакторе или вручную.

Движение вдоль этого пути реализуется командой
С привязкой объектов движения к пути посредством ID этого пути с помощью команды Фрагмент кода:
` `
Начало движения при наведении на кнопку "Start" begin="startButton.mouseover" Окончание анимации при наведении на кнопку "Stop" end="stopGreen.mouseover"
Далее добавляются еще два подобных блока кода для двух других объектов движения.
Для реализации движения друг за другом нескольких объектов, задается пауза до начала анимации для второго и третьего шарика. begin="startButton.mouseover+0.25s"
Необязательные украшательства:
Добавлены маркеры для указания направления движения, паттерн фона и блок радиокнопок остановки объектов движения. Ниже пример кода:
Start Stop
Анимация адаптивна, пробуйте изменять размер окна браузера.
Вариант #2
Объекты движения заменены на более сложные (ведьмы на метлах) Изменена траектория движения (заменяем патч Start Stop
Начало анимации при наведении на кнопку "Start"
Приостановка объектов анимации при наведении на соответствующую радиокнопку.

пятница, 1 марта 2019 г.

Программа не видит путь к файлу C:\Windows\ System32\nslookup.exe

Программа не видит путь к файлу C:\Windows\System32
slookup.exe Проверка естественно всегда выдает "Путь не найден". То же самое происходит и например с путем к фалу notepad.exe в этой же папке, но при этом если обратиться к файлу C:\Windows\twin_32.dll то программа его находит. Подскажите куда копать? Нужно назначить текущего пользователя владельцем папки System32?
if (File.Exists(@"C:\Windows\System32
slookup.exe")) { Console.WriteLine("Путь найден"); } else Console.WriteLine("Путь не найден");


Ответ

Дело в File System Redirector'е (https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx)
Если кратко, %windir%\System32 - для 64-битных приложений. 32-битные приложения система перенаправляет в %windir%\SysWOW64 где вашего файла вполне может и не быть.

среда, 20 февраля 2019 г.

Каким образом можно реализовать бегущую подсветку (выделение) многострочного текста?

Здесь уже был вопрос про закраску текста и на него был дан ответ
Вкратце суть решения состоит в создании FormattedText из содержимого скрытого TextBlock, а затем создается геометрия из FormattedText, которая отображается с помощью Path, который в свою очередь закрашивается с помощью анимации на нем.
И все прекрасно работает пока текст занимает одну строку, а вот когда строк несколько, получается не то, что хотелось бы.

XAML я повторять не буду, т.к. он полностью совпадает с таковым в выше указанном ответе. Мой код тоже мало чем отличается, но я его приведу для ясности вопроса.
private List _RectsForFill; // прямоугольники с каждым символом private double _LengthFillText; // общая ширина рисованного текста
//анимация Storyboard _Storyboard; DoubleAnimation _FromAnimation; DoubleAnimation _ToAnimation;
private void CreateFillText() { //получаем текстовое содержимое TextBlock tb = this.textBlockHidden; var text = tb.Text;
//создаем экземпляр форматированного текста FormattedText formattedText = new FormattedText( text, CultureInfo.GetCultureInfo("en-US"), FlowDirection.LeftToRight, new Typeface( tb.FontFamily, tb.FontStyle, tb.FontWeight, tb.FontStretch), tb.FontSize, Brushes.Black // конкретная кисть нам не важна, мы используем только геометрию );
//берем переносы строк у эталонного текстблока formattedText.MaxTextWidth = this.textBlockHidden.Width; formattedText.MaxTextHeight = this.textBlockHidden.Height;
// стащили геометрию у текста... var geo = formattedText.BuildGeometry(new Point()); // ...и отдали её Path'у Target.Data = geo;
//вычислим прямоугольники для заполнения GetRectsForFill(text, formattedText); }
private void GetRectsForFill(string text, FormattedText formattedText) { var bb = formattedText.BuildHighlightGeometry(new Point()); _LengthFillText = bb.Bounds.Width; // общая ширина
//заполняем коллекцию побуквенных боксов _RectsForFill = Enumerable.Range(0, text.Length) .Select(k => formattedText.BuildHighlightGeometry(new Point(), k, 1) .Bounds) .ToList();
//ссылки на анимацию для дальнейшей работы с ней _Storyboard = (Storyboard)Target.Resources["AnimationStoryboard"]; _FromAnimation = (DoubleAnimation)_Storyboard.Children[0]; _ToAnimation = (DoubleAnimation)_Storyboard.Children[1]; }
Вот метод, заполняет черным отрисованный текст
///

/// Закрашивание рисованного текста /// /// начальная позиция слова /// число закрашиваемых букв в слове public void FillTextPath(int startPos, int count) { if (count == 0) throw new ArgumentException(nameof(count));
//вычисляем индекс необходимого прямоугольника int index = startPos + count; if (index >= _RectsForFill.Count) index = _RectsForFill.Count - 1;
//необходимый прямоугольник Rect box = _RectsForFill[index];
//закрашиваем _FromAnimation.From = box.Left / _LengthFillText; _FromAnimation.To = box.Right / _LengthFillText; _ToAnimation.From = box.Left / _LengthFillText; _ToAnimation.To = box.Right / _LengthFillText; _Storyboard.Begin(); }


Ответ

Вы пошли правильным путём, разбить на отдельные Path'ы — хорошая идея.
Давайте её реализуем до конца.
Для начала, функциональность проигрывания уже достаточно сложна, так что вынесем её в отдельный UserControl. Затем, каждый контрол пусть отвечает за одну строку. Чтобы не искать куски по геометрии, просто отрежем эту строку при помощи Clip'а. На вход в UserControl будем подавать результаты разбора текста на геометрию (функцией Create).

В code-behind будет анимация:
public partial class SingleLine : UserControl { List boundingBoxes; double extent;
public SingleLine() { InitializeComponent(); }
public SingleLine(Geometry geo, List boundingBoxes, double totalExtent) : this() { Target.Data = geo; extent = totalExtent; Rect clip = boundingBoxes.Aggregate(Rect.Union); Clip = new RectangleGeometry(clip); this.boundingBoxes = boundingBoxes; }
public async Task Play() { var storyboard = (Storyboard)Target.Resources["AnimationStoryboard"]; var fromAnimation = (DoubleAnimation)storyboard.Children[0]; var toAnimation = (DoubleAnimation)storyboard.Children[1];
foreach (var b in boundingBoxes) { await Task.Delay(250); // перерыв между буквами fromAnimation.From = b.Left / extent; fromAnimation.To = b.Right / extent; toAnimation.From = b.Left / extent; toAnimation.To = b.Right / extent; storyboard.Begin(); await Task.Delay(250); // дождёмся конца анимации } } }
Зачем нам нужна такая сложность с Clip и totalExtent? К сожалению, я не нашёл метода выкусить только нужную часть геометрии. Поэтому мы даём на вход всю геометрию, а хотим показывать только текущую строку. Для этого мы вычисляем прямоугольник, соответствующий нужной части геометрии (текущей строке), и отрезаем отображение остального при помощи Clip'а. Но наши вычисления коэффициентов (b.Left / extent и т. д.) требуют процента от общей ширины Path'а, а не ширины текущей строки! (Напомню, наш Path получает геометрию всей строки, включая остальные строки тоже.) Поэтому приходится передавать ещё и общую ширину.
Теперь основной код. Он стал проще, так как часть функциональности отделилась. В нём мы не можем положить один, фиксированный Path, так как у нас количество строк не известно заранее. Поэтому контролы будем добавлять динамически.
Главное окно выглядит просто:

И code-behind:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Loaded += (o, args) => Create(); // вначале запустим Create PreviewKeyDown += (o, args) => Play(); // а по нажатию клавиши - Play }
// список контролов, отображающих строки List lineControls = new List();
void Create() // https://msdn.microsoft.com/en-us/library/ms745816(v=vs.110).aspx { TextBlock tb = Source; var text = tb.Text; FormattedText formattedText = new FormattedText( text, CultureInfo.GetCultureInfo("en-US"), FlowDirection.LeftToRight, new Typeface( tb.FontFamily, tb.FontStyle, tb.FontWeight, tb.FontStretch), tb.FontSize, Brushes.Black);
// установили максимальную ширину, чтобы текст был разбит на части formattedText.MaxTextWidth = Source.ActualWidth;
var boundingBoxes = // побуквенная ширина и позиции Enumerable.Range(0, text.Length) .Where(k => !char.IsWhiteSpace(text[k])) .Select(k => formattedText.BuildHighlightGeometry(new Point(), k, 1) .Bounds) .ToList();
// вычисляем охватывающий прямоугольник всех прямоугольников var totalBb = boundingBoxes.Aggregate(Rect.Union); var totalExtent = totalBb.Width;
List> boundingBoxesByLine = new List>(); List currentLine = null; double lastRectBottom = double.NegativeInfinity; foreach (var rect in boundingBoxes) { // проверка на новую строку. если верх текущего прямоугольника там же, // где низ предыдущего прямоугольника, или ещё ниже - новая строка, иначе нет if (rect.Top >= lastRectBottom) { // добавим старую строку в список строк if (currentLine != null) boundingBoxesByLine.Add(currentLine); // новый пустой контейнер прямоугольников для новой строки currentLine = new List(); } currentLine.Add(rect); lastRectBottom = rect.Bottom; } if (currentLine != null) // последнюю строку не теряем boundingBoxesByLine.Add(currentLine);
// стащили геометрию у текста... var geo = formattedText.BuildGeometry(new Point());
// строим по контролу для каждой строки: foreach (var line in boundingBoxesByLine) { // ... отдавая ему геометрию: var lineControl = new SingleLine(geo, line, totalExtent); Container.Children.Add(lineControl); lineControls.Add(lineControl); } }
async void Play() { // проигрываем просто построчно foreach (var line in lineControls) await line.Play(); } }
Всё!

Результат:

Каким образом можно реализовать бегущую подсветку (выделение) многострочного текста?

Здесь уже был вопрос про закраску текста и на него был дан ответ
Вкратце суть решения состоит в создании FormattedText из содержимого скрытого TextBlock, а затем создается геометрия из FormattedText, которая отображается с помощью Path, который в свою очередь закрашивается с помощью анимации на нем.
И все прекрасно работает пока текст занимает одну строку, а вот когда строк несколько, получается не то, что хотелось бы.

XAML я повторять не буду, т.к. он полностью совпадает с таковым в выше указанном ответе. Мой код тоже мало чем отличается, но я его приведу для ясности вопроса.
private List _RectsForFill; // прямоугольники с каждым символом private double _LengthFillText; // общая ширина рисованного текста
//анимация Storyboard _Storyboard; DoubleAnimation _FromAnimation; DoubleAnimation _ToAnimation;
private void CreateFillText() { //получаем текстовое содержимое TextBlock tb = this.textBlockHidden; var text = tb.Text;
//создаем экземпляр форматированного текста FormattedText formattedText = new FormattedText( text, CultureInfo.GetCultureInfo("en-US"), FlowDirection.LeftToRight, new Typeface( tb.FontFamily, tb.FontStyle, tb.FontWeight, tb.FontStretch), tb.FontSize, Brushes.Black // конкретная кисть нам не важна, мы используем только геометрию );
//берем переносы строк у эталонного текстблока formattedText.MaxTextWidth = this.textBlockHidden.Width; formattedText.MaxTextHeight = this.textBlockHidden.Height;
// стащили геометрию у текста... var geo = formattedText.BuildGeometry(new Point()); // ...и отдали её Path'у Target.Data = geo;
//вычислим прямоугольники для заполнения GetRectsForFill(text, formattedText); }
private void GetRectsForFill(string text, FormattedText formattedText) { var bb = formattedText.BuildHighlightGeometry(new Point()); _LengthFillText = bb.Bounds.Width; // общая ширина
//заполняем коллекцию побуквенных боксов _RectsForFill = Enumerable.Range(0, text.Length) .Select(k => formattedText.BuildHighlightGeometry(new Point(), k, 1) .Bounds) .ToList();
//ссылки на анимацию для дальнейшей работы с ней _Storyboard = (Storyboard)Target.Resources["AnimationStoryboard"]; _FromAnimation = (DoubleAnimation)_Storyboard.Children[0]; _ToAnimation = (DoubleAnimation)_Storyboard.Children[1]; }
Вот метод, заполняет черным отрисованный текст
///

/// Закрашивание рисованного текста /// /// начальная позиция слова /// число закрашиваемых букв в слове public void FillTextPath(int startPos, int count) { if (count == 0) throw new ArgumentException(nameof(count));
//вычисляем индекс необходимого прямоугольника int index = startPos + count; if (index >= _RectsForFill.Count) index = _RectsForFill.Count - 1;
//необходимый прямоугольник Rect box = _RectsForFill[index];
//закрашиваем _FromAnimation.From = box.Left / _LengthFillText; _FromAnimation.To = box.Right / _LengthFillText; _ToAnimation.From = box.Left / _LengthFillText; _ToAnimation.To = box.Right / _LengthFillText; _Storyboard.Begin(); }


Ответ

Вы пошли правильным путём, разбить на отдельные Path'ы — хорошая идея.
Давайте её реализуем до конца.
Для начала, функциональность проигрывания уже достаточно сложна, так что вынесем её в отдельный UserControl. Затем, каждый контрол пусть отвечает за одну строку. Чтобы не искать куски по геометрии, просто отрежем эту строку при помощи Clip'а. На вход в UserControl будем подавать результаты разбора текста на геометрию (функцией Create).

В code-behind будет анимация:
public partial class SingleLine : UserControl { List boundingBoxes; double extent;
public SingleLine() { InitializeComponent(); }
public SingleLine(Geometry geo, List boundingBoxes, double totalExtent) : this() { Target.Data = geo; extent = totalExtent; Rect clip = boundingBoxes.Aggregate(Rect.Union); Clip = new RectangleGeometry(clip); this.boundingBoxes = boundingBoxes; }
public async Task Play() { var storyboard = (Storyboard)Target.Resources["AnimationStoryboard"]; var fromAnimation = (DoubleAnimation)storyboard.Children[0]; var toAnimation = (DoubleAnimation)storyboard.Children[1];
foreach (var b in boundingBoxes) { await Task.Delay(250); // перерыв между буквами fromAnimation.From = b.Left / extent; fromAnimation.To = b.Right / extent; toAnimation.From = b.Left / extent; toAnimation.To = b.Right / extent; storyboard.Begin(); await Task.Delay(250); // дождёмся конца анимации } } }
Зачем нам нужна такая сложность с Clip и totalExtent? К сожалению, я не нашёл метода выкусить только нужную часть геометрии. Поэтому мы даём на вход всю геометрию, а хотим показывать только текущую строку. Для этого мы вычисляем прямоугольник, соответствующий нужной части геометрии (текущей строке), и отрезаем отображение остального при помощи Clip'а. Но наши вычисления коэффициентов (b.Left / extent и т. д.) требуют процента от общей ширины Path'а, а не ширины текущей строки! (Напомню, наш Path получает геометрию всей строки, включая остальные строки тоже.) Поэтому приходится передавать ещё и общую ширину.
Теперь основной код. Он стал проще, так как часть функциональности отделилась. В нём мы не можем положить один, фиксированный Path, так как у нас количество строк не известно заранее. Поэтому контролы будем добавлять динамически.
Главное окно выглядит просто:

И code-behind:
public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); Loaded += (o, args) => Create(); // вначале запустим Create PreviewKeyDown += (o, args) => Play(); // а по нажатию клавиши - Play }
// список контролов, отображающих строки List lineControls = new List();
void Create() // https://msdn.microsoft.com/en-us/library/ms745816(v=vs.110).aspx { TextBlock tb = Source; var text = tb.Text; FormattedText formattedText = new FormattedText( text, CultureInfo.GetCultureInfo("en-US"), FlowDirection.LeftToRight, new Typeface( tb.FontFamily, tb.FontStyle, tb.FontWeight, tb.FontStretch), tb.FontSize, Brushes.Black);
// установили максимальную ширину, чтобы текст был разбит на части formattedText.MaxTextWidth = Source.ActualWidth;
var boundingBoxes = // побуквенная ширина и позиции Enumerable.Range(0, text.Length) .Where(k => !char.IsWhiteSpace(text[k])) .Select(k => formattedText.BuildHighlightGeometry(new Point(), k, 1) .Bounds) .ToList();
// вычисляем охватывающий прямоугольник всех прямоугольников var totalBb = boundingBoxes.Aggregate(Rect.Union); var totalExtent = totalBb.Width;
List> boundingBoxesByLine = new List>(); List currentLine = null; double lastRectBottom = double.NegativeInfinity; foreach (var rect in boundingBoxes) { // проверка на новую строку. если верх текущего прямоугольника там же, // где низ предыдущего прямоугольника, или ещё ниже - новая строка, иначе нет if (rect.Top >= lastRectBottom) { // добавим старую строку в список строк if (currentLine != null) boundingBoxesByLine.Add(currentLine); // новый пустой контейнер прямоугольников для новой строки currentLine = new List(); } currentLine.Add(rect); lastRectBottom = rect.Bottom; } if (currentLine != null) // последнюю строку не теряем boundingBoxesByLine.Add(currentLine);
// стащили геометрию у текста... var geo = formattedText.BuildGeometry(new Point());
// строим по контролу для каждой строки: foreach (var line in boundingBoxesByLine) { // ... отдавая ему геометрию: var lineControl = new SingleLine(geo, line, totalExtent); Container.Children.Add(lineControl); lineControls.Add(lineControl); } }
async void Play() { // проигрываем просто построчно foreach (var line in lineControls) await line.Play(); } }
Всё!

Результат: