・~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~・
・グラフィックスライブラリ、SkiaSharpのSKMatrix44クラスを使用し、
・非アフェン変換を行い立体化させパラメータを連続可変させてアニメーション化します。
・~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~・
・グラフィックスライブラリ、SkiaSharpのSKMatrix44クラスを使用し、
・非アフェン変換を行い立体化させパラメータを連続可変させてアニメーション化します。
・~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~・
1.マーク・フリント氏による伝説のOP(83年)の再現のスクリーンショット 40年ぶりに蘇る
2.WQHD(2540x1440)での動画(キャプチャ中でFPS下がってます)。他、10年前のノートPCでもそれなりに動きました。
- 作ってて結局わからず放置してたがサンプルを見つけそれを改変しました。
- SKMatrixが古い等と警告でますがメークは通ります。
- 手製のプログラムに内蔵して演出させたらどうでしょう。パラメータ変えると色々表示が変わります。
- 元来、2D専用と言う事もあり厚みがありません。
- その昔、x86でグラフィックディスプレイコントローラ(μPD7220)直叩きで3Dやってたのに今や高級言語で出来ちゃう時代。
1.XYZ軸回転しながら近づいてまた遠方へ
漢字用 LINEフォント入れてない場合はTypeface = SKTypeface.FromFamilyName("LINE Seed JP_OTF"), を削除。
// SkiaSharp Test / inf102
// https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/transforms/3d-rotation
using SkiaSharp;
using SkiaSharp.Views.Desktop;
using System;
using System.Threading.Tasks;
using System.Windows;
namespace SkiaSharpSample {
public partial class MainWindow : Window {
static int r=0;//2000;
static float s=0;//=23;
static bool flg;
static string[] st = { "SKIA SHARP&SKMatrix44","三次元アニメーション映像", "3D VALIANT", "ThreeDimensions","Smooth 3D Video" };
static int stn = 0;
public MainWindow() {
InitializeComponent();
this.WindowState = WindowState.Maximized;
}
private async void Window_Loaded(object sender, RoutedEventArgs e) {
while (true){
skiaCanvas2.InvalidateVisual();
// Title = r + "s="+s;
if (r == 632) stn = 1;
if (r == 1345) stn = 2;
if (r == 2427) stn = 3;
if (r == 2249 && flg == true) stn = 4;
if (r>=3000) {
flg =true;
}
if (r<=0 || s<=0 ) {
flg=false;
r=0;
}
// 大きく
if (flg == false) {
r++;
s=s+(float)0.01; // SIZE
}
// 小さくする
else {
r--;
s=s-(float)0.03;
}
await Task.Delay (1); //2000 23
}
}
void PaintSurface(object sender, SKPaintSurfaceEventArgs args){
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear(SKColors.Black);
SKPaint textPaint = new SKPaint{
Style = SKPaintStyle.Fill,
Color = SKColors.Yellow,
IsAntialias=true,
LcdRenderText=true,
FakeBoldText = true,
TextSize = s,
TextAlign= (SKTextAlign)SKTextAlign.Center,
Typeface = SKTypeface.FromFamilyName("LINE Seed JP_OTF"),
//TextSkewX=2, // 斜め
//TextScaleX = 3f // 圧縮
};
if(stn == 1) textPaint.Color = new SKColor(0, 255, 0);
if(stn == 2) textPaint.Color = new SKColor(0, 00, 255);
// 色を変える場合
Random Rnd = new Random();
if (flg) textPaint.Color=new SKColor((byte)Rnd.Next(0, 255), (byte)Rnd.Next(0, 255),(byte)Rnd.Next(0, 255));
// Find center of canvas
float xCenter = info.Width / 2;
float yCenter = info.Height / 2;
// Translate center to origin
SKMatrix matrix = SKMatrix.MakeTranslation(-xCenter, -yCenter);
// Scale so text fits
float scale = Math.Min(info.Width / 110,info.Height / 110);
SKMatrix.PostConcat(ref matrix, SKMatrix.MakeScale(scale, scale));
// Calculate composite 3D transforms
float depth = 0.75f * scale * 100;
SKMatrix44 matrix44 = SKMatrix44.CreateIdentity();
matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(1, 0, 0, (float)r)); // 上下回転
matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 1, 0, (float)r)); // 左右回転
matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 0, 1, (float)r)); // 時計風回転
SKMatrix44 perspectiveMatrix = SKMatrix44.CreateIdentity();
perspectiveMatrix[3, 2] = -1 / depth;
matrix44.PostConcat(perspectiveMatrix);
// Concatenate with 2D matrix
SKMatrix.PostConcat(ref matrix, matrix44.Matrix);
// Translate back to center
SKMatrix.PostConcat(ref matrix,SKMatrix.MakeTranslation(xCenter, yCenter));
// Set the matrix and display the text 縦横移動率
canvas.SetMatrix(matrix);
float xText = xCenter - 3;
float yText = yCenter + 5;
canvas.DrawText(st[stn], xText, yText, textPaint);
}
}
}
2.Y軸のみ回転
// SkiaSharp Test / Y軸回転
// https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/transforms/3d-rotation
using SkiaSharp;
using SkiaSharp.Views.Desktop;
using System;
using System.Threading.Tasks;
using System.Windows;
namespace SkiaSharpSample {
public partial class MainWindow : Window {
static int r=0;
static float s=2;
static bool flg=false;
static string text="";
public MainWindow() {
InitializeComponent();
this.WindowState = WindowState.Maximized;
}
private async void Window_Loaded(object sender, RoutedEventArgs e) {
// 1st
text="3D VALIANT";
while (true){
skiaCanvas2.InvalidateVisual();
Title = s.ToString();
if ( s>=(float)30.06483 && flg==false) {
s=14;
r=0;
flg=true;
text="WPF+SkiaSharp"; //2nd
}
r++; // 回転
s=s+(float)0.015; // SIZE
await Task.Delay(1);
}
}
void PaintSurface(object sender, SKPaintSurfaceEventArgs args){
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear(SKColors.Black);
SKPaint textPaint = new SKPaint{
Style = SKPaintStyle.Fill,
IsAntialias=true,
LcdRenderText=true,
TextSize = s,
TextAlign= (SKTextAlign)SKTextAlign.Center,
// Typeface = SKTypeface.FromFamilyName("LINE Seed JP_OTF"),
};
if(flg == false) textPaint.Color = new SKColor(0, 255,127);
else textPaint.Color = new SKColor(255, 218,185);
// 色を変える場合
Random Rnd = new Random();
// textPaint.Color=new SKColor((byte)Rnd.Next(0, 255), (byte)Rnd.Next(0, 255),(byte)Rnd.Next(0, 255));
// Find center of canvas
float xCenter = info.Width / 2;
float yCenter = info.Height / 2;
// Translate center to origin
SKMatrix matrix = SKMatrix.MakeTranslation(-xCenter, -yCenter);
// Scale so text fits
float scale = Math.Min(info.Width / 110,info.Height / 110);
SKMatrix.PostConcat(ref matrix, SKMatrix.MakeScale(scale, scale));
// Calculate composite 3D transforms
float depth = 0.75f * scale * 100;
SKMatrix44 matrix44 = SKMatrix44.CreateIdentity();
matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 1, 0, (float)r));
// if (flg==true){
// matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 0, 1, (float)r));
// matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(1, 0, 0, (float)r));
// }
SKMatrix44 perspectiveMatrix = SKMatrix44.CreateIdentity();
perspectiveMatrix[3, 2] = -1 / depth;
matrix44.PostConcat(perspectiveMatrix);
// Concatenate with 2D matrix
SKMatrix.PostConcat(ref matrix, matrix44.Matrix);
// Translate back to center
SKMatrix.PostConcat(ref matrix,SKMatrix.MakeTranslation(xCenter, yCenter));
// Set the matrix and display the text
canvas.SetMatrix(matrix);
float xText = xCenter - 0; //回転軸
float yText = yCenter + 9; //縦位置
canvas.DrawText(text, xText, yText+1, textPaint);
}
}
}
3.XAML (共通)
<Window x:Class="SkiaSharpSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SkiaSharpSample" xmlns:skia="clr-namespace:SkiaSharp.Views.WPF;assembly=SkiaSharp.Views.WPF"
xmlns:wpf="clr-namespace:SkiaSharp.Views.WPF;assembly=SkiaSharp.Views.WPF" mc:Ignorable="d"
Title="SkiaSharp" Loaded="Window_Loaded" Height="850" Width="850" >
<Grid >
<wpf:SKElement x:Name="skiaCanvas2" PaintSurface="PaintSurface" />
</Grid>
</Window>